def registerVolume(self, targetFH, defaultDir):
        """create the filenames for a single registration call

        Two input arguments are required - a RegistrationPipeFH instance for the
        target volume and the default directory where the output should be placed.
        
        The output xfm is constructed based on:
            1. The names of the source and target base volumes.
            2. The group name (eg. base, lsq6, etc) or index (if names are not set,
               default is to index)
            3. A counter at the end, based on the number of previous transforms.
               e.g. The first transform will have _0.xfm, because the length of
               the transforms array will be 0, the second transform will have _1.xfm
               etc. 
        """
        sourceFilename = fh.removeBaseAndExtension(self.getLastBasevol())
        targetFilename = fh.removeBaseAndExtension(targetFH.getLastBasevol())
        xfmFileName = [sourceFilename, "to", targetFilename] 
        groupName = self.groupNames[self.currentGroupIndex]
        xfmsDict = self.groupedFiles[self.currentGroupIndex].transforms
        if xfmsDict.has_key(targetFH):
            numPrevXfms = len(xfmsDict[targetFH])
        else:
            numPrevXfms = 0
        xfmFileName += [str(groupName), str(numPrevXfms)]       
        xfmFileWithExt = "_".join(xfmFileName) + ".xfm"
        xfmOutputDir = self.setOutputDirectory(defaultDir)
        # MF TO DO: Need to add in some checking for duplicate names here. 
        outputXfm = fh.createBaseName(xfmOutputDir, xfmFileWithExt)
        self.addAndSetXfmToUse(targetFH, outputXfm)
        return(outputXfm)
Exemplo n.º 2
0
def finalGenerationFileNames(inputFH):
    """Set up and return filenames for final nlin generation, since we don't want to use defaults here.
       The naming of the final resampled files/transforms will be the same regardless of registration
       protocol (minctracc vs mincANTS) or number of generations. 
    """
    registerDir = inputFH.setOutputDirectory("transforms")
    registerFileName = removeBaseAndExtension(inputFH.basename) + "-final-nlin.xfm"
    registerOutput = createBaseName(registerDir, registerFileName)
    resampleDir = inputFH.setOutputDirectory("resampled")
    resampleFileName = removeBaseAndExtension(inputFH.basename) + "-resampled-final-nlin.mnc"
    resampleOutput = createBaseName(resampleDir, resampleFileName)
    return (registerOutput, resampleOutput)
