JPETTomography / j-pet-format-converter

Apache License 2.0
1 stars 3 forks source link

Minimal DICOM document #8

Open graag opened 2 years ago

graag commented 2 years ago

Opracować format opisu minimalnego obrazu DICOM

Minimalny zestaw atrybutów definiuje standard DICOM:

aistrych commented 2 years ago

Przykładowy kod tworzący plik wynikowy dicom stworzony na bazie przykładowych plików PETCT. Do każdego TAGa dodany jest jego kod w postaci pary integerów a także informacja o tym czy jest wymagany, opcjonalny lub warunkowy. Dane binarne wyciąłem, część wartości pozmieniałem.

# 1 - tag wymagany, nie moze byc null
# 2 - tag wymagany, moze byc null
# 3 - tag opcjonalny
# C - tag warunkowy

from pydicom.dataset import Dataset, FileMetaDataset
from pydicom.sequence import Sequence

# File meta info data elements
file_meta = FileMetaDataset()
file_meta.FileMetaInformationGroupLength = 190
file_meta.FileMetaInformationVersion = b'\x00\x01'
file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'                                     # (0008,1150) 1
file_meta.MediaStorageSOPInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406580734300013807'     # (0008,1155) 1
file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.1'
file_meta.ImplementationClassUID = '1.3.12.2.1107.5.1.4'
file_meta.ImplementationVersionName = 'SIEMENS_S5VB42A'

# Main data elements
ds = Dataset()
ds.SpecificCharacterSet = 'ISO_IR 100'                                                              # (0008,0005) 1C Required if an expanded or replacement character set is used.
ds.ImageType = ['DERIVED', 'PRIMARY', 'AXIAL', 'CT_SOM5 SPI']                                       # (0008,0008) 3, PET Image 1
ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.2'                                                        # (0008,0016) 1
ds.SOPInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406580734300013807'                        # (0008,0018) 1
ds.StudyDate = '20220316'                                                                           # (0008,0020) 2
ds.SeriesDate = '20220316'                                                                          # (0008,0021) General Series 3, PET Series 1
ds.AcquisitionDate = '20220316'                                                                     # (0008,0022) 3, PET Image 2
ds.ContentDate = '20220316'                                                                         # (0008,0023) 2C
ds.StudyTime = '140030.312000'                                                                      # (0008,0030) 2
ds.SeriesTime = '140224.515000'                                                                     # (0008,0031) General Series 3, PET Series 1
ds.AcquisitionTime = '140202.913288'                                                                # (0008,0032) 3, PET Image 2
ds.ContentTime = '140202.913288'                                                                    # (0008,0033) 2C
ds.AccessionNumber = ''                                                                             # (0008,0050) 2
ds.Modality = 'CT'                                                                                  # (0008,0060) 1
ds.Manufacturer = 'SIEMENS'                                                                         # (0008,0070) 2, Device 3, SOP Common 1
ds.InstitutionName = '<nazwa zakladu>'                                                              # (0008,0080) 3
ds.InstitutionAddress = '<Adres szpitala>'                                                          # (0008,0081) 3
ds.ReferringPhysicianName = ''                                                                      # (0008,0090) 2
ds.StationName = 'CT58039'                                                                          # (0008,1010) 3
ds.StudyDescription = 'PET^6_PETCT_GAL_68 (Adult)'                                                  # (0008,1030) 3
ds.SeriesDescription = 'CTWB TULOW  4.0  eFoV'                                                      # (0008,103E) 3
ds.ManufacturerModelName = 'Biograph 64'                                                            # (0008,1090) 3

# Referenced Image Sequence
refd_image_sequence = Sequence()
ds.ReferencedImageSequence = refd_image_sequence

# Referenced Image Sequence: Referenced Image 1
refd_image1 = Dataset()
refd_image1.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
refd_image1.ReferencedSOPInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406360382800006407'
refd_image_sequence.append(refd_image1)

