Browse Source

Adding segmentationBrowser

Andrej Studen 2 years ago
parent
commit
343e30ba83
1 changed files with 121 additions and 30 deletions
  1. 121 30
      slicerModules/segmentationBrowser.py

+ 121 - 30
slicerModules/segmentationBrowser.py

@@ -9,6 +9,7 @@ import nixModule
 import pathlib
 import chardet
 import re
+import functools
 #
 # labkeySlicerPythonExtension
 #
@@ -51,7 +52,7 @@ class segmentationBrowserWidget(ScriptedLoadableModuleWidget):
         self.addInfoSection()
         self.addSetupSection()
         self.addPatientsSelector()
-        #self.addSegmentEditor()
+        self.addSegmentViewer()
         self.addWindowManipulator()
 
     def addInfoSection(self):  
@@ -223,21 +224,20 @@ class segmentationBrowserWidget(ScriptedLoadableModuleWidget):
         submitFrame.setStyleSheet("background-color:rgba(220,215,180,45)")
         self.reviewBoxLayout.addWidget(submitFrame)
 
-    def addSegmentEditor(self):
+    def addSegmentViewer(self):
         #not used (for review)
         editorCollapsibleButton = ctk.ctkCollapsibleButton()
-        editorCollapsibleButton.text = "Segment Editor"
+        editorCollapsibleButton.text = "Segment Viewer"
         self.layout.addWidget(editorCollapsibleButton)
-        hLayout=qt.QVBoxLayout(editorCollapsibleButton)
+        self.vSegViewLayout=qt.QVBoxLayout(editorCollapsibleButton)
 
-        self.segmentEditorWidget=slicer.qMRMLSegmentEditorWidget()
-        hLayout.addWidget(self.segmentEditorWidget)
+        segList='                   '.join(self.logic.segmentList)
+        label=qt.QLabel("                        {}".format(segList))
+        self.vSegViewLayout.addWidget(label)
 
-        self.segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
-        segEditorNode=slicer.vtkMRMLSegmentEditorNode()
-        slicer.mrmlScene.AddNode(segEditorNode)
-        self.segmentEditorWidget.setMRMLSegmentEditorNode(segEditorNode)
-       
+        self.segList=[]
+
+        
     def addWindowManipulator(self):
         windowManipulatorCollapsibleButton=ctk.ctkCollapsibleButton()
         windowManipulatorCollapsibleButton.text="CT Window Manipulator"
@@ -359,24 +359,88 @@ class segmentationBrowserWidget(ScriptedLoadableModuleWidget):
             self.patientList.addItem(id)
 
     def onPatientLoadButtonClicked(self):
+        #clear first
+        self.logic.clearVolumesAndSegmentations()
         print("Load")
         #delegate loading to logic
         self.logic.loadImages(self.currentRow,self.keepCached.isChecked())
         self.logic.loadSegmentations(self.currentRow)
-        #self.setSegmentEditor()
+        self.updateSegmentationViewer(self.logic.segmentationRows)
         #self.logic.loadReview(self.currentRow)
         #self.logic.loadAE(self.currentRow)
 
         #self.onReviewSegmentChanged()
 
-    def setSegmentEditor(self):
-        #not used
-        #use current row to set segment in segment editor
-        self.segmentEditorWidget.setSegmentationNode(
-            self.logic.volumeNode['Segmentation'])
-        self.segmentEditorWidget.setMasterVolumeNode(
-            self.logic.volumeNode['PET'])
-  
+    def generateSegmentationView(self):
+        s=qt.QHBoxLayout()
+        nm=qt.QLabel("name")
+        s.addWidget(nm)
+        for g in self.logic.segmentList:
+            t=qt.QCheckBox()
+            s.addWidget(t)
+        return s
+    
+    def setSegmentationViewName(self,s,name):
+        label=s.itemAt(0).widget()
+        label.setText(name)
+
+    def getWidgetsFromLayout(self,s):
+        return [s.itemAt(i).widget() for i in range(s.count())]
+    
+    def hideLayout(self,s):
+        for w in self.getWidgetsFromLayout(s):
+            w.hide() 
+            
+    def disconnect(self,s):
+        for w in self.getWidgetsFromLayout(s)[1:]:
+            try:
+                w.stateChanged.disconnect()
+            except TypeError:
+                continue
+             
+    
+    def showLayout(self,s):
+        for w in self.getWidgetsFromLayout(s):
+            w.show() 
+    
+    def refreshCallbacks(self,s,entry):
+        w=self.getWidgetsFromLayout(s)
+        for i in range(len(self.logic.segmentList)):
+            w[i+1].stateChanged.connect(functools.partial(self.onSegmentationViewChanged,
+                                                    latestFile=entry['latestFile'],
+                                                    segment=self.logic.segmentList[i]))
+            
+
+    def getUserMap(self):
+        users=self.logic.lookups['core:Users']
+        #print('{}'.format(users))
+        return users
+
+    def updateSegmentationViewer(self,rows):
+        users=self.getUserMap()
+        for s in self.segList:
+            self.hideLayout(s)
+            self.disconnect(s)
+            #can't hide a layout
+            
+            #s.hide()
+        i=0
+        for r in rows:
+            try:
+                s=self.segList[i]
+            except IndexError:
+                #assume we only have to add one (since we iterate sequentially)
+                self.segList.append(self.generateSegmentationView())
+                s=self.segList[i]
+                self.vSegViewLayout.addLayout(s)
+            self.showLayout(s)
+            self.setSegmentationViewName(s,users[r['User']])
+            self.refreshCallbacks(s,r)
+            i+=1
+
+
+        
+
     def onReviewSegmentChanged(self):
         pass
 