Exemplo n.º 3
0
 def linAndNlinDisplacement(self):
     """
        The function calculates both the linear and nonlinear
        portions of the displacement, in order to find 
        pure nonlinear. Common space here is the target (usually
        an average of some sort). We also recentre pure non linear 
        displacement. 
        
     """
     
     """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]
     
     """Calculate full displacement from target to input"""
     self.calcFullDisplacement()
     
     """Calculate pure non-linear displacement from target to input
        1. Concatenate linear and inverse target to input transform to 
           get pure_nlin xfm
        2. Compute mincDisplacement on this transform. 
     """
     nlinXfm = createPureNlinXfmName(self.inputFH, self.invXfm)
     xc = xfmConcat([self.linearXfm, self.invXfm], nlinXfm, fh.logFromFile(self.inputFH.logDir, nlinXfm))
     self.p.addStage(xc)
     nlinDisp = mincDisplacement(self.targetFH, self.inputFH, transform=nlinXfm)
     self.p.addStage(nlinDisp)
     self.nlinDisp = nlinDisp.outputFiles[0]
     
     """Calculate average displacement and re-center non-linear displacement
        if an array of input file handlers was specified on instantiation. """
     
     if self.dispToAvg:
         """Calculate average inverse displacement"""
         avgOutput = abspath(self.targetFH.basedir) + "/" + "average_inv_pure_displacement.mnc"
         logBase = fh.removeBaseAndExtension(avgOutput)
         avgLog = fh.createLogFile(self.targetFH.basedir, logBase)
         avg = mincAverageDisp(self.dispToAvg, avgOutput, logFile=avgLog)
         self.p.addStage(avg)
         """Centre pure nlin displacement by subtracting average from existing"""
         centredBase = fh.removeBaseAndExtension(self.nlinDisp).split("_displacement")[0] 
         centredOut = fh.createBaseName(self.inputFH.statsDir, 
                                        centredBase + "_centred_displacement.mnc")
         cmd = ["mincmath", "-clobber", "-sub", InputFile(self.nlinDisp), 
                InputFile(avgOutput), OutputFile(centredOut)]
         centredDisp = CmdStage(cmd)
         centredDisp.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, centredOut)))
         self.p.addStage(centredDisp)
         """Reset centred displacement to be self.nlinDisp"""
         self.nlinDisp = centredOut
Exemplo n.º 4
0
def finalGenerationFileNames(inputFH):
    """Set up and return filenames for final nlin generation, since we don't want to use defaults here.
       The naming of the final resampled files/transforms will be the same regardless of registration
       protocol (minctracc vs mincANTS) or number of generations. 
    """
    registerDir = inputFH.setOutputDirectory("transforms")
    registerFileName = removeBaseAndExtension(
        inputFH.basename) + "-final-nlin.xfm"
    registerOutput = createBaseName(registerDir, registerFileName)
    resampleDir = inputFH.setOutputDirectory("resampled")
    resampleFileName = removeBaseAndExtension(
        inputFH.basename) + "-resampled-final-nlin.mnc"
    resampleOutput = createBaseName(resampleDir, resampleFileName)
    return (registerOutput, resampleOutput)
Exemplo n.º 5
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]
Exemplo n.º 6
0
def resampleToCommon(xfm, FH, statsGroup, statsKernels, nlinFH):
    blurs = []
    if isinstance(statsKernels, list):
        blurs = statsKernels
    elif isinstance(statsKernels, str):
        for i in statsKernels.split(","):
            blurs.append(float(i))
    else:
        print "Improper type of blurring kernels specified for stats calculation: " + str(statsKernels)
        sys.exit()
    pipeline = Pipeline()
    outputDirectory = FH.statsDir
    filesToResample = []
    for b in blurs:
        filesToResample.append(statsGroup.relativeJacobians[b])
        if statsGroup.absoluteJacobians:
            filesToResample.append(statsGroup.absoluteJacobians[b])
    for f in filesToResample:
        outputBase = fh.removeBaseAndExtension(f).split(".mnc")[0]
        outputFile = fh.createBaseName(outputDirectory, outputBase + "_common" + ".mnc")
        logFile = fh.logFromFile(FH.logDir, outputFile)
        targetAndLike=nlinFH.getLastBasevol()
        res = ma.mincresample(f, 
                              targetAndLike,
                              likeFile=targetAndLike,
                              transform=xfm,
                              output=outputFile,
                              logFile=logFile,
                              argArray=["-sinc"]) 
        pipeline.addStage(res)
    
    return pipeline
Exemplo n.º 7
0
 def iterate(self):
     for i in range(self.generations):
         nlinOutput = abspath(self.nlinDir) + "/" + "nlin-%g.mnc" % (i+1)
         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)
Exemplo n.º 8
0
def resampleToCommon(xfm, FH, statsGroup, statsKernels, nlinFH):
    blurs = []
    if isinstance(statsKernels, list):
        blurs = statsKernels
    elif isinstance(statsKernels, str):
        for i in statsKernels.split(","):
            blurs.append(float(i))
    else:
        print("Improper type of blurring kernels specified for stats calculation: " + str(statsKernels))
        sys.exit()
    pipeline = Pipeline()
    outputDirectory = FH.statsDir
    filesToResample = []
    for b in blurs:
        filesToResample.append(statsGroup.relativeJacobians[b])
        if statsGroup.absoluteJacobians:
            filesToResample.append(statsGroup.absoluteJacobians[b])
    for f in filesToResample:
        outputBase = removeBaseAndExtension(f).split(".mnc")[0]
        outputFile = createBaseName(outputDirectory, outputBase + "_common" + ".mnc")
        logFile = fh.logFromFile(FH.logDir, outputFile)
        targetAndLike=nlinFH.getLastBasevol()
        res = ma.mincresample(f, 
                              targetAndLike,
                              likeFile=targetAndLike,
                              transform=xfm,
                              output=outputFile,
                              logFile=logFile,
                              argArray=["-sinc"]) 
        pipeline.addStage(res)
    
    return pipeline
Exemplo n.º 9
0
 def setOutputFile(self, inFile, defaultDir):
     outDir = inFile.setOutputDirectory(defaultDir)
     outBase = (fh.removeBaseAndExtension(inFile.getLastBasevol()) + "_" +
                self.resolution + "res.mnc")
     outputFile = fh.createBaseName(outDir, outBase)
     inFile.setLastBasevol(outputFile)
     return (outputFile)
Exemplo n.º 10
0
 def setOutputFile(self, inFile, defaultDir):
     outDir = inFile.setOutputDirectory(defaultDir)
     outBase = (fh.removeBaseAndExtension(inFile.getLastBasevol()) + "_"
                + self.resolution + "res.mnc")
     outputFile = fh.createBaseName(outDir, outBase)
     inFile.setLastBasevol(outputFile)
     return(outputFile)  
    def blurFile(self, fwhm, gradient=False, defaultDir="tmp"):
        """create filename for a mincblur call

        Return a triplet of the basename, which mincblur needs as its
        input, the full filename, which mincblur will create after its done,
        and the log file"""
        
        #MF TODO: Error handling if there is no lastBaseVol
        lastBaseVol = self.getLastBasevol()
        outputbase = fh.removeBaseAndExtension(lastBaseVol)
        outputDir = self.setOutputDirectory(defaultDir)
        outputbase = "%s/%s_fwhm%g" % (outputDir, outputbase, fwhm)
        
        withext = "%s_blur.mnc" % outputbase     
        log = fh.logFromFile(self.logDir, withext)

        outlist = { "base" : outputbase,
                    "file" : withext,
                    "log"  : log }
        
        if gradient:
            gradWithExt = "%s_dxyz.mnc" % outputbase
            outlist["gradient"] = gradWithExt
        else:
            gradWithExt=None

        self.groupedFiles[self.currentGroupIndex].addBlur(withext, fwhm, gradWithExt)
        return(outlist)
Exemplo n.º 12
0
 def setOutputFileName(self, FH, **funcargs):
     endOfFile = "-" + funcargs["append"] + ".mnc"
     if self.setInputLabels:
         outBase = fh.removeBaseAndExtension(self.cxfm)
         if fnmatch.fnmatch(outBase, "*_minctracc_*"):
             outputName = outBase.split("_minctracc_")[0]
         elif fnmatch.fnmatch(outBase, "*_ANTS_*"):
             outputName = outBase.split("_ANTS_")[0]
         else:
             outputName = outBase
         outBase = outputName + "-input"
     else:
         labelsToResample = fh.removeBaseAndExtension(self.inFile)
         likeBaseVol = fh.removeBaseAndExtension(FH.getLastBasevol())
         outBase = labelsToResample + "_to_" + likeBaseVol 
     outBase += endOfFile
     return outBase
Exemplo n.º 13
0
 def setOutputFileName(self, FH, **funcargs):
     endOfFile = "-" + funcargs["append"] + ".mnc"
     if self.setInputLabels:
         outBase = fh.removeBaseAndExtension(self.cxfm)
         if fnmatch.fnmatch(outBase, "*_minctracc_*"):
             outputName = outBase.split("_minctracc_")[0]
         elif fnmatch.fnmatch(outBase, "*_ANTS_*"):
             outputName = outBase.split("_ANTS_")[0]
         else:
             outputName = outBase
         outBase = outputName + "-input"
     else:
         labelsToResample = fh.removeBaseAndExtension(self.inFile)
         likeBaseVol = fh.removeBaseAndExtension(FH.getLastBasevol())
         outBase = labelsToResample + "_to_" + likeBaseVol
     outBase += endOfFile
     return outBase
Exemplo n.º 14
0
def setupInitModel(inputModel, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space
    """
    errorMsg = "Failed to properly set up initModel."

    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, "init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(
                inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                errorMsg = "Required mask for the --init-model does not exist: " + str(
                    mask)
                raise
            standardFH = rfh.RegistrationPipeFH(imageFile,
                                                mask=mask,
                                                basedir=initModelDir)
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    errorMsg = "_native.mnc file included but associated mask not found"
                    raise
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName,
                                                      mask=mask,
                                                      basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        nativeToStdXfm = None
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print errorMsg
        print "Exiting..."
        sys.exit()
