Преглед изворни кода

Adding segmentation configuration files

Andrej Studen пре 3 година
родитељ
комит
9ae439d111

+ 0 - 0
pythonScripts/runSegmentation.py → pythonScripts/runSegmentationDM.py


+ 259 - 0
pythonScripts/runSegmentationnnUNet.py

@@ -0,0 +1,259 @@
+import os
+import json
+import re
+import subprocess
+import nibabel
+import shutil
+import sys
+import pathlib
+import SimpleITK
+import numpy
+
+#nothing gets done if you do import
+
+def getPatientLabel(row,participantField='PatientId'):
+    return row[participantField].replace('/','_') 
+
+def getVisitLabel(row):
+    return 'VISIT_'+str(int(row['SequenceNum']))
+
+def getStudyLabel(row,participantField='PatientId'):
+    return getPatientLabel(row,participantField)+'-'+getVisitLabel(row)
+
+
+def updateRow(project,dataset,row,imageResampledField,gzFileNames,\
+        participantField='PatientId'):
+    row['patientCode']=getPatientLabel(row,participantField)
+    row['visitCode']=getVisitLabel(row)
+    for im in imageResampledField:
+        row[imageResampledField[im]]=gzFileNames[im]
+    db.modifyRows('update',project,'study',dataset,[row])
+ 
+def replacePatterns(infile,outfile,replacePatterns):
+    of=open(outfile,'w')
+    with open(infile,'r') as f:
+        data=f.read()
+        for p in replacePatterns:
+            val=replacePatterns[p]
+            data=re.sub(p,val,data)
+    of.write(data)
+    of.close()
+    
+def valueSubstitution(pars,val):
+    if val.find('__home__')>-1:
+        val=re.sub(r'__home__',os.path.expanduser('~'),val)
+
+    return path
+
+def getSuffix(tempFile):
+    p=pathlib.Path(tempFile)
+    return ''.join(p.suffixes)
+
+def getSegmImagePath(tempFile):
+    sfx=getSuffix(tempFile)
+    return re.sub(sfx,'_Segm'+sfx,tempFile)
+
+def addVersion(tempFile,version):
+    sfx=getSuffix(tempFile)
+    return re.sub(sfx,'_'+version+sfx,tempFile)
+
+def addnnUNetCode(tempFile,fileNumber=0):
+    sfx=getSuffix(tempFile)
+    return re.sub(sfx,'_'+'{:04d}'.format(fileNumber)+sfx,tempFile)
+
+def runnnUNet(setup,pars):
+    args=[]
+    #set the environment
+    args.append(setup['paths']['nnUNetRunInference'])
+    #location of input images
+    args.extend(['-i',os.path.join(pars['tempBase'],'CT')])
+    #output path is segmentations
+    args.extend(['-o',os.path.join(pars['tempBase'],'segmentations')])
+    #modelid, nnUNet internal rules.
+    args.extend(['-t',pars['nnUNet']['ModelId']])
+    #specify configuration (3d_fullres)
+    args.extend(['-m',pars['nnUNet']['configuration']])
+    print(args) 
+    my_env = os.environ
+    for key in pars['nnUNet']['env']:
+        my_env[key]=pars['nnUNet']['env'][key]
+      
+    print(subprocess.run(args,env=my_env,check=True,stdout=subprocess.PIPE).stdout)
+
+def getSegmentationFile(pars):
+    #this is how deep medic stores files
+    return os.path.join(pars['tempBase'],'segmentations',\
+            pars['images']['CT']['tempFile'])
+            
+
+def runSegmentation(fb,row,pars,setup):
+    
+     
+    #download to temp file (could be a fixed name)
+    project=pars['project']
+    images=pars['images']
+    participantField=pars['participantField']
+    baseDir=fb.formatPathURL(project,pars['imageDir']+'/'+\
+        getPatientLabel(row,participantField)+'/'+\
+        getVisitLabel(row))
+    
+    #download CT
+    ctDir=os.path.join(pars['tempBase'],'CT')
+    if not os.path.isdir(ctDir):
+        os.mkdir(ctDir)
+    fullFile=os.path.join(ctDir,images['CT']['tempFile']) 
+
+    fullFile=addnnUNetCode(fullFile)
+    fb.readFileToFile(baseDir+'/'+row[images['CT']['queryField']],fullFile)
+    
+    #debug
+
+    #run deep medic
+    runnnUNet(setup,pars)
+
+    #processed file is
+    segFile=getSegmentationFile(pars)
+    #SimpleITK.WriteImage(outImg,segFile)
+    return segFile
+
+        
+def test(parameterFile):
+    
+    fhome=os.path.expanduser('~')
+
+    
+    with open(os.path.join(fhome,".labkey","setup.json")) as f:
+        setup=json.load(f)
+
+    sys.path.insert(0,setup["paths"]["nixWrapper"])
+    
+    import nixWrapper
+    
+    nixWrapper.loadLibrary("labkeyInterface")#force reload
+    import labkeyInterface
+    import labkeyDatabaseBrowser
+    import labkeyFileBrowser
+
+    nixWrapper.loadLibrary("parseConfig")
+    import parseConfig
+
+    with open(parameterFile) as f:
+        pars=json.load(f)
+    
+    pars=parseConfig.convert(pars)
+    pars=parseConfig.convertValues(pars)
+    #print(pars)
+
+
+    
+
+def doSegmentation(parameterFile):
+    fhome=os.path.expanduser('~')
+
+    
+    with open(os.path.join(fhome,".labkey","setup.json")) as f:
+        setup=json.load(f)
+
+    sys.path.insert(0,setup["paths"]["nixWrapper"])
+    
+    import nixWrapper
+    
+    nixWrapper.loadLibrary("labkeyInterface")#force reload
+    import labkeyInterface
+    import labkeyDatabaseBrowser
+    import labkeyFileBrowser
+
+    nixWrapper.loadLibrary("parseConfig")
+    import parseConfig
+
+    with open(parameterFile) as f:
+        pars=json.load(f)
+    
+    pars=parseConfig.convert(pars)
+    pars=parseConfig.convertValues(pars)
+    
+    project=pars['project']
+    dataset=pars['targetQuery']
+    schema=pars['targetSchema']
+    view=pars['viewName']
+
+
+    tempBase=pars['tempBase']
+    if not os.path.isdir(tempBase):
+        os.makedirs(tempBase)
+
+    #start the database interface
+    fconfig=os.path.join(fhome,'.labkey','network.json')
+    net=labkeyInterface.labkeyInterface()
+    net.init(fconfig)
+    db=labkeyDatabaseBrowser.labkeyDB(net)
+    fb=labkeyFileBrowser.labkeyFileBrowser(net)
+
+
+    #all images from database
+    ds=db.selectRows(project,schema,dataset,[],view)
+    
+    #input
+    #use webdav to transfer file (even though it is localhost)
+
+ 
+    i=0
+    rows=[ds['rows'][0]]
+    rows=ds['rows']
+    for row in rows:
+       
+
+        #check if file is already there
+        #dummy tf to get the suffix
+        sfx=pars['images']['segmentation']['suffix']
+        outpath=fb.buildPathURL(pars['project'],[pars['imageDir'],row['patientCode'],row['visitCode']])
+        outName=addVersion(\
+                getSegmImagePath(\
+                    getStudyLabel(row,pars['participantField'])+sfx),\
+                pars['version'])
+
+        outFile=outpath+'/'+outName
+
+        #check if file is there
+        if not fb.entryExists(outFile):
+
+            
+            segFile=getSegmentationFile(pars)
+            #remove existing file
+            if os.path.isfile(segFile):
+                os.remove(segFile)
+            
+            segFile=runSegmentation(fb,row,pars,setup)
+            #copy file to file
+            #normally I would update the targetQuery, but it contains previously set images
+            #copy to labkey
+            fb.writeFileToFile(segFile,outFile)
+            print(segFile)
+        #debug 
+
+        #update database
+        copyFields=[pars['participantField'],'SequenceNum','patientCode','visitCode']
+        row['SequenceNum']+=0.001*float(pars['versionNumber'])
+        filters=[{'variable':v,'value':str(row[v]),'oper':'eq'} for v in copyFields]
+        filters.append({'variable':'Version','value':pars['version'],'oper':'eq'})
+
+        ds1=db.selectRows(pars['project'],pars['segmentationSchema'],pars['segmentationQuery'],filters)
+
+        if len(ds1['rows'])>0:
+            mode='update'
+            outRow=ds1['rows'][0]
+        else:
+            mode='insert'
+            outRow={v:row[v] for v in copyFields}
+        outRow['Version']= pars['version']
+        outRow['Segmentation']= outName
+        print(db.modifyRows(mode,pars['project'],pars['segmentationSchema'],pars['segmentationQuery'],[outRow]))
+        #pull results back to LabKey
+    print("Done")
+
+
+if __name__ == '__main__':
+    #test(sys.argv[1])
+    doSegmentation(sys.argv[1])
+    #sys.exit()
+

