diff --git a/AutoWorkup/BRAINSCutCMD.py b/AutoWorkup/BRAINSCutCMD.py index db50f5ef..a54a93ab 100755 --- a/AutoWorkup/BRAINSCutCMD.py +++ b/AutoWorkup/BRAINSCutCMD.py @@ -59,7 +59,11 @@ def xmlGenerator(args, roi=""): outputStream.write(" TrainingModelFilename = \"na\"\n") # outputStream.write( " TrainingModelFilename = \"/nfsscratch/PREDICT/TEST_BRAINSCut/20120828ANNModel_Model_RF100.txt\"\n") outputStream.write(" TestVectorFilename = \"na\"\n") - outputStream.write(" Normalization = \"" + args.vectorNormalization + "\"\n") + if roi == "caudate": + outputStream.write(" Normalization = \"" + 'Linear' + "\"\n") + else: + outputStream.write(" Normalization = \"" + args.vectorNormalization + "\"\n") + outputStream.write(" />\n") # @@ -125,6 +129,8 @@ def xmlGenerator(args, roi=""): if args.inputSubjectT2Filename is not None: outputStream.write(" \n") outputStream.write(" \n") + if roi == "caudate": + outputStream.write(" \n") # outputStream.write( " \n".format(fn=args.inputSubjectTotalGMFilename)) # outputStream.write( " \n".format(fn=args.inputSubjectRegistrationROIFilename)) @@ -163,6 +169,9 @@ def xmlGenerator(args, roi=""): brainscutParser = argparse.ArgumentParser(description='BRAINSCut command line argument parser') +# HACK: This is to allow special treatment of caudates with masking +brainscutParser.add_argument('--candidateRegion', help='Specify the valid candidate region for caudate', required=True) + # # input arguments # @@ -232,7 +241,10 @@ def xmlGenerator(args, roi=""): for roi in roiList: currentXmlFilename = xmlGenerator(args, roi) - currentModelFilename = args.modelFilename[:-3] + '_' + roi + '.gz' # trainModelFile.txtD0060NT0060_accumben.gz + if roi == "caudate": + currentModelFilename = args.modelFilename[:-3] + '_' + roi + '_LinearWithMask.gz' # trainModelFile.txtD0060NT0060_caudate_LinearWithMask.gz + else: + currentModelFilename = args.modelFilename[:-3] + '_' + roi + '.gz' # trainModelFile.txtD0060NT0060_accumben.gz BRAINSCutCommand = ["BRAINSCut" + " --applyModel " + " --netConfiguration " + currentXmlFilename + diff --git a/AutoWorkup/PipeLineFunctionHelpers.py b/AutoWorkup/PipeLineFunctionHelpers.py index 41e031a7..e1ff2ab4 100644 --- a/AutoWorkup/PipeLineFunctionHelpers.py +++ b/AutoWorkup/PipeLineFunctionHelpers.py @@ -19,6 +19,27 @@ def convertToList(element): return [ element ] +def MakeInclusionMaskForGMStructures( posteriorDictionary ): + import SimpleITK as sitk + + AIR_FN=posteriorDictionary['AIR'] + CSF_FN=posteriorDictionary['CSF'] + VB_FN=posteriorDictionary['VB'] + WM_FN=posteriorDictionary['WM'] + + AIR_PROB=sitk.ReadImage(AIR_FN) + CSF_PROB=sitk.ReadImage(CSF_FN) + VB_PROB=sitk.ReadImage(VB_FN) + WM_PROB=sitk.ReadImage(WM_FN) + + AIR_Region=sitk.BinaryThreshold(AIR_PROB,0.51,1.01,1,0) + CSF_Region=sitk.BinaryThreshold(CSF_PROB,0.51,1.01,1,0) + VB_Region=sitk.BinaryThreshold(VB_PROB,0.51,1.01,1,0) + WM_Region=sitk.BinaryThreshold(WM_PROB,0.99,1.01,1,0) #NOTE: Higher tolerance for WM regions! + + outputCandidateRegion=sitk.BinaryThreshold(AIR_Region+CSF_Region+VB_Region+WM_Region,1,100,0,1) #NOTE: Inversion of input/output definitions + + return outputCandidateRegion def makeListOfValidImages(imageFile): if imageFile is None: diff --git a/AutoWorkup/RF12BRAINSCutWrapper.py b/AutoWorkup/RF12BRAINSCutWrapper.py index fd7e76f7..86b074f7 100644 --- a/AutoWorkup/RF12BRAINSCutWrapper.py +++ b/AutoWorkup/RF12BRAINSCutWrapper.py @@ -21,6 +21,7 @@ class RF12BRAINSCutWrapperCLInputSpec(CommandLineInputSpec): ### subject specific inputSubjectT1Filename = File(desc="Subject T1 Volume", exists=True, mandatory=True, argstr="--inputSubjectT1Filename %s") inputSubjectT2Filename = File(desc="Subject T2 Volume", exists=True, mandatory=False, argstr="--inputSubjectT2Filename %s") + candidateRegion = File(desc="Valid region for finding GM structures", exists=True, mandatory=True, argstr="--candidateRegion %s") inputSubjectGadSGFilename = File(desc="Subject SG Volume", exists=True, mandatory=False, argstr="--inputSubjectGadSGFilename %s") vectorNormalization = traits.Enum("IQR", "Linear", "Sigmoid_Q01", "Sigmoid_Q05", "ZScore", "NONE", desc="The type of intensity normalization to use", exists=True, mandatory=True, argstr="--vectorNormalization %s") diff --git a/AutoWorkup/WorkupT1T2.py b/AutoWorkup/WorkupT1T2.py index ad68a844..b82650fc 100644 --- a/AutoWorkup/WorkupT1T2.py +++ b/AutoWorkup/WorkupT1T2.py @@ -774,6 +774,8 @@ def WorkupT1T2(subjectid, mountPrefix, ExperimentBaseDirectoryCache, ExperimentB myLocalSegWF[sessionid] = CreateBRAINSCutWorkflow(projectid, subjectid, sessionid, 'Segmentation', CLUSTER_QUEUE, CLUSTER_QUEUE_LONG, BAtlas[subjectid], t1Only) # Note: Passing in the entire BAtlas Object here! + baw200.connect(PHASE_2_oneSubjWorkflow[sessionid], 'outputspec.posteriorImages', myLocalSegWF[sessionid], + "inputspec.posteriorDictionary") baw200.connect(PHASE_2_oneSubjWorkflow[sessionid], 'outputspec.t1_average', myLocalSegWF[sessionid], "inputspec.T1Volume") if (len(global_AllT2s[sessionid]) > 0): diff --git a/AutoWorkup/WorkupT1T2BRAINSCut.py b/AutoWorkup/WorkupT1T2BRAINSCut.py index 442be895..66851c0b 100644 --- a/AutoWorkup/WorkupT1T2BRAINSCut.py +++ b/AutoWorkup/WorkupT1T2BRAINSCut.py @@ -126,9 +126,10 @@ def CreateBRAINSCutWorkflow(projectid, cutWF = pe.Workflow(name=GenerateWFName(projectid, subjectid, sessionid, WFName)) inputsSpec = pe.Node(interface=IdentityInterface(fields=['T1Volume', 'T2Volume', - 'TotalGM', 'RegistrationROI', + 'posteriorImageDictionary', 'RegistrationROI', 'atlasToSubjectTransform']), name='inputspec') + if not t1Only: """ Gradient Anistropic Diffusion images for BRAINSCut @@ -157,6 +158,7 @@ def CreateBRAINSCutWorkflow(projectid, cutWF.connect(GADT1, 'outputVolume', SGI, 'inputVolume1') cutWF.connect(GADT2, 'outputVolume', SGI, 'inputVolume2') + """ BRAINSCut """ @@ -194,6 +196,14 @@ def CreateBRAINSCutWorkflow(projectid, RF12BC.inputs.outputBinaryRightGlobus = 'subjectANNLabel_r_globus.nii.gz' cutWF.connect(inputsSpec, 'T1Volume', RF12BC, 'inputSubjectT1Filename') + + from PipeLineFunctionHelpers import MakeInclusionMaskForGMStructures; + makeCandidateRegionNode = pe.Node(interface=Function(['posteriorDictionary'], + ['outputCandidateRegion'], + function=MakeInclusionMaskForGMStructures), name="MakeCandidateRegion") + cutWF.connect(inputsSpec,'posteriorDictionary',makeCandidateRegionNode,'posteriorDictionary') + cutWF.connect(makeCandidateRegionNode,'outputCandidateRegion', RF12BC,'candidateRegion') + if not t1Only: cutWF.connect(inputsSpec, 'T2Volume', RF12BC, 'inputSubjectT2Filename') # cutWF.connect(inputsSpec,'TotalGM',RF12BC,'inputSubjectTotalGMFilename')