Exemplo n.º 15
0
def initializeInputFiles(args, mainDirectory, maskDir=None):

    # initial error handling:  verify that at least one input file is specified
    # and that it is a MINC file
    if (len(args) < 1):
        print "Error: no source image provided\n"
        sys.exit()
    for i in range(len(args)):
        ext = splitext(args[i])[1]
        if (re.match(".mnc", ext) == None):
            print "Error: input file is not a MINC file:, ", args[i], "\n"
            sys.exit()

    inputs = []
    # the assumption in the following line is that args is a list
    # if that is not the case, convert it to one
    if (not (type(args) is list)):
        args = [args]
    for iFile in range(len(args)):
        inputPipeFH = rfh.RegistrationPipeFH(abspath(args[iFile]),
                                             basedir=mainDirectory)
        inputs.append(inputPipeFH)
    """After file handlers initialized, assign mask to each file
       If directory of masks is specified, apply to each file handler.
       Two options:
            1. One mask in directory --> use for all scans. 
            2. Same number of masks as files, with same naming convention. Individual
                 mask for each scan.  
    """
    if maskDir:
        absMaskPath = abspath(maskDir)
        masks = walk(absMaskPath).next()[2]
        numMasks = len(masks)
        numScans = len(inputs)
        if numMasks == 1:
            for inputFH in inputs:
                inputFH.setMask(absMaskPath + "/" + masks[0])
        elif numMasks == numScans:
            for m in masks:
                maskBase = fh.removeBaseAndExtension(m).split("_mask")[0]
                for inputFH in inputs:
                    if fnmatch.fnmatch(inputFH.getLastBasevol(),
                                       "*" + maskBase + "*"):
                        inputFH.setMask(absMaskPath + "/" + m)
        else:
            logger.error(
                "Number of masks in directory does not match number of scans, but is greater than 1. Exiting..."
            )
            sys.exit()
    else:
        logger.info(
            "No mask directory specified as command line option. No masks included during RegistrationPipeFH initialization."
        )
    return inputs
