예제 #1
0
    def restoreStateBeforeExitingModule(self):
        """Load the last state of the module when the user exited (labelmap, opacity, contrast window, etc.)
        """
        try:
            if self.savedVolumeID:
                # There is a previously saved valid state.
                SlicerUtil.setActiveVolumeIds(self.savedVolumeID)
                SlicerUtil.changeContrastWindow(self.savedContrastLevel[0],
                                                self.savedContrastLevel[1])
                # if self.savedLabelmapID:
                #     print "Restoring active labelmap: " + self.savedLabelmapID
                #     # There was a valid labelmap. Restore it
                #     SlicerUtil.displayLabelmapVolume(self.savedLabelmapID)
                #     # Restore previous opacity
                #     SlicerUtil.changeLabelmapOpacity(self.savedLabelmapOpacity)
                # else:
                #     # Hide labelmap
                #     print "No labelmap saved. Hide all"
                #     SlicerUtil.displayLabelmapVolume(None)
            # else:
            #     # Hide labelmap
            #     print "No volume saved. Hide labelmap"
            #     SlicerUtil.displayLabelmapVolume(None)

            # Restore layout
            SlicerUtil.changeLayout(self.savedLayout)
        except:
            Util.print_last_exception()
            pass
    def loadFiducials(self, volumeNode, fileName):
        """ Load from disk a list of fiducials for a particular volume node
        :param volumeNode: Volume (scalar node)
        :param fileName: full path of the file to load the fiducials where
        """
        with open(fileName, "r") as f:
            xml = f.read()

        geom = GTD.GeometryTopologyData.from_xml(xml)
        for point in geom.points:
            subtype = point.chest_type
            if subtype in self.params.mainTypes.keys():
                # Main type. The subtype will be "Any"
                mainType = subtype
                subtype = 0
            else:
                mainType = self.params.getMainTypeForSubtype(subtype)
            # Activate the current fiducials list based on the main type
            fidList = self.setActiveFiducialsListNode(volumeNode, mainType, subtype, point.feature_type)
            # Check if the coordinate system is RAS (and make the corresponding transform otherwise)
            if geom.coordinate_system == geom.LPS:
                coord = Util.lps_to_ras(point.coordinate)
            elif geom.coordinate_system == geom.IJK:
                coord = Util.ijk_to_ras(volumeNode, point.coordinate)
            else:
                # Try default mode (RAS)
                coord = point.coordinate
            # Add the fiducial
            fidList.AddFiducial(coord[0], coord[1], coord[2], self.getMarkupLabel(mainType, subtype, point.feature_type))
예제 #3
0
    def saveResults(self):
        try:
            if SlicerUtil.isSlicerACILLoaded():
                saveResultsRemotely = qt.QMessageBox.question(
                    slicer.util.mainWindow(), "Save volume remotely?",
                    "Do you want to save the results remotely?",
                    qt.QMessageBox.Yes
                    | qt.QMessageBox.No) == qt.QMessageBox.Yes
            else:
                saveResultsRemotely = False
            # First, save locally to the results directory (as a backup)
            labelmap = self.getCurrentLabelMapNode()
            localPath = os.path.join(self.saveResultsDirectoryButton.directory,
                                     labelmap.GetName() + ".nrrd")
            if saveResultsRemotely:
                self.caseNavigatorWidget.uploadVolume(
                    labelmap,
                    callbackFunction=self._uploadFileCallback_,
                    localPath=localPath)
            else:
                slicer.util.saveNode(labelmap, localPath)
                slicer.util.infoDisplay(
                    "Results saved to '{}'".format(localPath))

        except Exception as ex:
            Util.print_last_exception()
            slicer.util.errorDisplay(ex.message)
