def export(self,exportables): for exportable in exportables: # Get node to export node = slicer.mrmlScene.GetNodeByID(exportable.nodeID) if node.GetAssociatedNode() == None or not node.GetAssociatedNode().IsA('vtkMRMLScalarVolumeNode'): error = "Series '" + node.GetNameWithoutPostfix() + "' cannot be exported!" print(error) return error # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryDir = qt.QDir(exportable.directory) directoryDir.mkdir(exportable.nodeID) directoryDir.cd(exportable.nodeID) directory = directoryDir.absolutePath() print("Export scalar volume '" + node.GetAssociatedNode().GetName() + "' to directory " + directory) # Get study and patient nodes studyNode = node.GetParentNode() if studyNode == None: error = "Unable to get study node for series '" + node.GetAssociatedNode().GetName() + "'" print(error) return error patientNode = studyNode.GetParentNode() if patientNode == None: error = "Unable to get patient node for series '" + node.GetAssociatedNode().GetName() + "'" print(error) return error # Assemble tags dictionary for volume export from vtkSlicerSubjectHierarchyModuleMRMLPython import vtkMRMLSubjectHierarchyConstants tags = {} tags['Patient Name'] = exportable.tag(vtkMRMLSubjectHierarchyConstants.GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag(vtkMRMLSubjectHierarchyConstants.GetDICOMPatientIDTagName()) tags['Patient Comments'] = exportable.tag(vtkMRMLSubjectHierarchyConstants.GetDICOMPatientCommentsTagName()) tags['Study ID'] = self.defaultStudyID tags['Study Date'] = exportable.tag(vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDateTagName()) tags['Study Description'] = exportable.tag(vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + node.GetAssociatedNode().GetName() + "'" print(error) return error #TODO: more tag checks # Perform export exporter = DICOMExportScalarVolume(tags['Study ID'], node.GetAssociatedNode(), tags, directory) exporter.export() # Success return ""
def export(self,exportables): for exportable in exportables: # Get node to export node = slicer.mrmlScene.GetNodeByID(exportable.nodeID) if node.GetAssociatedNode() is None or not node.GetAssociatedNode().IsA('vtkMRMLScalarVolumeNode'): error = "Series '" + node.GetNameWithoutPostfix() + "' cannot be exported!" logging.error(error) return error # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryDir = qt.QDir(exportable.directory) directoryDir.mkdir(exportable.nodeID) directoryDir.cd(exportable.nodeID) directory = directoryDir.absolutePath() logging.info("Export scalar volume '" + node.GetAssociatedNode().GetName() + "' to directory " + directory) # Get study and patient nodes studyNode = node.GetParentNode() if studyNode is None: error = "Unable to get study node for series '" + node.GetAssociatedNode().GetName() + "'" logging.error(error) return error patientNode = studyNode.GetParentNode() if patientNode is None: error = "Unable to get patient node for series '" + node.GetAssociatedNode().GetName() + "'" logging.error(error) return error # Assemble tags dictionary for volume export tags = {} tags['Patient Name'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientIDTagName()) tags['Patient Comments'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientCommentsTagName()) tags['Study ID'] = self.defaultStudyID tags['Study Date'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDateTagName()) tags['Study Description'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + node.GetAssociatedNode().GetName() + "'" logging.error(error) return error #TODO: more tag checks # Perform export exporter = DICOMExportScalarVolume(tags['Study ID'], node.GetAssociatedNode(), tags, directory) exporter.export() # Success return ""
def export(self, exportables): for exportable in exportables: # Get volume node to export shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) if shNode is None: error = "Invalid subject hierarchy" logging.error(error) return error volumeNode = shNode.GetItemDataNode( exportable.subjectHierarchyItemID) if volumeNode is None or not volumeNode.IsA( 'vtkMRMLScalarVolumeNode'): error = "Series '" + shNode.GetItemName( exportable.subjectHierarchyItemID ) + "' cannot be exported as volume sequence" logging.error(error) return error sequenceBrowserNode = self.getSequenceBrowserNodeForMasterOutputNode( volumeNode) if not sequenceBrowserNode: error = "Series '" + shNode.GetItemName( exportable.subjectHierarchyItemID ) + "' cannot be exported as volume sequence" logging.error(error) return error volumeSequenceNode = sequenceBrowserNode.GetSequenceNode( volumeNode) if not volumeSequenceNode: error = "Series '" + shNode.GetItemName( exportable.subjectHierarchyItemID ) + "' cannot be exported as volume sequence" logging.error(error) return error # Get study and patient items studyItemID = shNode.GetItemParent( exportable.subjectHierarchyItemID) if not studyItemID: error = "Unable to get study for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error patientItemID = shNode.GetItemParent(studyItemID) if not patientItemID: error = "Unable to get patient for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error # Assemble tags dictionary for volume export tags = {} tags['Patient Name'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientIDTagName()) tags['Patient Comments'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientCommentsTagName()) if slicer.app.majorVersion >= 5 or (slicer.app.majorVersion == 4 and slicer.app.minorVersion >= 11): tags['Study Instance UID'] = pydicom.uid.generate_uid() else: tags['Study Instance UID'] = dicom.UID.generate_uid() tags['Study ID'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyIDTagName( )) tags['Study Date'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDateTagName()) tags['Study Time'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyTimeTagName()) tags['Study Description'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') tags['Series Date'] = exportable.tag("SeriesDate") tags['Series Time'] = exportable.tag("SeriesTime") if slicer.app.majorVersion >= 5 or (slicer.app.majorVersion == 4 and slicer.app.minorVersion >= 11): tags['Series Instance UID'] = pydicom.uid.generate_uid() tags[ 'Frame of Reference Instance UID'] = pydicom.uid.generate_uid( ) else: tags['Series Instance UID'] = dicom.UID.generate_uid() tags[ 'Frame of Reference Instance UID'] = dicom.UID.generate_uid( ) # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error #TODO: more tag checks sequenceItemCount = sequenceBrowserNode.GetMasterSequenceNode( ).GetNumberOfDataNodes() originalSelectedSequenceItemNumber = sequenceBrowserNode.GetSelectedItemNumber( ) masterVolumeNode = sequenceBrowserNode.GetMasterSequenceNode() # initialize content datetime from series datetime contentStartDate = exportable.tag("SeriesDate") contentStartTime = exportable.tag("SeriesTime") import datetime datetimeNow = datetime.datetime.now() if not contentStartDate: contentStartDate = datetimeNow.strftime("%Y%m%d") if not contentStartTime: contentStartTime = datetimeNow.strftime("%H%M%S.%f") contentStartDatetime = self.datetimeFromDicom( contentStartDate, contentStartTime) # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryName = 'VolumeSequence_' + str( exportable.subjectHierarchyItemID) directoryDir = qt.QDir(exportable.directory) directoryDir.mkdir(directoryName) directoryDir.cd(directoryName) directory = directoryDir.absolutePath() logging.info("Export scalar volume '" + volumeNode.GetName() + "' to directory " + directory) for sequenceItemIndex in range(sequenceItemCount): # Switch to next item in the series sequenceBrowserNode.SetSelectedItemNumber(sequenceItemIndex) slicer.app.processEvents() # Compute content date&time # TODO: verify that unit in sequence node is "second" (and convert to seconds if not) timeOffsetSec = float( masterVolumeNode.GetNthIndexValue(sequenceItemIndex) ) - float(masterVolumeNode.GetNthIndexValue(0)) contentDatetime = contentStartDatetime + datetime.timedelta( seconds=timeOffsetSec) tags['Content Date'] = contentDatetime.strftime("%Y%m%d") tags['Content Time'] = contentDatetime.strftime("%H%M%S.%f") # Perform export filenamePrefix = f"IMG_{sequenceItemIndex:04d}_" exporter = DICOMExportScalarVolume(tags['Study ID'], volumeNode, tags, directory, filenamePrefix) exporter.export() # Success return ""
def export(self, exportables): for exportable in exportables: # Get volume node to export shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) if shNode is None: error = "Invalid subject hierarchy" logging.error(error) return error volumeNode = shNode.GetItemDataNode( exportable.subjectHierarchyItemID) if volumeNode is None or not volumeNode.IsA( 'vtkMRMLScalarVolumeNode'): error = "Series '" + shNode.GetItemName( exportable.subjectHierarchyItemID) + "' cannot be exported" logging.error(error) return error # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryName = 'ScalarVolume_' + str( exportable.subjectHierarchyItemID) directoryDir = qt.QDir(exportable.directory) directoryDir.mkdir(directoryName) directoryDir.cd(directoryName) directory = directoryDir.absolutePath() logging.info("Export scalar volume '" + volumeNode.GetName() + "' to directory " + directory) # Get study and patient items studyItemID = shNode.GetItemParent( exportable.subjectHierarchyItemID) if not studyItemID: error = "Unable to get study for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error patientItemID = shNode.GetItemParent(studyItemID) if not patientItemID: error = "Unable to get patient for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error # Assemble tags dictionary for volume export tags = {} tags['Patient Name'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientIDTagName()) tags['Patient Comments'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientCommentsTagName()) tags['Study ID'] = self.defaultStudyID tags['Study Date'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDateTagName()) tags['Study Time'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyTimeTagName()) tags['Study Description'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') tags['Series Date'] = exportable.tag('SeriesDate') tags['Series Time'] = exportable.tag('SeriesTime') tags['Content Date'] = exportable.tag('ContentDate') tags['Content Time'] = exportable.tag('ContentTime') tags['Study Instance UID'] = exportable.tag('StudyInstanceUID') tags['Series Instance UID'] = exportable.tag('SeriesInstanceUID') tags['Frame of Reference Instance UID'] = exportable.tag( 'FrameOfReferenceInstanceUID') # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error #TODO: more tag checks # Perform export exporter = DICOMExportScalarVolume(tags['Study ID'], volumeNode, tags, directory) exporter.export() # Success return ""
def export(self,exportables): for exportable in exportables: # Get volume node to export shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene) if shNode is None: error = "Invalid subject hierarchy" logging.error(error) return error volumeNode = shNode.GetItemDataNode(exportable.subjectHierarchyItemID) if volumeNode is None or not volumeNode.IsA('vtkMRMLScalarVolumeNode'): error = "Series '" + shNode.GetItemName(exportable.subjectHierarchyItemID) + "' cannot be exported" logging.error(error) return error # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryName = 'ScalarVolume_' + str(exportable.subjectHierarchyItemID) directoryDir = qt.QDir(exportable.directory) directoryDir.mkdir(directoryName) directoryDir.cd(directoryName) directory = directoryDir.absolutePath() logging.info("Export scalar volume '" + volumeNode.GetName() + "' to directory " + directory) # Get study and patient items studyItemID = shNode.GetItemParent(exportable.subjectHierarchyItemID) if not studyItemID: error = "Unable to get study for series '" + volumeNode.GetName() + "'" logging.error(error) return error patientItemID = shNode.GetItemParent(studyItemID) if not patientItemID: error = "Unable to get patient for series '" + volumeNode.GetName() + "'" logging.error(error) return error # Assemble tags dictionary for volume export tags = {} tags['Patient Name'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientIDTagName()) tags['Patient Comments'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMPatientCommentsTagName()) tags['Study ID'] = self.defaultStudyID tags['Study Date'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDateTagName()) tags['Study Time'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyTimeTagName()) tags['Study Description'] = exportable.tag(slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') tags['Series Date'] = exportable.tag('SeriesDate') tags['Series Time'] = exportable.tag('SeriesTime') tags['Content Date'] = exportable.tag('ContentDate') tags['Content Time'] = exportable.tag('ContentTime') tags['Study Instance UID'] = exportable.tag('StudyInstanceUID') tags['Series Instance UID'] = exportable.tag('SeriesInstanceUID') tags['Frame of Reference Instance UID'] = exportable.tag('FrameOfReferenceInstanceUID') # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + volumeNode.GetName() + "'" logging.error(error) return error #TODO: more tag checks # Perform export exporter = DICOMExportScalarVolume(tags['Study ID'], volumeNode, tags, directory) exporter.export() # Success return ""
def export(self, exportables): for exportable in exportables: # Get volume node to export shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode( slicer.mrmlScene) if shNode is None: error = "Invalid subject hierarchy" logging.error(error) return error volumeNode = shNode.GetItemDataNode( exportable.subjectHierarchyItemID) if volumeNode is None or not volumeNode.IsA( 'vtkMRMLScalarVolumeNode'): error = "Series '" + shNode.GetItemName( exportable.subjectHierarchyItemID) + "' cannot be exported" logging.error(error) return error # Get output directory and create a subdirectory. This is necessary # to avoid overwriting the files in case of multiple exportables, as # naming of the DICOM files is static directoryName = 'ScalarVolume_' + str( exportable.subjectHierarchyItemID) directoryDir = qt.QDir(exportable.directory) directoryDir.mkpath(directoryName) directoryDir.cd(directoryName) directory = directoryDir.absolutePath() logging.info("Export scalar volume '" + volumeNode.GetName() + "' to directory " + directory) # Get study and patient items studyItemID = shNode.GetItemParent( exportable.subjectHierarchyItemID) if not studyItemID: error = "Unable to get study for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error patientItemID = shNode.GetItemParent(studyItemID) if not patientItemID: error = "Unable to get patient for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error # Assemble tags dictionary for volume export tags = {} tags['Patient Name'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientNameTagName()) tags['Patient ID'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientIDTagName()) tags['Patient Birth Date'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientBirthDateTagName()) tags['Patient Sex'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientSexTagName()) tags['Patient Comments'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMPatientCommentsTagName()) tags['Study ID'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants.GetDICOMStudyIDTagName( )) tags['Study Date'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDateTagName()) tags['Study Time'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyTimeTagName()) tags['Study Description'] = exportable.tag( slicer.vtkMRMLSubjectHierarchyConstants. GetDICOMStudyDescriptionTagName()) tags['Modality'] = exportable.tag('Modality') tags['Manufacturer'] = exportable.tag('Manufacturer') tags['Model'] = exportable.tag('Model') tags['Series Description'] = exportable.tag('SeriesDescription') tags['Series Number'] = exportable.tag('SeriesNumber') tags['Series Date'] = exportable.tag('SeriesDate') tags['Series Time'] = exportable.tag('SeriesTime') tags['Content Date'] = exportable.tag('ContentDate') tags['Content Time'] = exportable.tag('ContentTime') tags['Study Instance UID'] = exportable.tag('StudyInstanceUID') tags['Series Instance UID'] = exportable.tag('SeriesInstanceUID') tags['Frame of Reference UID'] = exportable.tag( 'FrameOfReferenceUID') # Generate any missing but required UIDs if not tags['Study Instance UID']: import pydicom as dicom tags['Study Instance UID'] = dicom.uid.generate_uid() if not tags['Series Instance UID']: import pydicom as dicom tags['Series Instance UID'] = dicom.uid.generate_uid() if not tags['Frame of Reference UID']: import pydicom as dicom tags['Frame of Reference UID'] = dicom.uid.generate_uid() # Use the default Study ID if none is specified if not tags['Study ID']: tags['Study ID'] = self.defaultStudyID # Validate tags if tags['Modality'] == "": error = "Empty modality for series '" + volumeNode.GetName( ) + "'" logging.error(error) return error seriesInstanceUID = tags['Series Instance UID'] if seriesInstanceUID: # Make sure we don't use a series instance UID that already exists (it would mix in more slices into an existing series, # which is very unlikely that users would want). db = slicer.dicomDatabase studyInstanceUID = db.studyForSeries(seriesInstanceUID) if studyInstanceUID: # This seriesInstanceUID is already found in the database if len(seriesInstanceUID) > 25: seriesInstanceUID = seriesInstanceUID[:20] + "..." error = f"A series already exists in the database by SeriesInstanceUID {seriesInstanceUID}." logging.error(error) return error # TODO: more tag checks # Perform export exporter = DICOMExportScalarVolume(tags['Study ID'], volumeNode, tags, directory) if not exporter.export(): return "Creating DICOM files from scalar volume failed. See the application log for details." # Success return ""