Exemplo n.º 16
0
def setupInitModel(inputModel, pipeName, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space

        we should make sure that files related to the initial model end up in 
        a directory named analogous to all other files, i.e., {pipeline_name}_init_model
        so we need to have the pipeName here:
    """
    errorMsg = "Failed to properly set up initModel."

    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, pipeName + "_init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                raise Exception("Required mask for the --init-model does not exist: " + str(mask))
            standardFH = rfh.RegistrationPipeFH(imageFile, mask=mask, basedir=initModelDir)            
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    raise Exception("_native.mnc file included but associated mask not found")
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName, mask=mask, basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        raise Exception("Your initial model directory has both native and standard files but no transformation between them; you need to supply %s_native_to_standard.xfm" % imageBase)
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print(errorMsg)
        raise
Exemplo n.º 17
0
def setupInitModel(inputModel, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space
    """
    errorMsg = "Failed to properly set up initModel."
    
    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, "init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                errorMsg = "Required mask for the --init-model does not exist: " + str(mask)
                raise
            standardFH = rfh.RegistrationPipeFH(imageFile, mask=mask, basedir=initModelDir)            
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    errorMsg = "_native.mnc file included but associated mask not found"
                    raise
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName, mask=mask, basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        nativeToStdXfm = None
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print errorMsg
        print "Exiting..."
        sys.exit()
Exemplo n.º 18
0
def initializeInputFiles(args, mainDirectory, maskDir=None):
    
    # initial error handling:  verify that at least one input file is specified 
    # and that it is a MINC file
    if(len(args) < 1):
        print "Error: no source image provided\n"
        sys.exit()
    for i in range(len(args)):
        ext = splitext(args[i])[1]
        if(re.match(".mnc", ext) == None):
            print "Error: input file is not a MINC file:, ", args[i], "\n"
            sys.exit()
    
    inputs = []
    # the assumption in the following line is that args is a list
    # if that is not the case, convert it to one
    if(not(type(args) is list)):
        args = [args]
    for iFile in range(len(args)):
        inputPipeFH = rfh.RegistrationPipeFH(abspath(args[iFile]), basedir=mainDirectory)
        inputs.append(inputPipeFH)
    """After file handlers initialized, assign mask to each file
       If directory of masks is specified, apply to each file handler.
       Two options:
            1. One mask in directory --> use for all scans. 
            2. Same number of masks as files, with same naming convention. Individual
                 mask for each scan.  
    """
    if maskDir:
        absMaskPath = abspath(maskDir)
        masks = walk(absMaskPath).next()[2]
        numMasks = len(masks)
        numScans = len(inputs)
        if numMasks == 1:
                for inputFH in inputs:
                    inputFH.setMask(absMaskPath + "/" + masks[0])
        elif numMasks == numScans:
            for m in masks:
                maskBase = fh.removeBaseAndExtension(m).split("_mask")[0]
                for inputFH in inputs:
                    if fnmatch.fnmatch(inputFH.getLastBasevol(), "*" + maskBase + "*"):
                        inputFH.setMask(absMaskPath + "/" + m)
        else:
            logger.error("Number of masks in directory does not match number of scans, but is greater than 1. Exiting...")
            sys.exit()
    else:
        logger.info("No mask directory specified as command line option. No masks included during RegistrationPipeFH initialization.")
    return inputs
 def __init__(self, filename, mask=None, basedir=None):
     self.groupedFiles = [RegistrationGroupedFiles(filename, mask)]
     # We will always have only one group for the base class.
     self.currentGroupIndex = 0
     self.inputFileName = filename
     self.mask = mask
     self.basename = fh.removeBaseAndExtension(self.inputFileName)
     """basedir optional for base class.
        If not specified, we assume we just need to read files, 
        but don't need to write anything associated with them
        Need to specify a basedir if any output is needed
        If unspecified, set as current directory (but assume no writing)"""
     if basedir:
         self.basedir = fh.makedirsIgnoreExisting(basedir)
     else:
         self.basedir = abspath(curdir)
         
     """Set up logDir in base directory.
        Subclasses will create additional directories as well."""
     self.setupNames()
Exemplo n.º 20
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)
Exemplo n.º 21
0
    def __init__(self, xfm, FH=None, logFile=None):
        CmdStage.__init__(self, None)

        try:
            self.xfm = xfm
            if isFileHandler(FH):
                invXfmBase = fh.removeBaseAndExtension(
                    self.xfm).split(".xfm")[0]
                self.output = fh.createBaseName(FH.transformsDir,
                                                invXfmBase + "_inverted.xfm")
                self.logFile = fh.logFromFile(FH.logDir, self.output)
            else:
                invXfmBase = splitext(self.xfm)[0]
                self.output = invXfmBase + "_inverted.xfm"
                if logFile:
                    self.logFile = logFile

        except:
            print "Failed in putting together xfminvert command"
            print "Unexpected error: ", sys.exc_info()

        self.finalizeCommand()
        self.setName()
