def _write_dicom_file(np_slice: np.ndarray, header: pydicom.FileDataset, file_path: str): """Replace data in header with 2D numpy array and write to `file_path`. Args: np_slice (np.ndarray): 2D slice to encode in dicom file. header (pydicom.FileDataset): DICOM header. file_path: File path to write to. """ # Deep copy required in case headers are shared. header = copy.deepcopy(header) expected_dimensions = header.Rows, header.Columns assert ( np_slice.shape == expected_dimensions ), "In-plane dimension mismatch - expected shape {}, got {}".format( str(expected_dimensions), str(np_slice.shape)) np_slice_bytes = np_slice.tobytes() bit_depth = int( len(np_slice_bytes) / (np_slice.shape[0] * np_slice.shape[1]) * 8) if bit_depth != header.BitsAllocated: np_slice = _update_np_dtype(np_slice, header.BitsAllocated) np_slice_bytes = np_slice.tobytes() bit_depth = int( len(np_slice_bytes) / (np_slice.shape[0] * np_slice.shape[1]) * 8) assert bit_depth == header.BitsAllocated, "Bit depth mismatch: Expected {:d} got {:d}".format( header.BitsAllocated, bit_depth) header.PixelData = np_slice_bytes header.save_as(file_path)
def __write_dicom_file__(self, np_slice: np.ndarray, header: pydicom.FileDataset, filepath: str): """ Replace data in header with 2D numpy array and write to filepath :param np_slice: a 2D numpy array :param header: a pydicom.FileDataset with fields populated :param filepath: Filepath to write dicom to """ expected_dimensions = header.Rows, header.Columns assert np_slice.shape == expected_dimensions, "In-plane dimension mismatch - expected shape %s, got %s" % ( str(expected_dimensions), str(np_slice.shape)) np_slice_bytes = np_slice.tobytes() bit_depth = int( len(np_slice_bytes) / (np_slice.shape[0] * np_slice.shape[1]) * 8) if bit_depth != header.BitsAllocated: np_slice = __update_np_dtype__(np_slice, header.BitsAllocated) np_slice_bytes = np_slice.tobytes() bit_depth = int( len(np_slice_bytes) / (np_slice.shape[0] * np_slice.shape[1]) * 8) assert bit_depth == header.BitsAllocated, "Bit depth mismatch: Expected %d got %d" % ( header.BitsAllocated, bit_depth) header.PixelData = np_slice_bytes header.save_as(filepath)
def _get_window(dicom_file: pydicom.FileDataset, window='default', unit=None): if isinstance(window, dict): wc = window.get('window_center') ww = window.get('window_width') elif window == 'default' or unit is None: try: wc = dicom_file.WindowCenter ww = dicom_file.WindowWidth if isinstance(wc, pydicom.multival.MultiValue): wc = wc[0] if isinstance(ww, pydicom.multival.MultiValue): ww = ww[0] except: BitsStored = dicom_file.get('BitsStored') wc = 2**(BitsStored - 1) ww = 2**BitsStored elif isinstance(window, str) and unit in ['HU', 'Hounsfield Unit']: wc, ww = get_ct_window(window) else: try: wc = dicom_file.WindowCenter ww = dicom_file.WindowWidth if isinstance(wc, pydicom.multival.MultiValue): wc = wc[0] if isinstance(ww, pydicom.multival.MultiValue): ww = ww[0] except: wc = None ww = None if wc is None or ww is None: raise ValueError('Either window center or window width not found') return wc, ww
def voi_lut_trans(dicom_file: pydicom.FileDataset, image_data: numpy.ndarray, depth, window='default', unit: str = None): VOILUTSequence = getattr(dicom_file, 'VOILUTSequence', [{}])[0] lut_descriptor = VOILUTSequence.get('LUTDescriptor') if lut_descriptor is None: lut_descriptor = VOILUTSequence.get('LUTDescriptor') if isinstance(lut_descriptor, bytes): PixelRepresentation = int(dicom_file.get('PixelRepresentation')) if modality_classifier( dicom_file) is None and PixelRepresentation == 0: dtype = numpy.ushort else: dtype = numpy.short lut_descriptor = numpy.frombuffer(lut_descriptor, dtype) lut_data = VOILUTSequence.get('LUTData') if isinstance(lut_data, bytes): if lut_descriptor[2] == 8: dtype = numpy.uint8 elif lut_descriptor[2] == 16: dtype = numpy.uint16 else: raise ValueError( f'LUTDescriptor[2] should be 8 or 16. Got {lut_descriptor[2]}') lut_data = numpy.frombuffer(lut_data, dtype) scale_factor = depth / int(2**getattr(dicom_file, 'BitsStored', 12)) return lut_trans(image_data, lut_descriptor, lut_data, scale_factor)
def test_force_is_true(self): """ - Writes dicom file from scratch without File Meta Information Header - read with force = True - Check it doesn't raise InvalidDicomError Exception - Check file_meta has length 0 """ original_ds = FileDataset(FILENAME_PATH, {}, file_meta=None) ds_creation_util.save_ds_file_as_dicom(original_ds) ds = dcmread(FILENAME_PATH, force=True) self.assertTrue(len(ds.file_meta) == 0)
def voi_classifier(dicom_file: pydicom.FileDataset): """ Get value of interest (voi) transform method name from dicom object :param dicom_file: object read from pydicom :return: voi transform method name. Includes 'LINEAR', 'LINEAR_EXACT', 'SIGMOID', 'TABLE', or None """ VOILUTFunction = dicom_file.get('VOILUTFunction') VOILUTSequence = dicom_file.get('VOILUTSequence') WindowCenter = dicom_file.get('WindowCenter') if (VOILUTSequence is not None) and (WindowCenter is None): return 'TABLE' elif WindowCenter is not None: if VOILUTFunction is None: return 'LINEAR' else: return VOILUTFunction else: return 'LINEAR'
def modality_lut_trans(dicom_file: pydicom.FileDataset, image_data: numpy.ndarray): ModalityLUTSequence = dicom_file.get('ModalityLUTSequence')[0] lut_descriptor = ModalityLUTSequence.get('LUTDescriptor') if lut_descriptor is None: # debug lut_descriptor = ModalityLUTSequence.get('LUTDescriptor') # if don't do this line, line 40 will be None if isinstance(lut_descriptor, bytes): PixelRepresentation = int(dicom_file.get('PixelRepresentation')) dtype = numpy.ushort if PixelRepresentation == 0 else numpy.short lut_descriptor = numpy.frombuffer(lut_descriptor, dtype) lut_data = ModalityLUTSequence.get('LUTData') if isinstance(lut_data, bytes): if lut_descriptor[2] == 8: dtype = numpy.uint8 elif lut_descriptor[2] == 16: dtype = numpy.uint16 else: raise ValueError(f'LUTDescriptor[2] should be 8 or 16. Got {lut_descriptor[2]}') lut_data = numpy.frombuffer(lut_data, dtype) unit = ModalityLUTSequence.get('ModalityLUTType') return lut_trans(image_data, lut_descriptor, lut_data), unit
def test_force_is_default_false_raise_exception(self): """ - Writes dicom file from scratch without File Meta Information Header - read with force = False - Check it raises InvalidDicomError Exception """ original_ds = FileDataset(FILENAME_PATH, {}) ds_creation_util.save_ds_file_as_dicom(original_ds) try: dcmread(FILENAME_PATH) self.fail() except InvalidDicomError: pass except: self.fail()
def __init__(self, iod_type): """ Parameters ---------- iod_type : Type of IOD, i.e. DICOM object of class IODTypes """ self.iod_type = iod_type file_meta = Dataset() file_meta.MediaStorageSOPClassUID = iod_type.value file_meta.MediaStorageSOPInstanceUID = uid.generate_uid() file_meta.ImplementationClassUID = "1.2.752.24.16.4.1" self.dataset = FileDataset(None, {}, file_meta=file_meta, preamble=b"\0" * 128) self.dataset.is_little_endian = True self.dataset.is_implicit_VR = False self.dataset.file_meta.TransferSyntaxUID = uid.ExplicitVRLittleEndian
def on_c_store(self, ds: Dataset, context, info): logger.info('C-Store processing') file_meta = Dataset() file_meta.TransferSyntaxUID = ImplicitVRLittleEndian file_meta.MediaStorageSOPClassUID = ds.SOPClassUID file_meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID file_meta.ImplementationClassUID = '1.3.6.1.4.1.9590.100.1.0.100.4.0' fds = FileDataset(None, {}, file_meta=file_meta, preamble=b'\0' * 128) fds.update(ds) fds.is_little_endian = True fds.is_implicit_VR = True DicomSaver.save(fds) logger.info('C-Store succeeded') return 0x0000
def get_dcm_filed(__dcm: pydicom.FileDataset, __field_name: str): __field = __dcm.get(__field_name) if type(__field) == pydicom.multival.MultiValue: return int(__field[0]) else: return int(__field)
def dump_dicom(data, folder, spacing=(1, 1, 1), origin=(0, 0, 0), intercept=0, slope=1): """ Dump 3D scan in dicom format. Parameters ---------- data : ndarray 3D numpy array containing ct scan's data. folder : str folder where dicom files will be dumped. spacing : ArrayLike ndarray of shape (3,) that contains spacing along z, y, x axes. origin : ArrayLike ndarray of shape (3,) that contains origin for z, y, x axes. interception : float interception value. Default is 0. slope : float slope value. Default is 1. """ spacing = np.array(spacing).reshape(-1) origin = np.array(origin).reshape(-1) if not os.path.exists(folder): os.makedirs(folder) num_slices = data.shape[0] scan_id = np.random.randint(2 ** 16) for i in range(num_slices): slice_name = ( hex(scan_id + i) .replace('x', '') .upper() .zfill(8) ) filename = os.path.join(folder, slice_name) pixel_array = (data[i, ...] - intercept) / slope locZ, locY, locX = (float(origin[0] + spacing[0] * i), float(origin[1]), float(origin[2])) file_meta = Dataset() file_meta.MediaStorageSOPClassUID = 'Secondary Capture Image Storage' file_meta.MediaStorageSOPInstanceUID = ( hex(scan_id) .replace('x', '') .upper() .zfill(8) ) file_meta.ImplementationClassUID = slice_name dataset = FileDataset(filename, {}, file_meta=file_meta, preamble=b"\0"*128) dataset.PixelData = pixel_array.astype(np.uint16).tostring() dataset.RescaleSlope = slope dataset.RescaleIntercept = intercept dataset.ImagePositionPatient = MultiValue(type_constructor=float, iterable=[locZ, locY, locX]) dataset.PixelSpacing = MultiValue(type_constructor=float, iterable=[float(spacing[1]), float(spacing[2])]) dataset.SliceThickness = float(spacing[0]) dataset.Modality = 'WSD' dataset.Columns = pixel_array.shape[0] dataset.Rows = pixel_array.shape[1] dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian dataset.PixelRepresentation = 1 dataset.BitsAllocated = 16 dataset.BitsStored = 16 dataset.SamplesPerPixel = 1 write_file(filename, dataset)
def generate_dicom_scans(dst, num_scans=10, intercept=0, slope=1): spacing = (0.4 + 0.4 * np.random.rand(num_scans, 3) + np.array([1 + 0.5 * np.random.rand(), 0, 0])) origin = np.random.randint(-200, 200, (num_scans, 3)) for i in range(num_scans): num_slices = np.random.randint(128, 169) scan_id = np.random.randint(2**16) scan_data = np.random.randint(0, 256, (num_slices, 128, 128)) folder = os.path.join(dst, hex(scan_id).replace('x', '').upper().zfill(8)) if not os.path.exists(folder): os.makedirs(folder) for k in range(num_slices): slice_name = (hex(scan_id + k).replace('x', '').upper().zfill(8)) filename = os.path.join(folder, slice_name) pixel_array = (scan_data[k, ...] - intercept) / slope locZ = float(origin[i, 0] + spacing[i, 0] * k) locY, locX = float(origin[i, 1]), float(origin[i, 2]) file_meta = DicomDataset() file_meta.MediaStorageSOPClassUID = "Secondary Capture Image Storage" file_meta.MediaStorateSOPInstanceUID = (hex(scan_id).replace( 'x', '').upper().zfill(8)) file_meta.ImplementationClassUID = slice_name dataset = DicomFileDataset(filename, {}, file_meta=file_meta, preamble=b"\0" * 128) dataset.PixelData = pixel_array.astype(np.uint16).tostring() dataset.RescaleSlope = slope dataset.RescaleIntercept = intercept dataset.ImagePositionPatient = MultiValue( type_constructor=float, iterable=[locZ, locY, locX]) dataset.PixelSpacing = MultiValue( type_constructor=float, iterable=[float(spacing[i, 1]), float(spacing[i, 2])]) dataset.SliceThickness = float(spacing[i, 0]) dataset.Modality = 'WSD' dataset.Columns = pixel_array.shape[0] dataset.Rows = pixel_array.shape[1] dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian dataset.PixelRepresentation = 1 dataset.BitsAllocated = 16 dataset.BitsStored = 16 dataset.SamplesPerPixel = 1 write_file(filename, dataset)
def createStructDS(self, planData, ImageInfoUIDs, setupPosition, roiShiftVector): print("Creating Data structure") # create RS SOPInstanceUID structSOPInstanceUID = pydicom.uid.generate_uid() structSeriesInstanceUID = pydicom.uid.generate_uid() # get image header info from ImageSet_0.ImageInfo structFrameUID = '' structStudyInstanceUID = '' structSeriesUID = '' structClassUID = '1.2.840.10008.5.1.4.1.1.481.3' if "ImageInfoList" in ImageInfoUIDs: structFrameUID = ImageInfoUIDs.ImageInfoList[0].FrameUID structStudyInstanceUID = ImageInfoUIDs.ImageInfoList[ 0].StudyInstanceUID structSeriesUID = ImageInfoUIDs.ImageInfoList[0].SeriesUID # structClassUID = ImageInfoUIDs.ImageInfoList[0].ClassUID # Populate required values for file meta information file_meta = Dataset() # RT Structure Set Storage file_meta.MediaStorageSOPClassUID = structClassUID file_meta.MediaStorageSOPInstanceUID = structSOPInstanceUID structfilename = "RS." + structSOPInstanceUID + ".dcm" # this value remains static since implementation for creating file is the same file_meta.ImplementationClassUID = '1.2.826.0.1.3680043.8.498.75006884747854523615841001' # Create the FileDataset instance (initially no data elements, but file_meta supplied) ds = FileDataset(structfilename, {}, file_meta=file_meta, preamble=b'\x00' * 128) # print(file_meta.preamble) # add info_data,basic patientinfo # [0008,0005] - [0008,0018] ds.SpecificCharacterSet = 'ISO_IR 100' ds.InstanceCreationDate = time.strftime("%Y%m%d") ds.InstanceCreationTime = time.strftime("%H%M%S") ds.SOPClassUID = structClassUID ds.SOPInstanceUID = structSOPInstanceUID ds.Modality = 'RTSTRUCT' ds.AccessionNumber = "" ds.Manufacturer = 'Pinnalce3' # from sample dicom file, maybe should change? # not sure where to get information for this element can find this and read in from ds.StationName = "adacp3u7" # ds.ManufacturersModelName = 'Pinnacle3' ds = self.modifyPatientInfo(ds, planData) # [0008,1110] ds.ReferencedStudySequence = Sequence() ReferencedStudy1 = Dataset() ds.ReferencedStudySequence.append(ReferencedStudy1) # Study Component Management SOP Class (chosen from template) ds.ReferencedStudySequence[ 0].ReferencedSOPClassUID = '1.2.840.10008.3.1.2.3.2' ds.ReferencedStudySequence[ 0].ReferencedSOPInstanceUID = structStudyInstanceUID # ds.StudyInstanceUID = StudyInstanceUID print("Setting structure file study instance: " + str(structStudyInstanceUID)) # [0020,000d] ds.StudyInstanceUID = structStudyInstanceUID # [0020,000e] ds.SeriesInstanceUID = structSeriesInstanceUID # [3006,0010] ds.ReferencedFrameOfReferenceSequence = Sequence() ReferencedFrameofReference1 = Dataset() ds.ReferencedFrameOfReferenceSequence.append( ReferencedFrameofReference1) ds.ReferencedFrameOfReferenceSequence[ 0].FrameofReferenceUID = structFrameUID # [3006,0012] ds.ReferencedFrameOfReferenceSequence[ 0].RTReferencedStudySequence = Sequence() RTReferencedStudy1 = Dataset() ds.ReferencedFrameOfReferenceSequence[ 0].RTReferencedStudySequence.append(RTReferencedStudy1) ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].ReferencedSOPClassUID = '1.2.840.10008.3.1.2.3.2' ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].ReferencedSOPInstanceUID = structStudyInstanceUID # ds.StudyInstanceUID = StudyInstanceUID # [3006,0014] ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence = Sequence() RTReferencedSeries1 = Dataset() ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence.append(RTReferencedSeries1) ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence[ 0].SeriesInstanceUID = structSeriesUID # [3006,0016] ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence[0].ContourImageSequence = Sequence() # [fffe,e000] for i, value in enumerate(ImageInfoUIDs.ImageInfoList, 1): exec("ContourImage%d = Dataset()" % i) exec( "ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[0].RTReferencedSeriesSequence[0].ContourImageSequence.append(ContourImage%d)" % i) ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence[0].ContourImageSequence[ i - 1].ReferencedSOPClassUID = value.ClassUID ds.ReferencedFrameOfReferenceSequence[0].RTReferencedStudySequence[ 0].RTReferencedSeriesSequence[0].ContourImageSequence[ i - 1].ReferencedSOPInstanceUID = value.InstanceUID # exec("del ContourImage%d" % i) # [3006,0020] roiListData = planData.planROIsRawData.roiList ds.StructureSetROISequence = Sequence() for i, value in enumerate(roiListData, 1): exec("ROISet%d = Dataset()" % i) exec("ds.StructureSetROISequence.append(ROISet%d)" % i) ds.StructureSetROISequence[i - 1].ROIName = value.name ds.StructureSetROISequence[i - 1].ROINumber = i ds.StructureSetROISequence[ i - 1].ReferencedFrameOfReferenceUID = structFrameUID if 'volume' in value: ds.StructureSetROISequence[i - 1].ROIVolume = value.volume ds.StructureSetROISequence[ i - 1].ROIGenerationAlgorithm = value.roiinterpretedtype # [3006,0039]get each ROI ds.ROIContourSequence = Sequence() for i, value in enumerate(roiListData, 1): exec("ContourSequence%d = Dataset()" % i) exec("ds.ROIContourSequence.append(ContourSequence%d)" % i) ds.ROIContourSequence[i - 1].ROIDisplayColor = [0, 255, 0] ds.ROIContourSequence[i - 1].ReferencedROINumber = i # get all curves in current ROI ds.ROIContourSequence[i - 1].ContourSequence = Sequence() planROIsCurvesList = value.num_curve # get each ROI_Curvers for j, data in enumerate(planROIsCurvesList, 1): exec("CurvesPoint%d = Dataset()" % j) exec( "ds.ROIContourSequence[i - 1].ContourSequence.append(CurvesPoint%d)" % j) # [3006,0040] ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourImageSequence = Sequence() coutourImage1 = Dataset() ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourImageSequence.append(coutourImage1) ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourImageSequence[ 0].ReferencedSOPClassUID = structClassUID ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourImageSequence[ 0].ReferencedSOPInstanceUID = self.getCTInstanceUID( data.Points[0], setupPosition, ImageInfoUIDs) # [3006,0042] ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourGeometricType = "CLOSED_PLANAR" ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].NumberOfContourPoints = data.num_points # get each ROI_Curves_Points, using data.Points ds.ROIContourSequence[i - 1].ContourSequence[ j - 1].ContourData = self.getContourCurvePoints( data.Points, setupPosition, roiShiftVector) # [3006,0080] ds.RTROIObservationsSequence = Sequence() for i, current_roi in enumerate(ds.StructureSetROISequence, 1): exec("Observation%d = Dataset()" % i) exec("ds.RTROIObservationsSequence.append(Observation%d)" % i) ds.RTROIObservationsSequence[ i - 1].ObservationNumber = current_roi.ROINumber ds.RTROIObservationsSequence[ i - 1].ReferencedROINumber = current_roi.ROINumber ds.RTROIObservationsSequence[i - 1].RTROIInterpretedType = 'ORGAN' ds.RTROIObservationsSequence[i - 1].ROIInterpreter = "" # find out where to get if its been approved or not ds.ApprovalStatus = 'UNAPPROVED' # Set the transfer syntax ds.is_little_endian = True ds.is_implicit_VR = True # # Create the FileDataset instance (initially no data elements, but file_meta supplied) # structds = FileDataset(structfilename, {}, # file_meta=ds, preamble=b'\x00' * 128) # structfilepath=outputfolder + patientfolder + "/" + structfilename # structds.save_as("structfilepath") # print("Structure file being saved\n") ds.save_as(os.getenv('HOME') + '/PinnWork/' + structfilename) # # dcmds = pydicom.dcmread(ds) # print(dcmds) return ds
def create_dcm_file(self): suffix = '.dcm' filename_little_endian = tempfile.NamedTemporaryFile( suffix=suffix).name filename_big_endian = tempfile.NamedTemporaryFile(suffix=suffix).name print("Setting 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...") ds = FileDataset(filename_little_endian, {}, file_meta=file_meta, preamble=b"\0" * 128) ds.PatientName = self.get_patient_name( ) + " " + self.get_patient_surname() ds.PatientID = self.get_patient_id() ds.PatientSex = self.get_patient_sex() ds.PatientAge = self.get_patient_age() ds.PatientWeight = self.get_patient_weight() ds.ImageComment = self.get_patient_comment() ds.PatientBirthDate = self.get_patient_birth() # 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 ds.BitsAllocated = 16 ds.Rows = self.image.shape[0] ds.Columns = self.image.shape[1] ds.PixelRepresentation = 0 ds.SamplesPerPixel = 1 ds.PhotometricInterpretation = "MONOCHROME2" image = self.image image *= 255 image = image.astype("uint16") ds.PixelData = Image.fromarray(image).tobytes() print("Writing test file", filename_little_endian) ds.save_as(filename_little_endian) print("File saved.") ds.file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRBigEndian ds.is_little_endian = False ds.is_implicit_VR = False print("Writing test file as Big Endian Explicit VR", filename_big_endian) ds.save_as(filename_big_endian) return ds
def generate_common_dicom_dataset_series(self, slice_count: int, system: Modality) -> list: output_dataset = [] slice_pos = 0 slice_thickness = 0 study_uid = generate_uid() series_uid = generate_uid() frame_of_ref_uid = generate_uid() date_ = datetime.now().date() age = timedelta(days=45 * 365) time_ = datetime.now().time() cols = 2 rows = 2 bytes_per_voxel = 2 for i in range(0, slice_count): file_meta = Dataset() pixel_array = b"\0" * cols * rows * bytes_per_voxel file_meta.MediaStorageSOPClassUID = sop_classes[system][1] file_meta.MediaStorageSOPInstanceUID = generate_uid() file_meta.ImplementationClassUID = generate_uid() tmp_dataset = FileDataset('', {}, file_meta=file_meta, preamble=pixel_array) tmp_dataset.file_meta.TransferSyntaxUID = "1.2.840.10008.1.2.1" tmp_dataset.SliceLocation = slice_pos + i * slice_thickness tmp_dataset.SliceThickness = slice_thickness tmp_dataset.WindowCenter = 1 tmp_dataset.WindowWidth = 2 tmp_dataset.AcquisitionNumber = 1 tmp_dataset.InstanceNumber = i tmp_dataset.SeriesNumber = 1 tmp_dataset.ImageOrientationPatient = [ 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000 ] tmp_dataset.ImagePositionPatient = [ 0.0, 0.0, tmp_dataset.SliceLocation ] tmp_dataset.ImageType = ['ORIGINAL', 'PRIMARY', 'AXIAL'] tmp_dataset.PixelSpacing = [1, 1] tmp_dataset.PatientName = 'John Doe' tmp_dataset.FrameOfReferenceUID = frame_of_ref_uid tmp_dataset.SOPClassUID = sop_classes[system][1] tmp_dataset.SOPInstanceUID = generate_uid() tmp_dataset.SeriesInstanceUID = series_uid tmp_dataset.StudyInstanceUID = study_uid tmp_dataset.BitsAllocated = bytes_per_voxel * 8 tmp_dataset.BitsStored = bytes_per_voxel * 8 tmp_dataset.HighBit = (bytes_per_voxel * 8 - 1) tmp_dataset.PixelRepresentation = 1 tmp_dataset.Columns = cols tmp_dataset.Rows = rows tmp_dataset.SamplesPerPixel = 1 tmp_dataset.AccessionNumber = '2' tmp_dataset.AcquisitionDate = date_ tmp_dataset.AcquisitionTime = datetime.now().time() tmp_dataset.AdditionalPatientHistory = 'UTERINE CA PRE-OP EVAL' tmp_dataset.ContentDate = date_ tmp_dataset.ContentTime = datetime.now().time() tmp_dataset.Manufacturer = 'Mnufacturer' tmp_dataset.ManufacturerModelName = 'Model' tmp_dataset.Modality = sop_classes[system][0] tmp_dataset.PatientAge = '064Y' tmp_dataset.PatientBirthDate = date_ - age tmp_dataset.PatientID = 'ID0001' tmp_dataset.PatientIdentityRemoved = 'YES' tmp_dataset.PatientPosition = 'FFS' tmp_dataset.PatientSex = 'F' tmp_dataset.PhotometricInterpretation = 'MONOCHROME2' tmp_dataset.PixelData = pixel_array tmp_dataset.PositionReferenceIndicator = 'XY' tmp_dataset.ProtocolName = 'some protocole' tmp_dataset.ReferringPhysicianName = '' tmp_dataset.SeriesDate = date_ tmp_dataset.SeriesDescription = 'test series ' tmp_dataset.SeriesTime = time_ tmp_dataset.SoftwareVersions = '01' tmp_dataset.SpecificCharacterSet = 'ISO_IR 100' tmp_dataset.StudyDate = date_ tmp_dataset.StudyDescription = 'test study' tmp_dataset.StudyID = '' if (system == Modality.CT): tmp_dataset.RescaleIntercept = 0 tmp_dataset.RescaleSlope = 1 tmp_dataset.StudyTime = time_ output_dataset.append(tmp_dataset) return output_dataset