def __init__( self, filename_or_obj, dataset, preamble=None, file_meta=None, is_implicit_VR=True, is_little_endian=True ): """Initialize a DICOMDIR dataset read from a DICOM file Carries forward all the initialization from FileDataset class :param filename: full path and filename to the file. Use None if is a BytesIO. :param dataset: some form of dictionary, usually a Dataset from read_dataset() :param preamble: the 128-byte DICOM preamble :param file_meta: the file meta info dataset, as returned by _read_file_meta, or an empty dataset if no file meta information is in the file :param is_implicit_VR: True if implicit VR transfer syntax used; False if explicit VR. Default is True. :param is_little_endian: True if little-endian transfer syntax used; False if big-endian. Default is True. """ # Usually this class is created through filereader.read_partial, # and it checks class SOP, but in case of direct creation, # check here also if file_meta: class_uid = file_meta.MediaStorageSOPClassUID if not class_uid == "Media Storage Directory Storage": msg = "SOP Class is not Media Storage Directory (DICOMDIR)" raise InvalidDicomError(msg) FileDataset.__init__( self, filename_or_obj, dataset, preamble, file_meta, is_implicit_VR=True, is_little_endian=True ) self.parse_records()
def __init__(self, filename_or_obj, dataset, preamble=None, file_meta=None, is_implicit_VR=True, is_little_endian=True): """Initialize a DICOMDIR dataset read from a DICOM file Carries forward all the initialization from FileDataset class :param filename: full path and filename to the file. Use None if is a BytesIO. :param dataset: some form of dictionary, usually a Dataset from read_dataset() :param preamble: the 128-byte DICOM preamble :param file_meta: the file meta info dataset, as returned by _read_file_meta, or an empty dataset if no file meta information is in the file :param is_implicit_VR: True if implicit VR transfer syntax used; False if explicit VR. Default is True. :param is_little_endian: True if little-endian transfer syntax used; False if big-endian. Default is True. """ # Usually this class is created through filereader.read_partial, # and it checks class SOP, but in case of direct creation, # check here also if file_meta: class_uid = file_meta.MediaStorageSOPClassUID if not class_uid == "Media Storage Directory Storage": msg = "SOP Class is not Media Storage Directory (DICOMDIR)" raise InvalidDicomError(msg) FileDataset.__init__(self, filename_or_obj, dataset, preamble, file_meta, is_implicit_VR=True, is_little_endian=True) self.parse_records()
def test_parse_dicom_file(self): # create a temporary dicom file temp_dir = tempfile.gettempdir() # get temp directory temp_file = os.path.join(temp_dir, 'dicom.dcm') # Reference https://stackoverflow.com/questions/14350675/create-pydicom-file-from-numpy-array pixel_array = np.diag([1, 2, 3 ]).astype(np.uint16) # create a diagonal matrix file_meta = Dataset() ds = FileDataset(temp_file, {}, file_meta=file_meta, preamble=b'\x00' * 128) file_meta.TransferSyntaxUID = uid.ImplicitVRLittleEndian ds.BitsAllocated = 16 ds.SamplesPerPixel = 1 ds.Columns = pixel_array.shape[0] ds.Rows = pixel_array.shape[1] ds.PixelRepresentation = 0 ds.PixelData = pixel_array.tostring() ds.save_as(temp_file) # parse file im_data = parsing.parse_dicom_file(temp_file) os.remove(temp_file) np.testing.assert_equal(im_data, {parsing.PIXEL_FIELD: pixel_array})
def FileSave(data, file_path): """Save a DICOM file using given file path from an array Using: PyDICOM""" file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.1.3.10' file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" ds = FileDataset(file_path, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.PixelData = data.tobytes() ds.save_as(file_path)
def generate_dicom_from_pdf(pdf_file): suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name file_meta = Dataset() # Will get this information from DCM4CHEE file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.104.1' file_meta.MediaStorageSOPInstanceUID = '2.16.840.1.114430.287196081618142314176776725491661159509.60.1' file_meta.ImplementationClassUID = '1.3.46.670589.50.1.8.0' ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.is_little_endian = True ds.is_implicit_VR = True dt = datetime.datetime.now() ds.ContentDate = dt.strftime('%Y%m%d') timeStr = dt.strftime('%H%M%S.%f') ds.ContentTime = timeStr # Will get this information from DCM4CHEE ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.104.1' with open(pdf_file, 'rb') as f: ds.EncapsulatedDocument = f.read() ds.MIMETypeOfEncapsulatedDocument = 'application/pdf' return ds
def add_study_and_series_information(ds: FileDataset, series_data): reference_ds = series_data[0] # All elements in series should have the same data ds.StudyDate = reference_ds.StudyDate ds.SeriesDate = getattr(reference_ds, "SeriesDate", "") ds.StudyTime = reference_ds.StudyTime ds.SeriesTime = getattr(reference_ds, "SeriesTime", "") ds.StudyDescription = getattr(reference_ds, "StudyDescription", "") ds.SeriesDescription = getattr(reference_ds, "SeriesDescription", "") ds.StudyInstanceUID = reference_ds.StudyInstanceUID ds.SeriesInstanceUID = generate_uid() # TODO: find out if random generation is ok ds.StudyID = reference_ds.StudyID ds.SeriesNumber = "1" # TODO: find out if we can just use 1 (Should be fine since its a new series)
def test_correct_ambiguous_vr_compressed(self): """Test correcting compressed Pixel Data read from file""" # Create an implicit VR compressed dataset ds = dcmread(jpeg_lossless_name) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.is_implicit_VR = True file_ds.is_little_endian = True file_ds.save_as(fp, write_like_original=True) ds = dcmread(fp, force=True) self.assertEqual(ds[0x7fe00010].VR, 'OB')
def create_base_ds(self, output_name): file_meta = Dataset() file_meta.MediaStorageSOPClassUID = \ MultiframeTrueColorSecondaryCaptureImageStorage file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid() file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian ds = FileDataset(output_name, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.is_little_endian = True ds.is_implicit_VR = False return ds
def __init__(self, filename_or_obj, dataset, preamble=None, file_meta=None, is_implicit_VR=True, is_little_endian=True): """Initialize a DICOMDIR dataset read from a DICOM file. Carries forward all the initialization from :class:`~pydicom.dataset.FileDataset` Parameters ---------- filename_or_obj : str or None Full path and filename to the file of ``None`` if :class:`io.BytesIO`. dataset : dataset.Dataset Some form of dictionary, usually a :class:`~pydicom.dataset.FileDataset` from :func:`~pydicom.filereader.dcmread`. preamble : bytes The 128-byte DICOM preamble. file_meta : dataset.Dataset The file meta :class:`~pydicom.dataset.Dataset`, such as the one returned by :func:`~pydicom.filereader.read_file_meta_info`, or an empty :class:`~pydicom.dataset.Dataset` if no file meta information is in the file. is_implicit_VR : bool ``True`` if implicit VR transfer syntax used (default); ``False`` if explicit VR. is_little_endian : bool ``True`` if little endian transfer syntax used (default); ``False`` if big endian. """ # Usually this class is created through filereader.read_partial, # and it checks class SOP, but in case of direct creation, # check here also if file_meta: class_uid = file_meta.MediaStorageSOPClassUID if not class_uid.name == "Media Storage Directory Storage": msg = "SOP Class is not Media Storage Directory (DICOMDIR)" raise InvalidDicomError(msg) FileDataset.__init__(self, filename_or_obj, dataset, preamble, file_meta, is_implicit_VR=is_implicit_VR, is_little_endian=is_little_endian) self.parse_records()
def test_long_specific_char_set(self): """Test that specific character set is read even if it is longer than defer_size""" ds = Dataset() long_specific_char_set_value = ['ISO 2022IR 100'] * 9 ds.add(DataElement(0x00080005, 'CS', long_specific_char_set_value)) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.save_as(fp) ds = read_file(fp, defer_size=65, force=True) self.assertEqual(ds[0x00080005].value, long_specific_char_set_value)
def add_circles(dicom, circles, save_file): print(dicom) file_meta = Dataset() file_meta.MediaStorageSOPClassUID = "1.2.840.10008.5.1.4.1.1.11.1" # Grayscale Softcopy Presentation State Storage SOP Class file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid() file_meta.ImplementationClassUID = "1.2.276.0.7230010.3.0.3.4.1" file_meta.ImplementationVersionName = "GSPS_DEMO" ds_out = FileDataset("sample_annotation", {}, file_meta=file_meta, preamble=b"\0" * 128) ds_out.PixelData = dicom.PixelData ds_out.save_as(save_file)
def on_c_store(dataset): """ Function replacing ApplicationEntity.on_store(). Called when a dataset is received following a C-STORE. Write the received dataset to file Parameters ---------- dataset - pydicom.Dataset The DICOM dataset sent via the C-STORE Returns ------- status : pynetdicom.sop_class.Status or int A valid return status code, see PS3.4 Annex B.2.3 or the StorageServiceClass implementation for the available statuses """ mode_prefix = 'UN' mode_prefixes = { 'CT Image Storage': 'CT', 'Enhanced CT Image Storage': 'CTE', 'MR Image Storage': 'MR', 'Enhanced MR Image Storage': 'MRE', 'Positron Emission Tomography Image Storage': 'PT', 'Enhanced PET Image Storage': 'PTE', 'RT Image Storage': 'RI', 'RT Dose Storage': 'RD', 'RT Plan Storage': 'RP', 'RT Structure Set Storage': 'RS', 'Computed Radiography Image Storage': 'CR', 'Ultrasound Image Storage': 'US', 'Enhanced Ultrasound Image Storage': 'USE', 'X-Ray Angiographic Image Storage': 'XA', 'Enhanced XA Image Storage': 'XAE', 'Nuclear Medicine Image Storage': 'NM', 'Secondary Capture Image Storage': 'SC' } try: mode_prefix = mode_prefixes[dataset.SOPClassUID.__str__()] except: pass filename = '{0!s}.{1!s}'.format(mode_prefix, dataset.SOPInstanceUID) logger.info('Storing DICOM file: {0!s}'.format(filename)) if os.path.exists(filename): logger.warning('DICOM file already exists, overwriting') meta = Dataset() meta.MediaStorageSOPClassUID = dataset.SOPClassUID meta.MediaStorageSOPInstanceUID = dataset.SOPInstanceUID meta.ImplementationClassUID = pynetdicom_uid_prefix ds = FileDataset(filename, {}, file_meta=meta, preamble=b"\0" * 128) ds.update(dataset) ds.is_little_endian = True ds.is_implicit_VR = True ds.save_as(filename) return 0x0000 # Success
def test_long_specific_char_set(self): """Test that specific character set is read even if it is longer than defer_size""" ds = Dataset() long_specific_char_set_value = ['ISO 2022IR 100'] * 9 ds.add(DataElement(0x00080005, 'CS', long_specific_char_set_value)) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.save_as(fp, write_like_original=True) ds = dcmread(fp, defer_size=65, force=True) self.assertEqual(ds[0x00080005].value, long_specific_char_set_value)
def on_c_store(self,sop_class,dataset): '''Function replacing ApplicationEntity.on_store(). Called when a dataset is received following a C-STORE. Write the received dataset to file :param sop_class: pydicom.sop_class.StorageServiceClass :param dataset: pydicom.Dataset sent via the C-STORE :returns status: a valid return status, see StorageServiceClass for available ''' filename = 'CT.{0!s}'.format(dataset.SOPInstanceUID) bot.info('Storing DICOM file: {0!s}'.format(filename)) if os.path.exists(filename): bot.warning('DICOM file already exists, overwriting') #logger.debug("pydicom::Dataset()") meta = Dataset() meta.MediaStorageSOPClassUID = dataset.SOPClassUID meta.MediaStorageSOPInstanceUID = '1.2.3' meta.ImplementationClassUID = '1.2.3.4' #logger.debug("pydicom::FileDataset()") ds = FileDataset(filename, {}, file_meta=meta, preamble=b"\0" * 128) ds.update(dataset) ds.is_little_endian = True ds.is_implicit_VR = True #logger.debug("pydicom::save_as()") ds.save_as(filename) return sop_class.Success
def test_long_specific_char_set(self): """Test that specific character set is read even if it is longer than defer_size""" ds = Dataset() long_specific_char_set_value = ['ISO 2022IR 100'] * 9 ds.add(DataElement(0x00080005, 'CS', long_specific_char_set_value)) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.save_as(fp, write_like_original=True) ds = dcmread(fp, defer_size=65, force=True) assert long_specific_char_set_value == ds[0x00080005].value
def generate_base_dataset() -> FileDataset: file_name = 'rt-utils-struct' file_meta = get_file_meta() ds = FileDataset(file_name, {}, file_meta=file_meta, preamble=b"\0" * 128) add_required_elements_to_ds(ds) add_sequence_lists_to_ds(ds) return ds
def test_correct_ambiguous_explicit_vr(self): """Test correcting ambiguous VR elements read from file""" ds = Dataset() ds.PixelRepresentation = 0 ds.add(DataElement(0x00280108, 'US', 10)) ds.add(DataElement(0x00280109, 'US', 500)) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.is_implicit_VR = False file_ds.is_little_endian = True file_ds.save_as(fp, write_like_original=True) ds = dcmread(fp, force=True) self.assertEqual(ds[0x00280108].VR, 'US') self.assertEqual(ds.SmallestPixelValueInSeries, 10)
def update_in_memory( dicom_object: FileDataset, data_element: str, element_value: str ): """ Update a particular data_element to the desired value, then write back to the SOURCE FILE! :param dicom_object: :param data_element: :param element_value: :param out_path :return: bool on operation success, and string on reason. """ """BE AWARE that if the key does not exist, it will not be created currently!""" try: dicom_object.data_element(data_element).value = element_value except KeyError: logger.error(f"Key {data_element } does not exist, creating the key.") return ( False, "DICOM key field does not exist. Not sure how to database one yet. ", ) except: return False, "Generic error encountered while anonymizing file!" return True, dicom_object
def test_write_explicit_vr_big_endian(self): """Test writing explicit big data for ambiguous elements.""" # Create a dataset containing element with ambiguous VRs ref_ds = Dataset() ref_ds.PixelRepresentation = 1 ref_ds.SmallestValidPixelValue = b'\x00\x01' # Big endian 1 fp = BytesIO() file_ds = FileDataset(fp, ref_ds) file_ds.is_implicit_VR = False file_ds.is_little_endian = False file_ds.save_as(fp) fp.seek(0) ds = read_dataset(fp, False, False) self.assertEqual(ds.SmallestValidPixelValue, 1) self.assertEqual(ds[0x00280104].VR, 'SS')
def add_refd_frame_of_ref_sequence(ds: FileDataset, series_data): refd_frame_of_ref = Dataset() refd_frame_of_ref.FrameOfReferenceUID = generate_uid() # TODO Find out if random generation is ok refd_frame_of_ref.RTReferencedStudySequence = create_frame_of_ref_study_sequence(series_data) # Add to sequence ds.ReferencedFrameOfReferenceSequence = Sequence() ds.ReferencedFrameOfReferenceSequence.append(refd_frame_of_ref)
def test_creation_with_container(self): """FileDataset.__init__ works OK with a container such as gzip""" class Dummy(object): filename = '/some/path/to/test' ds = Dataset() ds.PatientName = "CITIZEN^Jan" fds = FileDataset(Dummy(), ds) assert fds.filename == '/some/path/to/test'
def test_long_specific_char_set(self): """Test that specific character set is read even if it is longer than defer_size""" ds = Dataset() long_specific_char_set_value = ['ISO 2022IR 100'] * 9 ds.add(DataElement(0x00080005, 'CS', long_specific_char_set_value)) msg = (r"Unknown encoding 'ISO 2022IR 100' - using default encoding " r"instead") fp = BytesIO() file_ds = FileDataset(fp, ds) with pytest.warns(UserWarning, match=msg): file_ds.save_as(fp, write_like_original=True) with pytest.warns(UserWarning, match=msg): ds = dcmread(fp, defer_size=65, force=True) assert long_specific_char_set_value == ds[0x00080005].value
def on_c_store(dataset): """ Function replacing ApplicationEntity.on_store(). Called when a dataset is received following a C-STORE. Write the received dataset to file Parameters ---------- dataset - pydicom.Dataset The DICOM dataset sent via the C-STORE Returns ------- status : pynetdicom.SOPclass.Status or int A valid return status code, see PS3.4 Annex B.2.3 or the StorageServiceClass implementation for the available statuses """ mode_prefix = 'UN' mode_prefixes = {'CT Image Storage' : 'CT', 'Enhanced CT Image Storage' : 'CTE', 'MR Image Storage' : 'MR', 'Enhanced MR Image Storage' : 'MRE', 'Positron Emission Tomography Image Storage' : 'PT', 'Enhanced PET Image Storage' : 'PTE', 'RT Image Storage' : 'RI', 'RT Dose Storage' : 'RD', 'RT Plan Storage' : 'RP', 'RT Structure Set Storage' : 'RS', 'Computed Radiography Image Storage' : 'CR', 'Ultrasound Image Storage' : 'US', 'Enhanced Ultrasound Image Storage' : 'USE', 'X-Ray Angiographic Image Storage' : 'XA', 'Enhanced XA Image Storage' : 'XAE', 'Nuclear Medicine Image Storage' : 'NM', 'Secondary Capture Image Storage' : 'SC'} try: mode_prefix = mode_prefixes[dataset.SOPClassUID.__str__()] except: pass filename = '%s.%s' %(mode_prefix, dataset.SOPInstanceUID) logger.info('Storing DICOM file: %s' %filename) if os.path.exists(filename): logger.warning('DICOM file already exists, overwriting') meta = Dataset() meta.MediaStorageSOPClassUID = dataset.SOPClassUID meta.MediaStorageSOPInstanceUID = dataset.SOPInstanceUID meta.ImplementationClassUID = pynetdicom_uid_prefix ds = FileDataset(filename, {}, file_meta=meta, preamble=b"\0" * 128) ds.update(dataset) ds.is_little_endian = True ds.is_implicit_VR = True ds.save_as(filename) return 0x0000 # Success
def add_patient_information(ds: FileDataset, series_data): reference_ds = series_data[0] # All elements in series should have the same data ds.PatientName = getattr(reference_ds, "PatientName", "") ds.PatientID = getattr(reference_ds, "PatientID", "") ds.PatientBirthDate = getattr(reference_ds, "PatientBirthDate", "") ds.PatientSex = getattr(reference_ds, "PatientSex", "") ds.PatientAge = getattr(reference_ds, "PatientAge", "") ds.PatientSize = getattr(reference_ds, "PatientSize", "") ds.PatientWeight = getattr(reference_ds, "PatientWeight", "")
def write_rtstruct(src_dicom_data, label_volume_data_list): sop_instance_uid = pydicom.uid.generate_uid() filename = os.path.join(src_dicom_data[2], 'RS.' + sop_instance_uid + '.dcm') file_meta = Dataset() ds = FileDataset(filename, {}, file_meta=file_meta, preamble=b"\0" * 128) __write_file_meta(ds, sop_instance_uid) src_dicomdataset_list = src_dicom_data[1] __write_dicom_basic_info(ds, src_dicomdataset_list) roi_list = get_roi_list(src_dicomdataset_list, label_volume_data_list) __write_referenced_frame_of_reference_sequence(ds, src_dicomdataset_list) __write_structure_set_roi_sequence(ds, src_dicomdataset_list, roi_list) __write_roi_contour_sequence(ds, roi_list) __write_rt_roi_observations_sequence(ds, roi_list) ds.save_as(filename, write_like_original=False) print('end: write rtstructure')
def dicom_create_new_dataset(): suffix = '.dcm' file_name = tempfile.NamedTemporaryFile(suffix=suffix).name file_meta = Dataset() # Set the required values file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' file_meta.MediaStorageSOPInstanceUID = "1.3.6.1.4.1.5962.1.1.1.1.1.20040119072730.12322" file_meta.ImplementationClassUID = "1.3.6.1.4.1.5962.2" file_meta.TransferSyntaxUID = '1.2.840.10008.1.2' ds = FileDataset(file_name, {}, file_meta=file_meta, preamble=b"\0" * 128) return ds
def add_patient_information(ds: FileDataset, series_data): reference_ds = series_data[ 0] # All elements in series should have the same data ds.PatientName = reference_ds.PatientName ds.PatientID = reference_ds.PatientID ds.PatientBirthDate = reference_ds.PatientBirthDate ds.PatientSex = reference_ds.PatientSex ds.PatientAge = reference_ds.PatientAge ds.PatientSize = reference_ds.PatientSize ds.PatientWeight = reference_ds.PatientWeight
def write_slice_to_dicom(file_path, arr): ''' Write 2D numpy arr to an individual dicom file Note: Minimal dicom meta-data included. This should be improved in future work. ''' file_meta = Dataset() file_meta.TransferSyntaxUID = ImplicitVRLittleEndian file_meta.MediaStorageSOPClassUID = '1.1' file_meta.MediaStorageSOPInstanceUID = '1.2' file_meta.ImplementationClassUID = '1.3' ds = FileDataset(file_path, {}, file_meta=file_meta, preamble=b'\x00' * 128) ds.BitsAllocated = 16 ds.Rows = DIM ds.Columns = DIM ds.PixelRepresentation = 0 ds.SamplesPerPixel = 1 ds.PixelData = arr.tostring() ds.save_as(file_path, write_like_original=True) return
def OnReceiveStore(SOPClass, DS): print "Received C-STORE", DS.PatientName try: # do something with dataset. For instance, store it. file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # !! Need valid UID here file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !!! Need valid UIDs here file_meta.ImplementationClassUID = "1.2.3.4" filename = '%s/%s.dcm' % (tempfile.gettempdir(), DS.SOPInstanceUID) ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) ds.update(DS) #ds.is_little_endian = True #ds.is_implicit_VR = True ds.save_as(filename) print "File %s written" % filename except: pass # must return appropriate status return SOPClass.Success
def OnReceiveStore(SOPClass, DS): file_meta = Dataset() file_meta.PatientID = 'PAT020' filename = time.strftime("%Y%m%d_%H%M%S") + ".dcm" ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) ds.update(DS) ds.save_as(filename) return SOPClass.Success
def _on_c_store(self, event): ''' :param dataset: pydicom.Dataset The DICOM dataset sent via the C-STORE :param context: pynetdicom3.presentation.PresentationContextTuple Details of the presentation context the dataset was sent under. :param info: dict A dict containing information about the association and DIMSE message. :return: pynetdicom.sop_class.Status or int ''' dataset = event.dataset context = event.context try: logger.debug(f'_on_c_store called for {dataset.SOPInstanceUID}') os.makedirs(self.result_dir, exist_ok=True) filepath = self.path_for_dataset_instance(dataset) logger.info(f'Storing DICOM file: {filepath}') if os.path.exists(filepath): logger.warning('DICOM file already exists, overwriting') meta = Dataset() meta.MediaStorageSOPClassUID = dataset.SOPClassUID meta.MediaStorageSOPInstanceUID = dataset.SOPInstanceUID meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID meta.TransferSyntaxUID = context.transfer_syntax # The following is not mandatory, set for convenience meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION ds = FileDataset(filepath, {}, file_meta=meta, preamble=b"\0" * 128) ds.update(dataset) ds.is_little_endian = context.transfer_syntax.is_little_endian ds.is_implicit_VR = context.transfer_syntax.is_implicit_VR ds.save_as(filepath, write_like_original=False) status_ds = Dataset() status_ds.Status = 0x0000 except Exception as e: logger.error(f'C-STORE failed: {e}') status_ds = Dataset() status_ds.Status = 0x0110 # Processing Failure return status_ds
def setUp(self): ds = Dataset() ds.DoubleFloatPixelData = (b'\x00\x01\x02\x03\x04\x05\x06\x07' b'\x01\x01\x02\x03\x04\x05\x06\x07') # OD ds.SelectorOLValue = (b'\x00\x01\x02\x03\x04\x05\x06\x07' b'\x01\x01\x02\x03') # VR of OL ds.PotentialReasonsForProcedure = ['A', 'B', 'C'] # VR of UC, odd length ds.StrainDescription = 'Test' # Even length ds.URNCodeValue = 'http://test.com' # VR of UR ds.RetrieveURL = 'ftp://test.com ' # Test trailing spaces ignored ds.DestinationAE = ' TEST 12 ' # 16 characters max for AE self.fp = BytesIO() # Implicit little file_ds = FileDataset(self.fp, ds) file_ds.is_implicit_VR = True file_ds.is_little_endian = True file_ds.save_as(self.fp, write_like_original=True) self.fp_ex = BytesIO() # Explicit little file_ds = FileDataset(self.fp_ex, ds) file_ds.is_implicit_VR = False file_ds.is_little_endian = True file_ds.save_as(self.fp_ex, write_like_original=True)
def test_correct_ambiguous_vr_compressed(self): """Test correcting compressed Pixel Data read from file""" # Create an implicit VR compressed dataset ds = dcmread(jpeg_lossless_name) fp = BytesIO() file_ds = FileDataset(fp, ds) file_ds.is_implicit_VR = True file_ds.is_little_endian = True file_ds.save_as(fp) ds = dcmread(fp, force=True) self.assertEqual(ds[0x7fe00010].VR, 'OB')
def __init__(self, file_name, IsCreate=False): ## This code block was taken from the output of a MATLAB secondary ## capture. I do not know what the long dotted UIDs mean, but ## this code works. # Define items as (VR, VM, description, is_retired flag, keyword) # Leave is_retired flag blank. # Update the dictionary itself DicomDictionary.update(self.AI_ANLAYSIS_ITEM) if IsCreate: self.__file_name__ = file_name file_meta = Dataset() # Ultrasound Multiframe Image Storage - https://www.dicomlibrary.com/dicom/sop/ file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.3.1' file_meta.MediaStorageSOPInstanceUID = '999.999.2.19941105.134500.2.101' file_meta.ImplementationClassUID = '999.999' # Transfer Syntax - https://www.dicomlibrary.com/dicom/transfer-syntax/ file_meta.TransferSyntaxUID = '1.2.840.10008.1.2' ds = FileDataset(file_name, {}, file_meta=file_meta, preamble=b"\0" * 128) # DICOM modality, that represents DICOM file type - https://www.dicomlibrary.com/dicom/modality/ ds.Modality = 'US' # Ultrasound ds.ContentDate = str(datetime.date.today()).replace('-', '') ds.ContentTime = str(time.time()) # milliseconds since the epoch ds.StudyInstanceUID = '999.999.2.19941105.134500' ds.SeriesInstanceUID = '999.999.2.19941105.134500.2' ds.SOPInstanceUID = '999.999.2.19941105.134500.2.101' # https://searchcode.com/codesearch/view/13929148/ ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.3.1' # 'Ultrasound Multi-frame Image Storage' - 1.2.840.10008.5.1.4.1.1.3.1 # ds.SecondaryCaptureDeviceManufctur = 'Python 2.7.3' self.Dataset = ds else: self.Dataset = dicom.read_file(file_name)
def dicom_from_image_layer(image_layer): suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name filename_big_endian = tempfile.NamedTemporaryFile(suffix=suffix).name file_meta = FileMetaDataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.PatientName = "Test^Firstname" ds.PatientID = "123456" ds.PixelData = image_layer.data.tostring() ds.is_little_endian = True ds.is_implicit_VR = True dt = datetime.datetime.now() ds.ContentDate = dt.strftime('%Y%m%d') timeStr = dt.strftime('%H%M%S.%f') # long format with micro seconds ds.ContentTime = timeStr return ds
def setUp(self): ds = Dataset() #ds.DoubleFloatPixelData = FIXME # VR of OD # No element in _dicom_dict.py has a VR of OL #ds.LongCodeValue = FIXME # VR of UC ds.URNCodeValue = 'http://test.com' # VR of UR ds.RetrieveURL = 'ftp://test.com ' # Test trailing spaces ignored ds.DestinationAE = ' TEST 12 ' # 16 characters max for AE self.fp = BytesIO() file_ds = FileDataset(self.fp, ds) file_ds.is_implicit_VR = True file_ds.is_little_endian = True file_ds.save_as(self.fp)
def OnReceiveStore(SOPClass, DS): print "Received C-STORE" # do something with dataset. For instance, store it. file_meta = Dataset() # CT Image Storage file_meta.MediaStorageSOPClassUID = "1.2.840.10008.5.1.4.1.1.2" # !! Need valid UID here for real work file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here filename = "/tmp/%s.dcm" % DS.SOPInstanceUID ds = FileDataset(filename, {}, file_meta=file_meta, preamble="\0" * 128) ds.update(DS) ds.is_little_endian = True ds.is_implicit_VR = True ds.save_as(filename) print "File %s written" % filename # must return appropriate status return 0
def _build_dummy_pydicom_header(fields=None): """Builds dummy pydicom-based header. Note these headers are not dicom compliant and should not be used to write out DICOM files. Adapted from https://pydicom.github.io/pydicom/dev/auto_examples/input_output/plot_write_dicom.html """ suffix = ".dcm" filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name file_meta = FileMetaDataset() file_meta.MediaStorageSOPClassUID = "1.2.840.10008.5.1.4.1.1.2" file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" # Create the FileDataset instance (initially no data elements, but file_meta supplied). ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) # Add the data elements -- not trying to set all required here. Check DICOM standard. ds.PatientName = "Test^Firstname" ds.PatientID = "123456" if fields is not None: for k, v in fields.items(): setattr(ds, k, v) # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True # Set creation date/time dt = datetime.datetime.now() ds.ContentDate = dt.strftime("%Y%m%d") timeStr = dt.strftime("%H%M%S.%f") # long format with micro seconds ds.ContentTime = timeStr return ds
def retrieve_fast(DICOM_data: FileDataset, data_element: str) -> (bool, str): """ A low level function used to retrieve elements from DICOM object that has already been loaded and return a LIST of matching element. ACCEPT PARTIAL MATCH :param file_path: :param data_element: :return: LIST of all data elements that match the pattern provided in the data_element and their value. NO Regular EXPRESSION. """ try: # Get a list of all data elements that can have element label. element_values = DICOM_data.data_element(data_element).value return True, element_values except KeyError: # @todo: dicomdir situation most likely ends here. fail_reason = f"In memory retrieve of DICOM element failed. The data element provided: {data_element}, does not appear to exist" logger.error(fail_reason) return False, fail_reason except Exception: fail_reason = "In memory retrieve of DICOM element failed. General catch all exception reached. Contact author with the file to debug." logger.error(fail_reason) return False, fail_reason
def create_dicom_base(self): if _dicom_loaded is False: raise ModuleNotLoadedError("Dicom") if self.header_set is False: raise InputError("Header not loaded") # TODO tags + code datatypes are described here: # https://www.dabsoft.ch/dicom/6/6/#(0020,0012) # datatype codes are described here: # ftp://dicom.nema.org/medical/DICOM/2013/output/chtml/part05/sect_6.2.html meta = Dataset() meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage # Media Storage SOP Instance UID tag 0x0002,0x0003 (type UI - Unique Identifier) meta.MediaStorageSOPInstanceUID = self._ct_sop_instance_uid meta.ImplementationClassUID = "1.2.3.4" meta.TransferSyntaxUID = uid.ImplicitVRLittleEndian # Implicit VR Little Endian - Default Transfer Syntax ds = FileDataset("file", {}, file_meta=meta, preamble=b"\0" * 128) ds.PatientName = self.patient_name if self.patient_id in (None, ''): ds.PatientID = datetime.datetime.today().strftime('%Y%m%d-%H%M%S') else: ds.PatientID = self.patient_id # Patient ID tag 0x0010,0x0020 (type LO - Long String) ds.PatientSex = '' # Patient's Sex tag 0x0010,0x0040 (type CS - Code String) # Enumerated Values: M = male F = female O = other. ds.PatientBirthDate = '19010101' ds.SpecificCharacterSet = 'ISO_IR 100' ds.AccessionNumber = '' ds.is_little_endian = True ds.is_implicit_VR = True ds.SOPClassUID = '1.2.3' # !!!!!!!! # SOP Instance UID tag 0x0008,0x0018 (type UI - Unique Identifier) ds.SOPInstanceUID = self._ct_sop_instance_uid # Study Instance UID tag 0x0020,0x000D (type UI - Unique Identifier) # self._dicom_study_instance_uid may be either set in __init__ when creating new object # or set when import a DICOM file # Study Instance UID for structures is the same as Study Instance UID for CTs ds.StudyInstanceUID = self._dicom_study_instance_uid # Series Instance UID tag 0x0020,0x000E (type UI - Unique Identifier) # self._ct_dicom_series_instance_uid may be either set in __init__ when creating new object # or set when import a DICOM file # Series Instance UID for structures might be different than Series Instance UID for CTs ds.SeriesInstanceUID = self._ct_dicom_series_instance_uid # Study Instance UID tag 0x0020,0x000D (type UI - Unique Identifier) ds.FrameofReferenceUID = '1.2.3' # !!!!!!!!! ds.StudyDate = datetime.datetime.today().strftime('%Y%m%d') ds.StudyTime = datetime.datetime.today().strftime('%H%M%S') ds.PhotometricInterpretation = 'MONOCHROME2' ds.SamplesPerPixel = 1 ds.ImageOrientationPatient = ['1', '0', '0', '0', '1', '0'] ds.Rows = self.dimx ds.Columns = self.dimy ds.SliceThickness = str(self.slice_distance) ds.PixelSpacing = [self.pixel_size, self.pixel_size] # Add eclipse friendly IDs ds.StudyID = '1' # Study ID tag 0x0020,0x0010 (type SH - Short String) ds.ReferringPhysiciansName = 'py^trip' # Referring Physician's Name tag 0x0008,0x0090 (type PN - Person Name) ds.PositionReferenceIndicator = '' # Position Reference Indicator tag 0x0020,0x1040 ds.SeriesNumber = '1' # SeriesNumber tag 0x0020,0x0011 (type IS - Integer String) return ds
def on_c_store(dataset): """ Write `dataset` to file as little endian implicit VR Parameters ---------- dataset - pydicom.Dataset The DICOM dataset sent via the C-STORE Returns ------- status A valid return status code, see PS3.4 Annex B.2.3 or the StorageServiceClass implementation for the available statuses """ mode_prefix = 'UN' mode_prefixes = {'CT Image Storage' : 'CT', 'Enhanced CT Image Storage' : 'CTE', 'MR Image Storage' : 'MR', 'Enhanced MR Image Storage' : 'MRE', 'Positron Emission Tomography Image Storage' : 'PT', 'Enhanced PET Image Storage' : 'PTE', 'RT Image Storage' : 'RI', 'RT Dose Storage' : 'RD', 'RT Plan Storage' : 'RP', 'RT Structure Set Storage' : 'RS', 'Computed Radiography Image Storage' : 'CR', 'Ultrasound Image Storage' : 'US', 'Enhanced Ultrasound Image Storage' : 'USE', 'X-Ray Angiographic Image Storage' : 'XA', 'Enhanced XA Image Storage' : 'XAE', 'Nuclear Medicine Image Storage' : 'NM', 'Secondary Capture Image Storage' : 'SC'} try: mode_prefix = mode_prefixes[dataset.SOPClassUID.__str__()] except: pass filename = '%s.%s' %(mode_prefix, dataset.SOPInstanceUID) logger.info('Storing DICOM file: %s' %filename) if os.path.exists(filename): logger.warning('DICOM file already exists, overwriting') meta = Dataset() meta.MediaStorageSOPClassUID = dataset.SOPClassUID meta.MediaStorageSOPInstanceUID = dataset.SOPInstanceUID meta.ImplementationClassUID = pynetdicom_uid_prefix ds = FileDataset(filename, {}, file_meta=meta, preamble=b"\0" * 128) ds.update(dataset) ds.is_little_endian = True ds.is_implicit_VR = True if not args.ignore: # Try to save to output-directory if args.output_directory is not None: filename = os.path.join(args.output_directory, filename) try: ds.save_as(filename) except IOError: logger.error('Could not write file to specified directory:') logger.error(" %s" %os.path.dirname(filename)) logger.error('Directory may not exist or you may not have write ' 'permission') return 0xA700 # Failed - Out of Resources except: logger.error('Could not write file to specified directory:') logger.error(" %s" %os.path.dirname(filename)) return 0xA700 # Failed - Out of Resources return 0x0000 # Success
# Create some temporary filenames suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name filename_big_endian = tempfile.NamedTemporaryFile(suffix=suffix).name print("Setting file meta information...") # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' file_meta.MediaStorageSOPInstanceUID = "1.2.3" file_meta.ImplementationClassUID = "1.2.3.4" print("Setting dataset values...") # Create the FileDataset instance (initially no data elements, but file_meta # supplied) ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) # Add the data elements -- not trying to set all required here. Check DICOM # standard ds.PatientName = "Test^Firstname" ds.PatientID = "123456" # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True # Set creation date/time dt = datetime.datetime.now() ds.ContentDate = dt.strftime('%Y%m%d') timeStr = dt.strftime('%H%M%S.%f') # long format with micro seconds ds.ContentTime = timeStr
def create_dicom_plan(self): """ Create a dummy DICOM RT-plan object. The only data which is forwarded to this object, is self.patient_name. :returns: a DICOM RT-plan object. """ meta = Dataset() meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage meta.MediaStorageSOPInstanceUID = "1.2.3" meta.ImplementationClassUID = "1.2.3.4" meta.TransferSyntaxUID = uid.ImplicitVRLittleEndian # Implicit VR Little Endian - Default Transfer Syntax ds = FileDataset("file", {}, file_meta=meta, preamble=b"\0" * 128) ds.PatientsName = self.patient_name if self.patient_id in (None, ''): ds.PatientID = datetime.datetime.today().strftime('%Y%m%d-%H%M%S') else: ds.PatientID = self.patient_id # Patient ID tag 0x0010,0x0020 (type LO - Long String) ds.PatientsSex = '' # Patient's Sex tag 0x0010,0x0040 (type CS - Code String) # Enumerated Values: M = male F = female O = other. ds.PatientsBirthDate = '19010101' ds.SpecificCharacterSet = 'ISO_IR 100' ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.2' # CT Image Storage # Study Instance UID tag 0x0020,0x000D (type UI - Unique Identifier) # self._dicom_study_instance_uid may be either set in __init__ when creating new object # or set when import a DICOM file # Study Instance UID for structures is the same as Study Instance UID for CTs ds.StudyInstanceUID = self._dicom_study_instance_uid # Series Instance UID tag 0x0020,0x000E (type UI - Unique Identifier) # self._pl_dicom_series_instance_uid may be either set in __init__ when creating new object # Series Instance UID might be different than Series Instance UID for CTs ds.SeriesInstanceUID = self._plan_dicom_series_instance_uid ds.Modality = "RTPLAN" ds.SeriesDescription = 'RT Plan' ds.RTPlanDate = datetime.datetime.today().strftime('%Y%m%d') ds.RTPlanGeometry = '' ds.RTPlanLabel = 'B1' ds.RTPlanTime = datetime.datetime.today().strftime('%H%M%S') structure_ref = Dataset() structure_ref.RefdSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.3' # RT Structure Set Storage structure_ref.RefdSOPInstanceUID = '1.2.3' ds.RefdStructureSets = Sequence([structure_ref]) dose_ref = Dataset() dose_ref.DoseReferenceNumber = 1 dose_ref.DoseReferenceStructureType = 'SITE' dose_ref.DoseReferenceType = 'TARGET' dose_ref.TargetPrescriptionDose = self.target_dose dose_ref.DoseReferenceDescription = "TUMOR" ds.DoseReferenceSequence = Sequence([dose_ref]) return ds
else: homedir = os.path.expanduser("~") filename = os.path.join(homedir, "test.dcm") filename2 = os.path.join(homedir, "test-explBig.dcm") print("Setting file meta information...") # Populate required values for file meta information file_meta = Dataset() file_meta.MediaStorageSOPClassUID = "1.2.840.10008.5.1.4.1.1.2" # CT Image Storage file_meta.MediaStorageSOPInstanceUID = "1.2.3" # !! Need valid UID here for real work file_meta.ImplementationClassUID = "1.2.3.4" # !!! Need valid UIDs here print("Setting dataset values...") # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(filename, {}, file_meta=file_meta, preamble=b"\0" * 128) # Add the data elements -- not trying to set all required here. Check DICOM standard ds.PatientName = "Test^Firstname" ds.PatientID = "123456" # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True print("Writing test file", filename) ds.save_as(filename) print("File saved.") # Write as a different transfer syntax ds.file_meta.TransferSyntaxUID = (