Exemplo n.º 22
0
 def __init__(self, 
              xfm,
              FH=None,
              logFile=None):
     CmdStage.__init__(self, None)
     
     try:  
         self.xfm = xfm
         if isFileHandler(FH):
             invXfmBase = fh.removeBaseAndExtension(self.xfm).split(".xfm")[0]
             self.output = fh.createBaseName(FH.transformsDir, invXfmBase + "_inverted.xfm")
             self.logFile = fh.logFromFile(FH.logDir, self.output)
         else:
             invXfmBase = splitext(self.xfm)[0]
             self.output = invXfmBase + "_inverted.xfm"
             if logFile:
                 self.logFile = logFile
 
     except:
         print "Failed in putting together xfminvert command"
         print "Unexpected error: ", sys.exc_info()
                                            
     self.finalizeCommand()
     self.setName()
Exemplo n.º 23
0
 def setOutputFile(self, inFile, defaultDir):
     outDir = inFile.setOutputDirectory(defaultDir)
     outBase = (fh.removeBaseAndExtension(self.xfm) + "_linear_part.xfm")
     outputFile = fh.createBaseName(outDir, outBase)
     return(outputFile)  
Exemplo n.º 24
0
def createOutputFileName(iFH, xfm, outputDir, nameExt):
    outDir = iFH.setOutputDirectory(outputDir)
    outBase = fh.removeBaseAndExtension(xfm) + nameExt
    outputFile = fh.createBaseName(outDir, outBase)
    return outputFile
Exemplo n.º 25
0
 def calcDetAndLogDet(self, useFullDisp=False):  
     if useFullDisp:
         dispToUse = self.fullDisp #absolute jacobians
     else:
         dispToUse = self.nlinDisp #relative jacobians
     """Insert -1 at beginning of blurs array to include the calculation of unblurred jacobians."""
     self.blurs.insert(0,-1)    
     for b in self.blurs:
         """Create base name for determinant calculation."""
         outputBase = fh.removeBaseAndExtension(dispToUse).split("_displacement")[0]
         """Calculate smoothed deformation field for all blurs other than -1"""
         if b != -1:
             fwhm = "--fwhm=" + str(b)
             outSmooth = fh.createBaseName(self.inputFH.tmpDir, 
                                    outputBase + "_smooth_displacement_fwhm" + str(b) + ".mnc")
             cmd = ["smooth_vector", "--clobber", "--filter", fwhm, 
                    InputFile(dispToUse), OutputFile(outSmooth)]
             smoothVec = CmdStage(cmd)
             smoothVec.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outSmooth)))
             self.p.addStage(smoothVec)
             """Set input for determinant calculation."""
             inputDet = outSmooth
             nameAddendum = "_fwhm" + str(b)
         else:
             inputDet = dispToUse
             nameAddendum = ""
         outputDet = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_determinant" + nameAddendum + ".mnc")
         outDetShift = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_det_plus1" + nameAddendum + ".mnc")
         
         if useFullDisp: 
             #absolute jacobians
             outLogDet = fh.createBaseName(self.inputFH.statsDir, 
                                       outputBase + "_absolute_log_determinant" + nameAddendum + ".mnc")
         else:
             #relative jacobians
             outLogDet = fh.createBaseName(self.inputFH.statsDir, 
                                       outputBase + "_relative_log_determinant" + nameAddendum + ".mnc")
         
         """Calculate the determinant, then add 1 (per mincblob weirdness)"""
         
         cmd = ["mincblob", "-clobber", "-determinant", InputFile(inputDet), OutputFile(outputDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outputDet)))
         self.p.addStage(det)
         
         cmd = ["mincmath", "-clobber", "-2", "-const", str(1), "-add", 
                InputFile(outputDet), OutputFile(outDetShift)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outDetShift)))
         self.p.addStage(det)
         
         """Calculate log determinant (jacobian) and add to statsGroup."""
         cmd = ["mincmath", "-clobber", "-2", "-log", InputFile(outDetShift), OutputFile(outLogDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outLogDet)))
         self.p.addStage(det)
         if useFullDisp:
             self.statsGroup.absoluteJacobians[b] = outLogDet
         else:
             self.statsGroup.relativeJacobians[b] = outLogDet