예제 #4
0
    def loadFiducialsXml(self, volumeNode, fileName):
        """ Load from disk a list of fiducials for a particular volume node
        :param volumeNode: Volume (scalar node)
        :param fileName: full path of the file to load the fiducials where
        """
        with open(fileName, "r") as f:
            xml = f.read()

        self.currentGeometryTopologyData = gtd.GeometryTopologyData.from_xml(
            xml)
        for point in self.currentGeometryTopologyData.points:
            # Activate the current fiducials list based on the type list
            typesList = self.getTypesListFromXmlPoint(point)
            fidListNode = self.setActiveFiducialsListNode(
                volumeNode, typesList)
            # Check if the coordinate system is RAS (and make the corresponding transform otherwise)
            if self.currentGeometryTopologyData.coordinate_system == self.currentGeometryTopologyData.LPS:
                coord = Util.lps_to_ras(point.coordinate)
            elif self.currentGeometryTopologyData.coordinate_system == self.currentGeometryTopologyData.IJK:
                coord = Util.ijk_to_ras(volumeNode, point.coordinate)
            else:
                # Try default mode (RAS)
                coord = point.coordinate
            # Add the fiducial
            fidListNode.AddFiducial(coord[0], coord[1], coord[2],
                                    self.getMarkupLabel(typesList))
예제 #5
0
    def loadFiducialsXml(self, volumeNode, fileName):
        """ Load from disk a list of fiducials for a particular volume node
        :param volumeNode: Volume (scalar node)
        :param fileName: full path of the file to load the fiducials where
        """
        with open(fileName, "r") as f:
            xml = f.read()

        self.currentGeometryTopologyData = GTD.GeometryTopologyData.from_xml(
            xml)
        for point in self.currentGeometryTopologyData.points:
            subtype = point.chest_type
            if subtype in self.params.mainTypes.keys():
                # Main type. The subtype will be "Any"
                mainType = subtype
                subtype = 0
            else:
                mainType = self.params.getMainTypeForSubtype(subtype)
            # Activate the current fiducials list based on the main type
            fidListNode = self.setActiveFiducialsListNode(
                volumeNode, mainType, subtype, point.feature_type)
            # Check if the coordinate system is RAS (and make the corresponding transform otherwise)
            if self.currentGeometryTopologyData.coordinate_system == self.currentGeometryTopologyData.LPS:
                coord = Util.lps_to_ras(point.coordinate)
            elif self.currentGeometryTopologyData.coordinate_system == self.currentGeometryTopologyData.IJK:
                coord = Util.ijk_to_ras(volumeNode, point.coordinate)
            else:
                # Try default mode (RAS)
                coord = point.coordinate
            # Add the fiducial
            fidListNode.AddFiducial(
                coord[0], coord[1], coord[2],
                self.getMarkupLabel(mainType, subtype, point.feature_type))
예제 #6
0
 def saveResultsCurrentNode(self):
     """ Get current active node and save the xml fiducials file
     """
     try:
         d = self.saveResultsDirectoryButton.directory
         if not os.path.isdir(d):
             # Ask the user if he wants to create the folder
             if qt.QMessageBox.question(
                     slicer.util.mainWindow(), "Create directory?",
                     "The directory '{0}' does not exist. Do you want to create it?"
                     .format(d), qt.QMessageBox.Yes
                     | qt.QMessageBox.No) == qt.QMessageBox.Yes:
                 try:
                     os.makedirs(d)
                     # Make sure that everybody has write permissions (sometimes there are problems because of umask)
                     os.chmod(d, 0o777)
                 except:
                     qt.QMessageBox.warning(
                         slicer.util.mainWindow(), 'Directory incorrect',
                         'The folder "{0}" could not be created. Please select a valid directory'
                         .format(d))
                     return
             else:
                 # Abort process
                 SlicerUtil.logDevelop("Saving results process aborted",
                                       includePythonConsole=True)
                 return
                 # self.logic.saveCurrentFiducials(d, self.caseNavigatorWidget, self.uploadFileResult)
                 # qt.QMessageBox.information(slicer.util.mainWindow(), 'Results saved',
                 #                            "The results have been saved succesfully")
         # else:
         if SlicerUtil.isSlicerACILLoaded():
             question = qt.QMessageBox.question(
                 slicer.util.mainWindow(), "Save results remotely?",
                 "Your results will be saved locally. Do you also want to save your results in your remote server? (MAD, etc.)",
                 qt.QMessageBox.Yes | qt.QMessageBox.No
                 | qt.QMessageBox.Cancel)
             if question == qt.QMessageBox.Cancel:
                 return
             saveInRemoteRepo = question == qt.QMessageBox.Yes
         else:
             saveInRemoteRepo = False
         self.logic.saveCurrentFiducials(
             d,
             caseNavigatorWidget=self.caseNavigatorWidget,
             callbackFunction=self.uploadFileResult,
             saveInRemoteRepo=saveInRemoteRepo)
         qt.QMessageBox.information(
             slicer.util.mainWindow(), 'Results saved',
             "The results have been saved succesfully")
     except:
         Util.print_last_exception()
         qt.QMessageBox.critical(
             slicer.util.mainWindow(), "Error when saving the results",
             "Error when saving the results. Please review the console for additional info"
         )
