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
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