Exemplo n.º 26
0
 def setOutputFile(self, inFile, defaultDir):
     outDir = inFile.setOutputDirectory(defaultDir)
     outBase = (fh.removeBaseAndExtension(self.xfm) + "_linear_part.xfm")
     outputFile = fh.createBaseName(outDir, outBase)
     return(outputFile)  
Exemplo n.º 27
0
def createOutputFileName(iFH, xfm, outputDir, nameExt):
    outDir = iFH.setOutputDirectory(outputDir)
    outBase = fh.removeBaseAndExtension(xfm) + nameExt
    outputFile = fh.createBaseName(outDir, outBase)
    return outputFile
Exemplo n.º 28
0
 def calcDetAndLogDet(self, useFullDisp=False):  
     if useFullDisp:
         dispToUse = self.fullDisp #absolute jacobians
     else:
         dispToUse = self.nlinDisp #relative jacobians
     """Insert -1 at beginning of blurs array to include the calculation of unblurred jacobians."""
     self.blurs.insert(0,-1)    
     for b in self.blurs:
         """Create base name for determinant calculation."""
         outputBase = fh.removeBaseAndExtension(dispToUse).split("_displacement")[0]
         """Calculate smoothed deformation field for all blurs other than -1"""
         if b != -1:
             fwhm = "--fwhm=" + str(b)
             outSmooth = fh.createBaseName(self.inputFH.tmpDir, 
                                    outputBase + "_smooth_displacement_fwhm" + str(b) + ".mnc")
             cmd = ["smooth_vector", "--clobber", "--filter", fwhm, 
                    InputFile(dispToUse), OutputFile(outSmooth)]
             smoothVec = CmdStage(cmd)
             smoothVec.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outSmooth)))
             self.p.addStage(smoothVec)
             """Set input for determinant calculation."""
             inputDet = outSmooth
             nameAddendum = "_fwhm" + str(b)
         else:
             inputDet = dispToUse
             nameAddendum = ""
         outputDet = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_determinant" + nameAddendum + ".mnc")
         outDetShift = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_det_plus1" + nameAddendum + ".mnc")
         
         if useFullDisp: 
             #absolute jacobians
             outLogDet = fh.createBaseName(self.inputFH.statsDir, 
                                       outputBase + "_absolute_log_determinant" + nameAddendum + ".mnc")
         else:
             #relative jacobians
             outLogDet = fh.createBaseName(self.inputFH.statsDir, 
                                       outputBase + "_relative_log_determinant" + nameAddendum + ".mnc")
         
         """Calculate the determinant, then add 1 (per mincblob weirdness)"""
         
         cmd = ["mincblob", "-clobber", "-determinant", InputFile(inputDet), OutputFile(outputDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outputDet)))
         self.p.addStage(det)
         
         cmd = ["mincmath", "-clobber", "-2", "-const", str(1), "-add", 
                InputFile(outputDet), OutputFile(outDetShift)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outDetShift)))
         self.p.addStage(det)
         
         """Calculate log determinant (jacobian) and add to statsGroup."""
         cmd = ["mincmath", "-clobber", "-2", "-log", InputFile(outDetShift), OutputFile(outLogDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outLogDet)))
         self.p.addStage(det)
         if useFullDisp:
             self.statsGroup.absoluteJacobians[b] = outLogDet
         else:
             self.statsGroup.relativeJacobians[b] = outLogDet