예제 #7
0
    def refreshTextboxes(self, reset=False):
        """ Update the information of the textboxes that give information about the measurements
        """
        self.aortaTextBox.setText("0")
        self.paTextBox.setText("0")
        self.ratioTextBox.setText("0")
        self.ratioTextBox.setStyleSheet(
            " QLineEdit { background-color: white; color: black}")

        volumeId = self.volumeSelector.currentNodeID
        # if volumeId not in self.logic.currentVolumesLoaded:
        #     return

        if volumeId:
            self.logic.changeActiveRulersColor(volumeId,
                                               self.logic.defaultColor)
        aorta = None
        pa = None
        if not reset:
            rulerAorta, newAorta = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeID,
                self.logic.AORTA,
                createIfNotExist=False)
            rulerPA, newPA = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeID,
                self.logic.PA,
                createIfNotExist=False)
            if rulerAorta:
                aorta = rulerAorta.GetDistanceMeasurement()
                self.aortaTextBox.setText(str(aorta))
            if rulerPA:
                pa = rulerPA.GetDistanceMeasurement()
                self.paTextBox.setText(str(pa))
            if pa is not None and aorta is not None and aorta != 0:
                try:
                    ratio = pa / aorta
                    self.ratioTextBox.setText(str(ratio))
                    if ratio > 1.0:
                        # Switch colors ("alarm")
                        st = " QLineEdit {{ background-color: rgb({0}, {1}, {2}); color: white }}". \
                                                        format(int(self.logic.defaultWarningColor[0]*255),
                                                                int(self.logic.defaultWarningColor[1]*255),
                                                                int(self.logic.defaultWarningColor[2]*255))
                        self.ratioTextBox.setStyleSheet(st)
                        self.logic.changeActiveRulersColor(
                            volumeId, self.logic.defaultWarningColor)
                except Exception:
                    Util.print_last_exception()
예제 #8
0
    def refreshTextboxes(self, reset=False):
        """ Update the information of the textboxes that give information about the measurements
        """
        self.rvTextBox.setText("0")
        self.lvTextBox.setText("0")
        self.ratioTextBox.setText("0")
        self.ratioTextBox.setStyleSheet(
            " QLineEdit { background-color: white; color: black}")

        volumeId = self.volumeSelector.currentNodeID
        # if volumeId not in self.logic.currentVolumesLoaded:
        #     return

        rv = None
        lv = None
        if not reset:
            rulerRV, newRV = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeID,
                self.logic.RV,
                createIfNotExist=False)
            rulerLV, newLV = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeID,
                self.logic.LV,
                createIfNotExist=False)
            if rulerRV:
                rv = rulerRV.GetDistanceMeasurement()
                self.rvTextBox.setText(str(rv))
            if rulerLV:
                lv = rulerLV.GetDistanceMeasurement()
                self.lvTextBox.setText(str(lv))
            if lv is not None and rv is not None and rv != 0:
                try:
                    ratio = lv / rv
                    self.ratioTextBox.setText(str(ratio))
                    if ratio > 1.0:
                        # Switch colors ("alarm")
                        st = " QLineEdit {{ background-color: rgb({0}, {1}, {2}); color: white }}". \
                                                        format(int(self.logic.defaultWarningColor[0]*255),
                                                                int(self.logic.defaultWarningColor[1]*255),
                                                                int(self.logic.defaultWarningColor[2]*255))
                        self.ratioTextBox.setStyleSheet(st)
                except Exception:
                    Util.print_last_exception()