@@ -402,6 +466,10 @@ class segmentationBrowserWidget(ScriptedLoadableModuleWidget):
     def onCtLungButtonClicked(self):
         self.logic.setWindow('CT:lung')
 
+    def onSegmentationViewChanged(self,state,latestFile,segment):
+        print('onSegmentationViewChanged {} {} {} '.format(latestFile,segment,state))
+        self.logic.toggleSegmentVisibility(latestFile,segment,state>0)
+
     def cleanup(self):
         pass
 
@@ -619,9 +687,13 @@ class segmentationBrowserLogic(ScriptedLoadableModuleLogic):
         if idx=="Segmentation":
             filetype='SegmentationFile'
             #properties["labelmap"]=1
-              
+
+        try:
+            volumeIdx=iData['volumeIdx']
+        except KeyError:   
+            volumeIdx=idx
           
-        self.volumeNode[idx]=slicer.util.loadNodeFromFile(localPath,
+        self.volumeNode[volumeIdx]=slicer.util.loadNodeFromFile(localPath,
                         filetype=filetype,properties=properties)
           
         if not keepCached:
@@ -664,34 +736,38 @@ class segmentationBrowserLogic(ScriptedLoadableModuleLogic):
             'visitCode':row['visitCode']}
         ds=self.getDataset(name='SegmentationsMaster',
                 dbFilter=dbFilter)
-        if len(ds['rows'])<0:
+        self.segmentationRows=ds['rows']
+        if len(self.segmentationRows)<0:
             print('No segmentations for {}'.format(dbFilter))
             return
-        for r in ds['rows']:
+        for r in self.segmentationRows:
             #update self.segmentationEntry
             #self.segmentationEntry=ds['rows'][0]
             #self.segmentationEntry['origin']='database'
             #if loadFile:
             self.loadSegmentationFromEntry(r)
-            return
+            #make invisile by default
+            for s in self.segmentList:
+                self.toggleSegmentVisibility(r['latestFile'],s,False)
         print('load Segmentation: done')
         #create new segmentation 
         #self.createSegmentation(row)
 
-    def getSegmentationPath(self):
+    def getSegmentationPath(self,entry):
         path=[self.isetup['imageDir'],
-                self.segmentationEntry['patientCode'],
-                self.segmentationEntry['visitCode']]
+                entry['patientCode'],
+                entry['visitCode']]
         path.append('Segmentations')
         return path
 
     def loadSegmentationFromEntry(self,r):
         #compile path
         entry=r
-        path=self.getSegmentationPath()
+        path=self.getSegmentationPath(entry)
         path.append(entry['latestFile'])
         iData={'idx':'Segmentation','path':path,
-                    'keepCached':0,'dataset':'SegmentationsMaster'}
+                    'keepCached':0,'dataset':'SegmentationsMaster',
+                    'volumeIdx':entry['latestFile']}
         self.loadImage(iData)
         #look for missing segments
         return
@@ -710,6 +786,17 @@ class segmentationBrowserLogic(ScriptedLoadableModuleLogic):
                 print(s)
         print('Done')
 
+    def toggleSegmentVisibility(self,latestFile,segmentId,visible):
+        segNode=self.volumeNode[latestFile]
+        if segNode==None:
+            print('Could not find segNode')
+            return
+        seg=segNode.GetSegmentation()
+        segment=seg.GetSegment(segmentId)
+        if segment==None:
+            print('Could not find segment {}'.format(segmentId))
+            return
+        segNode.GetDisplayNode().SetSegmentVisibility(segmentId, visible)
 
 
 
@@ -806,6 +893,10 @@ class segmentationBrowserLogic(ScriptedLoadableModuleLogic):
         nodes=slicer.util.getNodesByClass("vtkMRMLVolumeNode")
         nodes.extend(slicer.util.getNodesByClass("vtkMRMLSegmentationNode"))
         res=[slicer.mrmlScene.RemoveNode(f) for f in nodes] 
+        try:
+            self.volumeNode.clear()
+        except AttributeError:
+            pass
         #self.segmentationNode=None
         #self.reviewResult={}
         #self.aeList={}