+ 84 - 0
templates/segmentationIRAEMM.json

@@ -0,0 +1,84 @@
+{
+ "setVariables":["__tempBase__","__segBase__","__roiFile__","__petFile__","__ctFile__","__segFile__","__modelName__"],
+ "setVariablesComment":"this variables will get updated with local values like home and can be used to set variables further on",
+ "__tempBase__":"__home__/temp/segmentationdm",
+ "__segBase__":"/home/studen/software/src/iraemm/segmentation",
+ "__roiFile__":"testMask.nii.gz",
+ "__ctFile__":"testCT.nii.gz",
+ "__petFile__":"testPET.nii.gz",
+ "__segFile__":"segmentation.nii.gz",
+ "__modelName__":"DM_defaults.DM_train_VISCERAL16_Fold1.final.2019-10-01.07.46.19.932616.model.ckpt",
+ "tempBase":"__tempBase__",
+ "model":"__model__",
+ "project":"/iPNUMMretro/Study",
+ "targetSchema":"study",
+ "targetQuery":"Imaging1",
+ "viewName":"segmentationReview",
+ "participantField":"PatientId",
+ "segmentationSchema":"study",
+ "segmentationQuery":"Segmentations",
+ "imageDir":"preprocessedImages",
+ "version":"v5",
+ "versionNumber":"5",
+ "images":{
+	"CT":{
+		"queryField":"ctResampled",
+		"tempFile":"__ctFile__"},
+	"PET":{
+		"queryField":"petResampled",
+		"tempFile":"__petFile__"},
+	"patientmask":{
+		"queryField":"ROImask",
+		"tempFile":"__roiFile__"},
+	"segmentation":{
+		"suffix":".nii.gz"
+	}
+ },
+ "replacePattern":{
+	 "__workDir__":"__tempBase__",
+	 "__roi__":"__tempBase__/__roiFile__",
+	 "__pet__":"__tempBase__/__petFile__",
+	 "__ct__":"__tempBase__/__ctFile__",
+	 "__seg__":"__tempBase__/__segFile__",
+	 "__model__":"__modelName__"
+ },
+ "nnUNet":{
+	 "ModelId":"501",
+	 "configuration":"3d_fullres",
+	 "env":{
+		"nnUNet_raw_data_base":"__tempBase__",
+		"nnUNet_preprocessed":"__tempBase__",
+		"RESULTS_FOLDER":"/home/studen/software/src/iraemmsegmentationmodels"
+	 }
+ },
+ "deepmedic": {
+	 "config":{
+		 "model":{
+		 	"template":"__segBase__/model/modelConfig.cfg.template",
+		 	"out":"__tempBase__/modelConfig.cfg"
+	 	},
+	 	"test":{
+			"template":"__segBase__/test/testConfig.cfg.template",
+		 	"out":"__tempBase__/testConfig.cfg"
+	 	},
+		"predictions":{
+			"template":"__segBase__/test/testNamesOfPredictions.cfg.template",
+			"out":"__tempBase__/testNamesOfPredictions.cfg"
+		},
+		"CT":{
+			"template":"__segBase__/test/testChannels_CT.cfg.template",
+			"out":"__tempBase__/testChannels_CT.cfg"
+		},
+		"ROI":{
+			"template":"__segBase__/test/testRoiMasks.cfg.template",
+			"out":"__tempBase__/testRoiMasks.cfg"
+		}
+
+
+
+	 }
+ }
+
+
+
+}