예제 #9
0
 def saveResultsCurrentNode(self):
     """ Get current active node and save the xml fiducials file
     """
     try:
         d = self.saveResultsDirectoryButton.directory
         if not os.path.isdir(d):
             # Ask the user if he wants to create the folder
             if qt.QMessageBox.question(
                     slicer.util.mainWindow(), "Create directory?",
                     "The directory '{0}' does not exist. Do you want to create it?"
                     .format(d), qt.QMessageBox.Yes
                     | qt.QMessageBox.No) == qt.QMessageBox.Yes:
                 try:
                     os.makedirs(d)
                     # Make sure that everybody has write permissions (sometimes there are problems because of umask)
                     os.chmod(d, 0777)
                 except:
                     qt.QMessageBox.warning(
                         slicer.util.mainWindow(), 'Directory incorrect',
                         'The folder "{0}" could not be created. Please select a valid directory'
                         .format(d))
                     return
                 self.logic.saveCurrentFiducials(d,
                                                 self.caseNavigatorWidget,
                                                 self.uploadFileResult)
                 qt.QMessageBox.information(
                     slicer.util.mainWindow(), 'Results saved',
                     "The results have been saved succesfully")
         else:
             self.logic.saveCurrentFiducials(d, self.caseNavigatorWidget,
                                             self.uploadFileResult)
             qt.QMessageBox.information(
                 slicer.util.mainWindow(), 'Results saved',
                 "The results have been saved succesfully")
     except:
         Util.print_last_exception()
         qt.QMessageBox.critical(
             slicer.util.mainWindow(), "Error when saving the results",
             "Error when saving the results. Please review the console for additional info"
         )
    def saveCurrentFiducials(self, directory):
        """ Save all the fiducials for the current volume.
        The name of the file will be VolumeName_parenchymaTraining.xml"
        :param volume: scalar node
        :param directory: destiny directory
        :return:
        """
        volume = slicer.util.getNode(self.currentVolumeId)
        print("DEBUG: saving the fidcuals for volume " + volume.GetName())
        # Iterate over all the fiducials list nodes
        pos = [0,0,0]
        topology = GTD.GeometryTopologyData()
        topology.coordinate_system = topology.LPS
        # Get the transformation matrix LPS-->IJK
        matrix = Util.get_lps_to_ijk_transformation_matrix(volume)
        topology.lps_to_ijk_transformation_matrix = Util.convert_vtk_matrix_to_list(matrix)

        for fidListNode in slicer.util.getNodes("{0}_fiducials_*".format(volume.GetID())).itervalues():
            # Get all the markups
            for i in range(fidListNode.GetNumberOfMarkups()):
                fidListNode.GetNthFiducialPosition(i, pos)
                # Get the type from the description (region will always be 0)
                desc = fidListNode.GetNthMarkupDescription(i)
                typeId = int(desc.split("_")[0])
                artifactId = int(desc.split("_")[1])
                # Switch coordinates from RAS to LPS
                lps_coords = Util.ras_to_lps(list(pos))
                p = GTD.Point(0, typeId, artifactId, lps_coords)
                topology.add_point(p)

        # Get the xml content file
        xml = topology.to_xml()
        # Save the file
        fileName = os.path.join(directory, "{0}_parenchymaTraining.xml".format(volume.GetName()))
        with open(fileName, 'w') as f:
            f.write(xml)

        # Mark the current volume as saved
        #self.savedVolumes.add(volume.GetID())
        self.savedVolumes[volume.GetID()] = True