Exemplo n.º 29
0
 def setOutputFile(self, FH, defaultDir):
     outBase = fh.removeBaseAndExtension(self.cxfm) + "-resampled.mnc"
     outDir = FH.setOutputDirectory(defaultDir)
     return (fh.createBaseName(outDir, outBase))
Exemplo n.º 30
0
    def __init__(self, 
                 inputFiles, 
                 createMontage=True,
                 montageOutPut=None,
                 scalingFactor=20,
                 message="lsq6"):
        self.p = Pipeline()
        self.individualImages = []
        self.individualImagesLabeled = [] 
        self.message = message

        if createMontage and montageOutPut == None:
            print("\nError: createMontage is specified in createQualityControlImages, but no output name for the montage is provided. Exiting...\n")
            sys.exit()

        # for each of the input files, run a mincpik call and create 
        # a triplane image.
        for inFile in inputFiles:
            if isFileHandler(inFile):
                # create command using last base vol
                inputToMincpik = inFile.getLastBasevol()
                outputMincpik = createBaseName(inFile.tmpDir,
                                            removeBaseAndExtension(inputToMincpik) + "_QC_image.png")
                cmd = ["mincpik", "-clobber",
                       "-scale", scalingFactor,
                       "-triplanar",
                       InputFile(inputToMincpik),
                       OutputFile(outputMincpik)]
                mincpik = CmdStage(cmd)
                mincpik.setLogFile(LogFile(logFromFile(inFile.logDir, outputMincpik)))
                self.p.addStage(mincpik)
                self.individualImages.append(outputMincpik)
                # we should add a label to each of the individual images
                # so it will be easier for the user to identify what
                # which images potentially fail
                outputConvert = createBaseName(inFile.tmpDir, 
                                               removeBaseAndExtension(inputToMincpik) + "_QC_image_labeled.png")
                cmdConvert = ["convert", "-label", inFile.basename,
                              InputFile(outputMincpik),
                              OutputFile(outputConvert)]
                convertAddLabel = CmdStage(cmdConvert)
                convertAddLabel.setLogFile(LogFile(logFromFile(inFile.logDir, outputConvert)))
                self.p.addStage(convertAddLabel)
                self.individualImagesLabeled.append(outputConvert)

        # if montageOutput is specified, create the overview image
        if createMontage:
            cmdmontage = ["montage", "-geometry", "+2+2"] \
                         + map(InputFile, self.individualImagesLabeled) + [OutputFile(montageOutPut)]
            montage = CmdStage(cmdmontage)
            montage.setLogFile(splitext(montageOutPut)[0] + ".log")
            message_to_print = "\n* * * * * * *\nPlease consider the following verification "
            message_to_print += "image, which shows a slice through all input "
            message_to_print += "files %s. " % self.message
            message_to_print += "\n%s\n" % (montageOutPut)
            message_to_print += "* * * * * * *\n"
            # the hook needs a return. Given that "print" does not return
            # anything, we need to encapsulate the print statement in a 
            # function (which in this case will return None, but that's fine)
            def printMessageForMontage():
                print(message_to_print)
            montage.finished_hooks.append(
                lambda : printMessageForMontage())
            self.p.addStage(montage)
Exemplo n.º 31
0
 def setOutputFile(self, FH, defaultDir):
     outBase = fh.removeBaseAndExtension(self.cxfm) + "-resampled.mnc"
     outDir = FH.setOutputDirectory(defaultDir)
     return(fh.createBaseName(outDir, outBase))  