ds.DerivationDescription = 'Reconstruction field larger than scan field'                            # (0008,2111) 3

# Source Image Sequence
source_image_sequence = Sequence()
ds.SourceImageSequence = source_image_sequence

# Source Image Sequence: Source Image 1
source_image1 = Dataset()
source_image1.ReferencedSOPClassUID = '1.3.12.2.1107.5.9.1'
source_image1.ReferencedSOPInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406360382800006426'
source_image_sequence.append(source_image1)

ds.add_new((0x0009, 0x0010), 'LO', 'SIEMENS CT VA1 DUMMY')                                          # UNKNOWN TAG

ds.PatientName = '<IMIE I NAZWISKO>'                                                                 # (0010,0010) 2
ds.PatientID = '21.12.08-14:36:25-STD-1.3.12.2.1107.5.1.4.1016'                                     # (0010,0020) 1
ds.PatientBirthDate = '19770801'                                                                    # (0010,0030) 2
ds.PatientSex = 'M'                                                                                 # (0010,0040) 2
ds.PatientAge = '035Y'                                                                              # (0010,1010) 3
ds.PatientWeight = '80.0'                                                                           # (0010,1030) 3

ds.BodyPartExamined = 'ABDOMEN'                                                                     # (0018,0015) 3
ds.SliceThickness = '4.0'                                                                           # (0018,0050) 2
ds.KVP = '120.0'                                                                                    # (0018,0060) 3
ds.DataCollectionDiameter = '500.0'                                                                 # (0018,0090) 3 (CT Modules)
ds.DeviceSerialNumber = '1016'                                                                      # (0018,1000) 3
ds.SoftwareVersions = '6.7.3'                                                                       # (0018,1020) 3
ds.ProtocolName = '6_PETCT_GAL_68'                                                                  # (0018,1030) 3
ds.ReconstructionDiameter = '700.0'                                                                 # (0018,1100) 3 (MR Modules)
ds.DistanceSourceToDetector = '1040.0'                                                              # (0018,1110) 3 (CT Modules)
ds.DistanceSourceToPatient = '570.0'                                                                # (0018,1111) 3 (X-Ray Modules)
ds.GantryDetectorTilt = '0.0'                                                                       # (0018,1120) PET Series 3
ds.TableHeight = '145.0'                                                                            # (0018,1130) 3 (CT Modules)
ds.RotationDirection = 'CW'                                                                         # (0018,1140) 3 (CT Modules)
ds.ExposureTime = '500'                                                                             # (0018,1150) 3 (CT Modules)
ds.XRayTubeCurrent = '194'                                                                          # (0018,1151) 3 (CT Modules)
ds.Exposure = '121'                                                                                 # (0018,1152) 3 (CT Modules)
ds.FilterType = '0'                                                                                 # (0018,1160) 3 (CT Modules)
ds.GeneratorPower = '33'                                                                            # (0018,1170) 3 (CT Modules)
ds.FocalSpots = '1.2'                                                                               # (0018,1190) 3 (CT Modules)
ds.DateOfLastCalibration = '20220316'                                                               # (0018,1200) 3
ds.TimeOfLastCalibration = '073432.000000'                                                          # (0018,1201) 3
ds.ConvolutionKernel = 'B30f'                                                                       # (0018,1210) 3 (CT Modules)
ds.PatientPosition = 'HFS'                                                                          # (0018,5100) 2C
ds.SingleCollimationWidth = 1.2                                                                     # (0018,9306) 3 (CT Modules)
ds.TotalCollimationWidth = 28.799999999999997                                                       # (0018,9307) 3 (CT Modules)
ds.TableSpeed = 46.0                                                                                # (0018,9309) 3 (CT Modules)
ds.TableFeedPerRotation = 23.0                                                                      # (0018,9310) 3 (CT Modules)
ds.SpiralPitchFactor = 0.8                                                                          # (0018,9311) 3 (CT Modules)
ds.ExposureModulationType = 'XYZ_EC'                                                                # (0018,9323) 3 (CT Modules)
ds.EstimatedDoseSaving = 57.8078                                                                    # (0018,9324) 3 (CT Modules)
ds.CTDIvol = 8.186462608695651                                                                      # (0018,9345) 3 (CT Modules)
ds.add_new((0x0019, 0x0010), 'LO', 'SIEMENS CT VA0  COAD')                                          # UNKNOWN TAG 
ds.add_new((0x0019, 0x10b0), 'DS', '23.0')                                                          # UNKNOWN TAG
ds.add_new((0x0019, 0x10b1), 'LO', '4.30000022031406570357800000074')                               # UNKNOWN TAG
ds.StudyInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406564064000000062'                      # (0020,000D) 1
ds.SeriesInstanceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406580734300013726'                     # (0020,000E) 1
ds.StudyID = '5'                                                                                    # (0020,0010) 2 (Common Composite Image IOD Modules)
ds.SeriesNumber = '2'                                                                               # (0020,0011) 2
ds.AcquisitionNumber = '2'                                                                          # (0020,0012) 3
ds.InstanceNumber = '201'                                                                           # (0020,0013) 2, SOP Common 3
ds.ImagePositionPatient = [-349.31640625, -494.31640625, -1246.5]                                   # (0020,0032) 1
ds.ImageOrientationPatient = [1, 0, 0, 0, 1, 0]                                                     # (0020,0037) 1
ds.FrameOfReferenceUID = '1.3.12.2.1107.5.1.4.1016.30000022031406360382800006406'                   # (0020,0052) 1
ds.PositionReferenceIndicator = ''                                                                  # (0020,1040) 2
ds.SliceLocation = '-1246.5'                                                                        # (0020,1041) 3
ds.ImageComments = ''                                                                               # (0020,4000) 3
ds.add_new((0x0021, 0x0010), 'LO', 'SIEMENS MED')                                                   # UNKNOWN TAG
ds.add_new((0x0021, 0x1011), 'DS', [0, 0])                                                          # UNKNOWN TAG
ds.SamplesPerPixel = 1                                                                              # (0028,0002) 1
ds.PhotometricInterpretation = 'MONOCHROME2'                                                        # (0028,0004) 1
ds.Rows = 512                                                                                       # (0028,0010) 1
ds.Columns = 512                                                                                    # (0028,0011) 1
ds.PixelSpacing = [1.3671875, 1.3671875]                                                            # (0028,0030) 1
ds.BitsAllocated = 16                                                                               # (0028,0100) 1
ds.BitsStored = 12                                                                                  # (0028,0101) 1
ds.HighBit = 11                                                                                     # (0028,0102) 1
ds.PixelRepresentation = 0                                                                          # (0028,0103) 1
ds.SmallestImagePixelValue = 0                                                                      # (0028,0106) 3
ds.LargestImagePixelValue = 2269                                                                    # (0028,0107) 3
ds.WindowCenter = [40, 300]                                                                         # (0028,1050) 1C Required if VOI LUT Sequence (0028,3010) is not present
ds.WindowWidth = [300, 1500]                                                                        # (0028,1051) 1C Required if Window Center (0028,1050) is present.
ds.RescaleIntercept = '-1024.0'                                                                     # (0028,1052) 1
ds.RescaleSlope = '1.0'                                                                             # (0028,1053) 1
ds.WindowCenterWidthExplanation = ['WINDOW1', 'WINDOW2']                                            # (0028,1055) 3
ds.LossyImageCompression = '01'                                                                     # (0028,2110) 3, PET Image 1C
ds.add_new((0x0029, 0x0010), 'LO', 'SIEMENS CSA HEADER')                                            # UNKNOWN TAG
ds.add_new((0x0029, 0x0011), 'LO', 'SIEMENS MEDCOM HEADER')                                         # UNKNOWN TAG
ds.add_new((0x0029, 0x0012), 'LO', 'SIEMENS MEDCOM OOG')                                            # UNKNOWN TAG
ds.add_new((0x0029, 0x1008), 'CS', 'SOM 5')                                                         # UNKNOWN TAG 
ds.add_new((0x0029, 0x1009), 'LO', 'VA10A 971201')                                                  # UNKNOWN TAG
ds.add_new((0x0029, 0x1010), 'OB', <binary data>)                                                   # UNKNOWN TAG