예제 #11
0
    def saveStateBeforeEnteringModule(self):
        """Save the state of the module regarding labelmap, etc. This state will be saved/loaded when
        exiting/entering the module
        """
        if self.preventSavingState:
            # Avoid that the first time that the module loads, the state is saved twice
            self.preventSavingState = False
            return

        # Save existing layout
        self.savedLayout = None
        if slicer.app.layoutManager() is not None:
            self.savedLayout = slicer.app.layoutManager().layout

        # Get the active volume (it it exists)
        activeVolumeId = SlicerUtil.getFirstActiveVolumeId()
        if activeVolumeId is None:
            # Reset state
            self.resetModuleState()
        else:
            # There is a Volume loaded. Save state
            try:
                self.savedVolumeID = activeVolumeId
                displayNode = SlicerUtil.getNode(
                    activeVolumeId).GetDisplayNode()
                self.savedContrastLevel = (displayNode.GetWindow(),
                                           displayNode.GetLevel())
                # activeLabelmapId = SlicerUtil.getFirstActiveLabelmapId()
                # self.savedLabelmapID = activeLabelmapId
                # if activeLabelmapId is None:
                #     self.savedLabelmapOpacity = None
                # else:
                #     self.savedLabelmapOpacity = SlicerUtil.getLabelmapOpacity()
                #     # Hide any labelmap
                #     SlicerUtil.displayLabelmapVolume(None)
            except:
                Util.print_last_exception()
                # Not action really needed
                pass
예제 #12
0
    def refreshTextboxes(self, reset=False):
        """ Update the information of the textboxes that give information about the measurements
        """
        self.aortaTextBox.setText("0")
        self.paTextBox.setText("0")
        self.ratioTextBox.setText("0")
        self.ratioTextBox.setStyleSheet(" QLineEdit { background-color: white; color: black}")

        volumeId = self.volumeSelector.currentNodeId
        if volumeId not in self.logic.currentVolumesLoaded:
            return

        if volumeId:
            self.logic.changeColor(volumeId, self.logic.defaultColor)
        aorta = None
        pa = None
        if not reset:
            rulerAorta, newAorta = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeId, self.logic.AORTA, createIfNotExist=False
            )
            rulerPA, newPA = self.logic.getRulerNodeForVolumeAndStructure(
                self.volumeSelector.currentNodeId, self.logic.PA, createIfNotExist=False
            )
            if rulerAorta:
                aorta = rulerAorta.GetDistanceMeasurement()
                self.aortaTextBox.setText(str(aorta))
            if rulerPA:
                pa = rulerPA.GetDistanceMeasurement()
                self.paTextBox.setText(str(pa))
            if aorta is not None and aorta != 0:
                try:
                    ratio = pa / aorta
                    self.ratioTextBox.setText(str(ratio))
                    if ratio > 1:
                        # Switch colors ("alarm")
                        self.ratioTextBox.setStyleSheet(" QLineEdit { background-color: rgb(255, 0, 0); color: white}")
                        self.logic.changeColor(volumeId, self.logic.defaultWarningColor)
                except Exception:
                    Util.print_last_exception()
예제 #13
0
if not path.isdir(results_dir):
    # Create the results folder if it doesn't exist
    os.makedirs(results_dir)
files = os.listdir(files_dir)

types_delete = [97, 98, 99, 100]
types_replace = {
    94: 84,
    96: 85,
    101: 34,
    102: 86,
    103: 88
}