+ 84 - 0
templates/segmentationTCIA.json

@@ -0,0 +1,84 @@
+{
+ "setVariables":["__tempBase__","__segBase__","__roiFile__","__petFile__","__ctFile__","__segFile__","__modelName__"],
+ "setVariablesComment":"this variables will get updated with local values like home and can be used to set variables further on",
+ "__tempBase__":"__home__/temp/segmentationdm",
+ "__segBase__":"/home/studen/software/src/iraemm/segmentation",
+ "__roiFile__":"testMask.nii.gz",
+ "__ctFile__":"testCT.nii.gz",
+ "__petFile__":"testPET.nii.gz",
+ "__segFile__":"segmentation.nii.gz",
+ "__modelName__":"DM_defaults.DM_train_VISCERAL16_Fold1.final.2019-10-01.07.46.19.932616.model.ckpt",
+ "tempBase":"__tempBase__",
+ "model":"__model__",
+ "project":"/Test/segmentationTest",
+ "targetSchema":"study",
+ "targetQuery":"Imaging1",
+ "viewName":"segmentationReview",
+ "participantField":"ParticipantId",
+ "segmentationSchema":"study",
+ "segmentationQuery":"Segmentations",
+ "imageDir":"preprocessedImages",
+ "version":"v5",
+ "versionNumber":"5",
+ "images":{
+	"CT":{
+		"queryField":"ctResampled",
+		"tempFile":"__ctFile__"},
+	"PET":{
+		"queryField":"petResampled",
+		"tempFile":"__petFile__"},
+	"patientmask":{
+		"queryField":"ROImask",
+		"tempFile":"__roiFile__"},
+	"segmentation":{
+		"suffix":".nii.gz"
+	}
+ },
+ "replacePattern":{
+	 "__workDir__":"__tempBase__",
+	 "__roi__":"__tempBase__/__roiFile__",
+	 "__pet__":"__tempBase__/__petFile__",
+	 "__ct__":"__tempBase__/__ctFile__",
+	 "__seg__":"__tempBase__/__segFile__",
+	 "__model__":"__modelName__"
+ },
+ "nnUNet":{
+	 "ModelId":"501",
+	 "configuration":"3d_fullres",
+	 "env":{
+		"nnUNet_raw_data_base":"__tempBase__",
+		"nnUNet_preprocessed":"__tempBase__",
+		"RESULTS_FOLDER":"/home/studen/software/src/iraemmsegmentationmodels"
+	 }
+ },
+ "deepmedic": {
+	 "config":{
+		 "model":{
+		 	"template":"__segBase__/model/modelConfig.cfg.template",
+		 	"out":"__tempBase__/modelConfig.cfg"
+	 	},
+	 	"test":{
+			"template":"__segBase__/test/testConfig.cfg.template",
+		 	"out":"__tempBase__/testConfig.cfg"
+	 	},
+		"predictions":{
+			"template":"__segBase__/test/testNamesOfPredictions.cfg.template",
+			"out":"__tempBase__/testNamesOfPredictions.cfg"
+		},
+		"CT":{
+			"template":"__segBase__/test/testChannels_CT.cfg.template",
+			"out":"__tempBase__/testChannels_CT.cfg"
+		},
+		"ROI":{
+			"template":"__segBase__/test/testRoiMasks.cfg.template",
+			"out":"__tempBase__/testRoiMasks.cfg"
+		}
+
+
+
+	 }
+ }
+
+
+
+}