# [Application Header Sequence]
tag00291140 = Sequence()
ds.Tag00291140 = tag00291140

# [Application Header Sequence]: [Application Header] 1
tag002911401 = Dataset()
tag002911401.add_new((0x0029, 0x0010), 'LO', 'SIEMENS MEDCOM HEADER')                               # UNKNOWN TAG
tag002911401.add_new((0x0029, 0x1041), 'CS', 'SOM 5 TPOS')                                          # UNKNOWN TAG
tag002911401.add_new((0x0029, 0x1042), 'LO', 'SOM 5 NULLPOSITION')                                  # UNKNOWN TAG
tag002911401.add_new((0x0029, 0x1043), 'LO', 'VB10A 20030626')                                      # UNKNOWN TAG
tag002911401.add_new((0x0029, 0x1044), 'OB', b'+000000000\x00A')                                    # UNKNOWN TAG
tag00291140.append(tag002911401)

ds.add_new((0x0029, 0x1208), 'CS', 'MEDCOM OOG 2')                                                  # UNKNOWN TAG
ds.add_new((0x0029, 0x1209), 'LO', 'VX70G')                                                         # UNKNOWN TAG
ds.add_new((0x0029, 0x1210), 'OB', <file description and data>)                                     # UNKNOWN TAG

ds.add_new([0x6000, 0x0010], 'US', 512)  # Overlay Rows                                             # (6000,0010) 1
ds.add_new([0x6000, 0x0011], 'US', 512)  # Overlay Columns                                          # (6000,0011) 1
ds.add_new([0x6000, 0x0015], 'US', 1)        # Overlay number of frames                             # (6000,0015) 1
ds.add_new([0x6000, 0x0022], 'LO', 'Siemens MedCom Object Graphics')    # Overlay description       # (6000,0022) 3
ds.add_new([0x6000, 0x0040], 'CS', 'G')      # Overlay Type ('R','G'), ROI or Graphics              # (6000,0040) 1
ds.add_new([0x6000, 0x0050], 'SS', [1, 1])   # Overlay Origin                                       # (6000,0050) 1
ds.add_new([0x6000, 0x0051], 'US', 1)        # Image Frame Origin                                   # (6000,0051) 3
ds.add_new([0x6000, 0x0100], 'US', 1)        # Overlay Bits Allocated, mandatory fixed value = 1    # (6000,0100) 1
ds.add_new([0x6000, 0x0102], 'US', 0)        # Overlay Bit Position, mandatory fixed value = 0      # (6000,0102) 1

overlay_data =  # <binary data>
ds.add_new([0x6000, 0x3000], 'OW', overlay_data)  # OverlayData                                     # (6000, 3000) 1

ds.PixelData =  # <binary data>

ds.DataSetTrailingPadding = # <binary data>                                                         # (FFFC,FFFC)

ds.file_meta = file_meta
ds.is_implicit_VR = False
ds.is_little_endian = True

ds.save_as(r'test.dcm', write_like_original=False)
graag commented 2 years ago

Kilka komentarzy do atrybutów:

Tagi specyficzne SIEMENS-a możemy olać, tak samo overlay.

graag commented 2 years ago

@jawka @wkrzemien

Kilka pytań :)

graag commented 1 year ago

@wkrzemien Zamykamy bo PR już jest w master. Tak?