for file_name in files:
    if Util.get_file_extension(file_name) != ".xml":
        continue
    p = path.join(files_dir, file_name)
    print ("Processing {0}...".format(file_name))
    with open(p, "r+b") as f:
        xml = f.read()
        geom = gtd.GeometryTopologyData.from_xml(xml)
        geom.num_dimensions = 3
        points = []
        change_coords = geom.coordinate_system != geom.LPS
        for point in geom.points:
            if point.chest_type not in types_delete:
                if types_replace.has_key(point.chest_type):
                    # Replace type
                    point.chest_type = types_replace[point.chest_type]
                if change_coords:
예제 #14
0
sys.path.append("/Users/jonieva/Projects/SlicerCIP/Scripted/CIP_Common/")
from CIP.logic import geometry_topology_data as gtd
from CIP.logic import Util

import os
import os.path
import re

wrong_cases_path = "/Volumes/Mac500/Dropbox/rola-jorge/LH ROI failure/"
xmls_path = "/Volumes/Mac500/Dropbox/ACIL-Biomarkers/parenchyma training 2015-10-02/"
results_path = "/Volumes/Mac500/Data/tempdata/parenchyma training 2015-10-02/Removed Points/LH ROI failure"
current_case = ""
caseIds = dict()

for file_name in os.listdir(wrong_cases_path):
    if Util.get_file_extension(file_name) != ".png":
        continue
    expr = "(?P<caseid>(^(.*?)_(.*?)_(.*?)_(.*?)_(.*?)))_(.*?)_p(?P<point>(.*?))_(.*)"
    r = re.match(expr, file_name)
    caseId = r.group("caseid")
    point = int(r.group("point"))
    if not caseIds.has_key(caseId):
        caseIds[caseId] = []
    caseIds[caseId].append(point)

for caseId, excludedPoints in caseIds.iteritems():
    # Load the Geometry object
    geom = gtd.GeometryTopologyData.from_xml_file(os.path.join(xmls_path, caseId + "_parenchymaTraining.xml"))
    newPoints=[]
    for i in range(len(geom.points)):
        if i not in excludedPoints:
예제 #15
0
    def saveCurrentFiducials(self,
                             localFilePath,
                             caseNavigatorWidget=None,
                             callbackFunction=None,
                             saveInRemoteRepo=False):
        """ Save all the fiducials for the current volume.
        The name of the file will be VolumeName_parenchymaTraining.xml"
        :param filePath: destination file (local)
        :param caseNavigatorWidget: case navigator widget (optional)
        :param callbackFunction: function to invoke when the file has been uploaded to the server (optional)
        """
        volume = slicer.mrmlScene.GetNodeByID(self.currentVolumeId)
        #fileName = volume.GetName() + Util.file_conventions_extensions[self._xmlFileExtensionKey_]
        # If there is already a xml file in the results directory, make a copy.
        #localFilePath = os.path.join(directory, fileName)
        if os.path.isfile(localFilePath):
            # Make a copy of the file for history purposes
            copyfile(localFilePath,
                     localFilePath + "." + time.strftime("%Y%m%d.%H%M%S"))

        # Iterate over all the fiducials list nodes
        pos = [0, 0, 0]
        geometryTopologyData = gtd.GeometryTopologyData()
        geometryTopologyData.coordinate_system = geometryTopologyData.LPS
        # Get the transformation matrix LPS-->IJK
        matrix = Util.get_lps_to_ijk_transformation_matrix(volume)
        geometryTopologyData.lps_to_ijk_transformation_matrix = Util.convert_vtk_matrix_to_list(
            matrix)
        # Save spacing and origin of the volume
        geometryTopologyData.origin = volume.GetOrigin()
        geometryTopologyData.spacing = volume.GetSpacing()
        geometryTopologyData.dimensions = volume.GetImageData().GetDimensions()

        # Get the hashtable and seed from previously loaded GeometryTopologyData object (if available)
        if self.currentGeometryTopologyData is None:
            hashTable = {}
        else:
            hashTable = self.currentGeometryTopologyData.get_hashtable()
            geometryTopologyData.seed_id = self.currentGeometryTopologyData.seed_id

        # Get a timestamp that will be used for all the points
        timestamp = gtd.GeometryTopologyData.get_timestamp()

        for fidListNode in slicer.util.getNodes("{0}_fiducials_*".format(
                volume.GetName())).itervalues():
            # Get all the markups
            for i in range(fidListNode.GetNumberOfMarkups()):
                fidListNode.GetNthFiducialPosition(i, pos)
                # Get the type from the description (region will always be 0)
                desc = fidListNode.GetNthMarkupDescription(i)
                # Switch coordinates from RAS to LPS
                lps_coords = Util.ras_to_lps(list(pos))
                pointMetadata = self.getPointMetadataFromFiducialDescription(
                    desc)
                p = gtd.Point(pointMetadata[0],
                              pointMetadata[1],
                              pointMetadata[2],
                              lps_coords,
                              description=pointMetadata[3])
                key = p.get_hash()
                if hashTable.has_key(key):
                    # Add previously existing point
                    geometryTopologyData.add_point(hashTable[key],
                                                   fill_auto_fields=False)
                else:
                    # Add a new point with a precalculated timestamp
                    geometryTopologyData.add_point(p, fill_auto_fields=True)
                    p.timestamp = timestamp

        # Get the xml content file
        xml = geometryTopologyData.to_xml()
        # Save the file
        with open(localFilePath, 'w') as f:
            f.write(xml)

        # Use the new object as the current GeometryTopologyData
        self.currentGeometryTopologyData = geometryTopologyData

        # Upload to MAD if we are using the ACIL case navigator
        if saveInRemoteRepo:
            caseNavigatorWidget.uploadFile(localFilePath,
                                           callbackFunction=callbackFunction)

        # Mark the current volume as saved
        self.savedVolumes[volume.GetName()] = True
예제 #16
0
sys.path.append("/Users/jonieva/Projects/SlicerCIP/Scripted/CIP_Common/")
from CIP.logic import geometry_topology_data as gtd
from CIP.logic import Util

import os
import os.path
import re

wrong_cases_path = "/Volumes/Mac500/Dropbox/rola-jorge/LH ROI failure/"
xmls_path = "/Volumes/Mac500/Dropbox/ACIL-Biomarkers/parenchyma training 2015-10-02/"
results_path = "/Volumes/Mac500/Data/tempdata/parenchyma training 2015-10-02/Removed Points/LH ROI failure"
current_case = ""
caseIds = dict()

for file_name in os.listdir(wrong_cases_path):
    if Util.get_file_extension(file_name) != ".png":
        continue
    expr = "(?P<caseid>(^(.*?)_(.*?)_(.*?)_(.*?)_(.*?)))_(.*?)_p(?P<point>(.*?))_(.*)"
    r = re.match(expr, file_name)
    caseId = r.group("caseid")
    point = int(r.group("point"))
    if not caseIds.has_key(caseId):
        caseIds[caseId] = []
    caseIds[caseId].append(point)

for caseId, excludedPoints in caseIds.iteritems():
    # Load the Geometry object
    geom = gtd.GeometryTopologyData.from_xml_file(
        os.path.join(xmls_path, caseId + "_parenchymaTraining.xml"))
    newPoints = []
    for i in range(len(geom.points)):
예제 #17
0
if not path.isdir(results_dir):
    # Create the results folder if it doesn't exist
    os.makedirs(results_dir)
files = os.listdir(files_dir)

types_delete = [97, 98, 99, 100]
types_replace = {
    94: 84,
    96: 85,
    101: 34,
    102: 86,
    103: 88
}