Exemplo n.º 32
0
 def calcDetAndLogDet(self, useFullDisp=False):  
     #Lots of repetition here--let's see if we can't make some functions.
     """useFullDisp indicates whether or not to use full displacement field or non-linear component only""" 
     if useFullDisp:
         dispToUse = self.fullDisp
     else:
         dispToUse = self.nlinDisp
     """Insert -1 at beginning of blurs array to include the calculation of unblurred jacobians."""
     self.blurs.insert(0,-1)    
     for b in self.blurs:
         """Calculate default output filenames and set input for determinant calculation."""
         outputBase = fh.removeBaseAndExtension(dispToUse).split("_displacement")[0]
         inputDet = dispToUse
         outputDet = fh.createBaseName(self.inputFH.tmpDir, outputBase + "_determinant.mnc")
         outDetShift = fh.createBaseName(self.inputFH.tmpDir, outputBase + "_det_plus1.mnc")
         outLogDet = fh.createBaseName(self.inputFH.statsDir, outputBase + "_log_determinant.mnc")
         outLogDetScaled = fh.createBaseName(self.inputFH.statsDir, outputBase + "_log_determinant_scaled.mnc")
         """Calculate smoothed deformation field for all blurs other than -1"""
         if b != -1:
             fwhm = "--fwhm=" + str(b)
             outSmooth = fh.createBaseName(self.inputFH.tmpDir, 
                                    outputBase + "_smooth_displacement_fwhm" + str(b) + ".mnc")
             cmd = ["smooth_vector", "--clobber", "--filter", fwhm, 
                    InputFile(dispToUse), OutputFile(outSmooth)]
             smoothVec = CmdStage(cmd)
             smoothVec.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outSmooth)))
             self.p.addStage(smoothVec)
             """Override file name defaults for each blur and set input for determinant calculation."""
             inputDet = outSmooth
             outputDet = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_determinant_fwhm" + str(b) + ".mnc")
             outDetShift = fh.createBaseName(self.inputFH.tmpDir, 
                                       outputBase + "_det_plus1_fwhm" + str(b) + ".mnc")
             outLogDet = fh.createBaseName(self.inputFH.statsDir, 
                                       outputBase + "_log_determinant_fwhm" + str(b) + ".mnc")
             outLogDetScaled = fh.createBaseName(self.inputFH.statsDir, 
                                                 outputBase + "_log_determinant_scaled_fwhm" + str(b) + ".mnc")
         
         """Calculate the determinant, then add 1 (per mincblob weirdness)"""
         
         cmd = ["mincblob", "-clobber", "-determinant", InputFile(inputDet), OutputFile(outputDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outputDet)))
         self.p.addStage(det)
         
         cmd = ["mincmath", "-clobber", "-2", "-const", str(1), "-add", 
                InputFile(outputDet), OutputFile(outDetShift)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outDetShift)))
         self.p.addStage(det)
         
         """Calculate log determinant (jacobian) and add to statsGroup."""
         cmd = ["mincmath", "-clobber", "-2", "-log", InputFile(outDetShift), OutputFile(outLogDet)]
         det = CmdStage(cmd)
         det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outLogDet)))
         self.p.addStage(det)
         self.statsGroup.jacobians[b] = outLogDet
         
         """If self.linearXfm present, calculate scaled log determinant (scaled jacobian) and add to statsGroup"""
         if not useFullDisp:
             """
                 If self.scaleFactor is specified, then concatenate this additional transform
                 with self.linearXfm. Typically, this will come from an LSQ12 registration, but
                 may come from another alignment. 
             """
             if self.scalingFactor:
                 toConcat = [self.scalingFactor, self.linearXfm]
                 self.fullLinearXfm = fh.createBaseName(self.inputFH.transformsDir, self.inputFH.basename + "_full_linear.xfm")
                 logFile=fh.logFromFile(self.inputFH.logDir, fh.removeBaseAndExtension(self.fullLinearXfm))
                 concat = xfmConcat(toConcat, self.fullLinearXfm, logFile=logFile)
                 self.p.addStage(concat)
             else:
                 self.fullLinearXfm = self.linearXfm
             cmd = ["scale_voxels", "-clobber", "-invert", "-log", 
                    InputFile(self.fullLinearXfm), InputFile(outLogDet), OutputFile(outLogDetScaled)]
             det = CmdStage(cmd)
             det.setLogFile(LogFile(fh.logFromFile(self.inputFH.logDir, outLogDetScaled)))
             self.p.addStage(det)
             self.statsGroup.scaledJacobians[b] = outLogDetScaled
         else:
             self.statsGroup.scaledJacobians = None
Exemplo n.º 33
0
def createInvXfmName(iFH, xfm):
    invXfmBase = fh.removeBaseAndExtension(xfm).split(".xfm")[0]
    invXfm = fh.createBaseName(iFH.transformsDir, invXfmBase + "_inverted.xfm")
    return invXfm
Exemplo n.º 34
0
def setDispName(iFH, xfm, defaultDir):
        outDir = iFH.setOutputDirectory(defaultDir)
        outBase = fh.removeBaseAndExtension(xfm) + "_displacement.mnc"
        outputFile = fh.createBaseName(outDir, outBase)
        return outputFile  
Exemplo n.º 35
0
def createPureNlinXfmName(iFH, xfm):
    nlinBase = fh.removeBaseAndExtension(xfm) + "_pure_nlin.xfm"
    nlinXfm = fh.createBaseName(iFH.tmpDir, nlinBase)
    return nlinXfm