for file_name in files:
    if Util.get_file_extension(file_name) != ".xml":
        continue
    p = path.join(files_dir, file_name)
    print ("Processing {0}...".format(file_name))
    with open(p, "r+b") as f:
        xml = f.read()
        geom = gtd.GeometryTopologyData.from_xml(xml)
        geom.num_dimensions = 3
        points = []
        change_coords = geom.coordinate_system != geom.LPS
        for point[ in geom.points:
            if point.chest_type not in types_delete:
                if types_replace.has_key(point.chest_type):
                    # Replace type
                    point.chest_type = types_replace[point.chest_type]
                if change_coords:
예제 #18
0
    def saveCurrentFiducials(self,
                             directory,
                             caseNavigatorWidget=None,
                             callbackFunction=None):
        """ Save all the fiducials for the current volume.
        The name of the file will be VolumeName_parenchymaTraining.xml"
        :param volume: scalar node
        :param directory: destination directory
        """
        volume = slicer.mrmlScene.GetNodeByID(self.currentVolumeId)
        fileName = volume.GetName(
        ) + Util.file_conventions_extensions["ParenchymaTrainingFiducialsXml"]
        # If there is already a xml file in the results directory, make a copy.
        fiducialsLocalFilePath = os.path.join(directory, fileName)
        if os.path.isfile(fiducialsLocalFilePath):
            # Make a copy of the file for history purposes
            copyfile(
                fiducialsLocalFilePath,
                fiducialsLocalFilePath + "." + time.strftime("%Y%m%d.%H%M%S"))

        # Iterate over all the fiducials list nodes
        pos = [0, 0, 0]
        geometryTopologyData = GTD.GeometryTopologyData()
        geometryTopologyData.coordinate_system = geometryTopologyData.LPS
        # Get the transformation matrix LPS-->IJK
        matrix = Util.get_lps_to_ijk_transformation_matrix(volume)
        geometryTopologyData.lps_to_ijk_transformation_matrix = Util.convert_vtk_matrix_to_list(
            matrix)
        # Get the hashtable and seed from previously loaded GeometryTopologyData object (if available)
        if self.currentGeometryTopologyData is None:
            hashTable = {}
        else:
            hashTable = self.currentGeometryTopologyData.get_hashtable()
            geometryTopologyData.id_seed = self.currentGeometryTopologyData.id_seed

        # Get a timestamp that will be used for all the points
        timestamp = GTD.GeometryTopologyData.get_timestamp()

        for fidListNode in slicer.util.getNodes("{0}_fiducials_*".format(
                volume.GetName())).itervalues():
            # Get all the markups
            for i in range(fidListNode.GetNumberOfMarkups()):
                fidListNode.GetNthFiducialPosition(i, pos)
                # Get the type from the description (region will always be 0)
                desc = fidListNode.GetNthMarkupDescription(i)
                typeId = int(desc.split("_")[0])
                artifactId = int(desc.split("_")[1])
                # Switch coordinates from RAS to LPS
                lps_coords = Util.ras_to_lps(list(pos))
                p = GTD.Point(0, typeId, artifactId, lps_coords)
                key = p.get_hash()
                if hashTable.has_key(key):
                    # Add previously existing point
                    geometryTopologyData.add_point(hashTable[key],
                                                   fill_auto_fields=False)
                else:
                    # Add a new point with a precalculated timestamp
                    geometryTopologyData.add_point(p, fill_auto_fields=True)
                    p.timestamp = timestamp

        # Get the xml content file
        xml = geometryTopologyData.to_xml()
        # Save the file
        with open(fiducialsLocalFilePath, 'w') as f:
            f.write(xml)

        # Use the new object as the current GeometryTopologyData
        self.currentGeometryTopologyData = geometryTopologyData

        # Upload to MAD if we are using the ACIL case navigator
        if caseNavigatorWidget is not None:
            caseNavigatorWidget.uploadFile(fiducialsLocalFilePath,
                                           callbackFunction=callbackFunction)

        # Mark the current volume as saved
        self.savedVolumes[volume.GetName()] = True