Exemplo n.º 1
0
def get_file_meta(dcm, root_uid):
    file_meta = FileMetaDataset()

    # From pydicom
    file_meta.MediaStorageSOPClassUID = (
        pydicom._storage_sopclass_uids.RTStructureSetStorage)
    file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid(
        root_uid)  # TODO Generate this properly
    file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian

    # From dicom imaging file
    imaging_meta = [
        "FileMetaInformationVersion",
        "ImplementationClassUID",
        "ImplementationVersionName",
    ]

    copy_attrs(dcm.file_meta, file_meta, imaging_meta)

    # file_meta.FileMetaInformationVersion = dcm.file_meta.FileMetaInformationVersion
    # file_meta.ImplementationClassUID = (
    #     dcm.file_meta.ImplementationClassUID
    # )  # TODO Check this is true on non-anon data
    # file_meta.ImplementationVersionName = dcm.file_meta.ImplementationVersionName

    return file_meta
Exemplo n.º 2
0
def convert(nome_tiff, nome_dicom):
	global ds
	# Nomes do arquivo
	filename_little_endian = nome_dicom

	# Criando arquivos com informações minimas
	print('Criando arquivo Dicom Image')
	file_meta = FileMetaDataset()
	file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.1' #http://dicom.nema.org/dicom/2013/output/chtml/part04/sect_I.4.html
	file_meta.MediaStorageSOPInstanceUID = "1.2.246.352.81.3.273720375.51644.19651.179.0"
	file_meta.ImplementationClassUID = "1.2.246.352.70.2.1.160.3"

	#Criando um dataset "vazio" ==> https://pydicom.github.io/pydicom/dev/reference/generated/pydicom.dataset.FileDataset.html
	ds = FileDataset(filename_little_endian, {}, file_meta = file_meta, preamble = b"\0"*128)

	#Adicionando elementos
	ds.PatientName = "Teste"
	ds.PatientID = "123456789"

	#Transfer Syntax
	ds.file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian
	ds.is_little_endian = True
	ds.is_implicit_VR = False

	#Adicionando data e hora de criação
	dt = datetime.datetime.now()
	ds.ContentDate = dt.strftime('%Y%m%d')
	timeStr = dt.strftime('%H%M%S.%f') # formato longo com micro segundos
	ds.ContentTime = timeStr

	#Carregando arquivo TIFF
	tiff_file = Image.open(nome_tiff)
	tiff_rotacionada90 = tiff_file.rotate(90)
	tiff_array = np.array(tiff_rotacionada90)

	#Adicionando array e outras informações da imagem ao dataset
	ds.PixelData = tiff_array.tobytes()

	tiff_meta_dict = {TAGS[key] : tiff_file.tag[key] for key in tiff_file.tag.keys()}

	ds.add_new([0x0008,0x0016], 'UI','1.2.840.10008.5.1.4.1.1.481.1') #SOP Class UID
	ds.add_new([0x0008,0x0018], 'UI','1.2.246.352.81.3.273720375.51644.19651.179.0') #SOP Instance UID
	ds.add_new([0x0028,0x0010], 'US',tiff_meta_dict['ImageLength'][0]) #rows
	ds.add_new([0x0028,0x0011], 'US',tiff_meta_dict['ImageWidth'][0]) #columns
	ds.add_new([0x0028,0x0100], 'US',tiff_meta_dict['BitsPerSample'][0]) #Bits Alocated
	ds.add_new([0x0028,0x0103], 'US', 0) # PixelRepresentation
	ds.add_new([0x0028,0x0002], 'US', tiff_meta_dict['SamplesPerPixel'][0]) # SamplesPerPixel
	ds.add_new([0x0028,0x0004], 'CS', 'MONOCHROME2') # Photometric Interpretation ==> https://dicom.innolitics.com/ciods/enhanced-mr-image/enhanced-mr-image/00280103
	ds.add_new([0x0008,0x0060], 'CS', 'RTIMAGE') #Modality
	ds.add_new([0x0028,0x0101], 'US',tiff_meta_dict['BitsPerSample'][0]) #Bits Stored
	ds.add_new([0x3002,0x0022], 'DS', 1000.0) # Radiation Machine SAD
	ds.add_new([0x3002,0x0026], 'DS', 1600.0) # RT Image SID
	ds.add_new([0x5000,0x0030], 'SH', ['PIXL', 'PIXL']) #Axis Units

	x = tiff_meta_dict['XResolution'][0]
	### Rever resolução IVIEW
	x_res = 1/((x[0]/x[1])/40.25) # mm por pixel

	ds.add_new([0x3002,0x0011], 'DS', [x_res,x_res]) #Image Plane Pixel Spacing
	print('Pronto!')
Exemplo n.º 3
0
def _read_file_meta_info(fp: BinaryIO) -> FileMetaDataset:
    """Return a Dataset containing any File Meta (0002,eeee) elements in `fp`.

    File Meta elements are always Explicit VR Little Endian (DICOM Standard,
    Part 10, :dcm:`Section 7<part10/chapter_7.html>`). Once any File Meta
    elements are read `fp` will be positioned at the start of the next group
    of elements.

    Parameters
    ----------
    fp : file-like
        The file-like positioned at the start of any File Meta Information
        group elements.

    Returns
    -------
    dataset.Dataset
        The File Meta elements as a Dataset instance. May be empty if no
        File Meta are present.
    """
    def _not_group_0002(tag: BaseTag, vr: Optional[str], length: int) -> bool:
        """Return True if the tag is not in group 0x0002, False otherwise."""
        return tag.group != 2

    start_file_meta = fp.tell()
    file_meta = FileMetaDataset(
        read_dataset(fp,
                     is_implicit_VR=False,
                     is_little_endian=True,
                     stop_when=_not_group_0002))
    if not file_meta._dict:
        return file_meta

    # Test the file meta for correct interpretation by requesting the first
    #   data element: if it fails, retry loading the file meta with an
    #   implicit VR (issue #503)
    try:
        file_meta[list(file_meta.elements())[0].tag]
    except NotImplementedError:
        fp.seek(start_file_meta)
        file_meta = FileMetaDataset(
            read_dataset(fp,
                         is_implicit_VR=True,
                         is_little_endian=True,
                         stop_when=_not_group_0002))

    # Log if the Group Length doesn't match actual length
    if 'FileMetaInformationGroupLength' in file_meta:
        # FileMetaInformationGroupLength must be 12 bytes long and its value
        #   counts from the beginning of the next element to the end of the
        #   file meta elements
        actual_len = fp.tell() - (start_file_meta + 12)
        elem_len = file_meta.FileMetaInformationGroupLength
        if elem_len != actual_len:
            logger.info(
                "_read_file_meta_info: (0002,0000) 'File Meta Information "
                "Group Length' value doesn't match the actual File Meta "
                f"Information length ({elem_len} vs {actual_len} bytes)")

    return file_meta
Exemplo n.º 4
0
def dicom_object_3d(dicom_object):
    series = "1.2.345"
    study = "2.3.456"
    dcm = deepcopy(dicom_object)
    source = Path(pydicom.data.get_testdata_files("*CT*")[0])  # type: ignore
    dcm.StudyInstanceUID = study
    dcm.SeriesInstanceUID = series
    dcm.SOPInstanceUID = series
    file_meta = FileMetaDataset()
    file_meta.MediaStorageSOPClassUID = UID("1.2.345")
    file_meta.MediaStorageSOPInstanceUID = UID("2.3.456")

    def func(num_frames, syntax=ExplicitVRLittleEndian):
        file_meta.TransferSyntaxUID = syntax
        old_data = dcm.PixelData
        dcm.NumberOfFrames = num_frames

        if syntax.is_compressed:
            new_data = encapsulate([old_data for _ in range(num_frames)],
                                   has_bot=False)
            dcm.PixelData = new_data
            dcm.compress(syntax)

        else:
            new_data = b"".join(old_data for _ in range(num_frames))
            dcm.PixelData = new_data

        dcm.file_meta = file_meta
        return dcm

    return func
Exemplo n.º 5
0
        def handle(event):
            meta = FileMetaDataset()
            meta.TransferSyntaxUID = event.context.transfer_syntax
            event.dataset.file_meta = meta

            event_out.append(event.dataset)

            return 0x0000
Exemplo n.º 6
0
def empty_dicom():
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationGroupLength = 206
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
    file_meta.MediaStorageSOPInstanceUID = '1.2.826.0.1.3680043.8.498.51645380419494159785729751472725175471'
    file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.1'
    file_meta.ImplementationClassUID = '1.2.826.0.1.3680043.8.498.1'
    file_meta.ImplementationVersionName = 'PYDICOM 2.0.0'

    ds = Dataset()
    ds.ImageType = ['ORIGINAL', 'PRIMARY', 'AXIAL']
    ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
    ds.SOPInstanceUID = '1.2.826.0.1.3680043.8.498.51645380419494159785729751472725175471'
    ds.Modality = 'CT'
    ds.StudyInstanceUID = '1.2.826.0.1.3680043.8.498.75112040858074996916346159754932379994'
    ds.SeriesInstanceUID = '1.2.826.0.1.3680043.8.498.64119849432490865623274415908957426618'
    ds.InstanceNumber = "1"
    ds.FrameOfReferenceUID = '1.2.826.0.1.3680043.8.498.10194591012322579188814682575529857631'
    ds.ImagesInAcquisition = "1"
    ds.SamplesPerPixel = 1
    ds.PhotometricInterpretation = 'MONOCHROME2'
    ds.BitsAllocated = 8
    ds.BitsStored = 8
    ds.HighBit = 7
    ds.PixelRepresentation = 0

    return ds, file_meta
Exemplo n.º 7
0
def create_ds():
    # Populate required values for file meta information
    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_PATH, {},
                     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 image position patient and image orientation patient
    ds.PixelSpacing = ['3.0', '3.0']
    slice_data = numpy.zeros((50, 50)).astype(numpy.uint16)
    ds.ImagePositionPatient = [
        '-74.87273061275482', '-147.24999237060547', '-147.1303328871727'
    ]
    ds.ImageOrientationPatient = [
        '0.9995653468771569', '0.027916281967051135', '-0.00947620828628687',
        '-0.02835352390030065', '0.9983635539946439', '-0.04966177340388578'
    ]

    # set the settings for this slice
    ds.Rows = slice_data.shape[1]
    ds.Columns = slice_data.shape[0]

    ds.SamplesPerPixel = 1
    ds.PhotometricInterpretation = 'MONOCHROME2'
    ds.PlanarConfiguration = 0
    ds.BitsAllocated = 16
    ds.BitsStored = 16
    ds.HighBit = 15
    ds.PixelRepresentation = 1
    ds.WindowCenter = 0
    ds.WindowWidth = 100

    # 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
Exemplo n.º 8
0
def set_file_meta(instance: Dataset):
    meta = FileMetaDataset()
    # meta.FileMetaInformationGroupLength = ??
    # meta.FileMetaInformationVersion = b'\x00\x01'
    meta.MediaStorageSOPClassUID = instance.SOPClassUID
    meta.MediaStorageSOPInstanceUID = instance.SOPInstanceUID
    meta.TransferSyntaxUID = ImplicitVRLittleEndian
    instance.is_implicit_VR = instance.is_little_endian = True
    # meta.ImplementationClassUID = ??
    # meta.ImplementationVersionName = ??
    instance.file_meta = meta
    instance.preamble = b'\x00' * 128
Exemplo n.º 9
0
def get_file_meta() -> FileMetaDataset:
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationGroupLength = 202
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
    file_meta.MediaStorageSOPClassUID = SOPClassUID.RTSTRUCT
    file_meta.MediaStorageSOPInstanceUID = generate_uid() # TODO find out random generation is fine
    file_meta.ImplementationClassUID = SOPClassUID.RTSTRUCT_IMPLEMENTATION_CLASS
    return file_meta
Exemplo n.º 10
0
def get_file_meta(dcms):
    dcm = dcms[0]
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationVersion = dcm.file_meta.FileMetaInformationVersion
    file_meta.MediaStorageSOPClassUID = "RT Structure Set Storage"
    file_meta.MediaStorageSOPInstanceUID = "Anonymous"  # TODO
    file_meta.TransferSyntaxUID = dcm.file_meta.TransferSyntaxUID
    file_meta.ImplementationClassUID = dcm.file_meta.ImplementationClassUID
    file_meta.ImplementationVersionName = dcm.file_meta.ImplementationVersionName
    return file_meta
Exemplo n.º 11
0
    def __init__(self, ct_path, mask, structures=None, output=None):

        if structures is None:
            structures = []

        self.ct_path = ct_path
        self.mask = mask
        self.structures = structures
        self.output = output or "RS.dcm"
        self.ct_files = natsorted([os.path.join(self.ct_path, ct) for ct in os.listdir(self.ct_path)
                                   if ct.endswith("dcm")])

        self.ds_cts = [dcmread(ct_file) for ct_file in self.ct_files]
        self.ds_ct_sop_instance_uid = [ds_ct.SOPInstanceUID for ds_ct in self.ds_cts]

        self.ds_ct_reference = self.ds_cts[0]

        self.mask = Mask(self.mask, ds_cts=self.ds_cts, ct_path=self.ct_path)
        self.ds_rs = Dataset()

        # RS meta
        self.ds_rs.file_meta = FileMetaDataset()
        self.ds_rs.file_meta.MediaStorageSOPClassUID = 'RT Structure Set Storage'
        self.ds_rs.file_meta.MediaStorageSOPInstanceUID = '1.2.345.678.9.1.11111111111111111.1111.11111'

        # RS transfer syntax
        self.ds_rs.is_little_endian = True
        self.ds_rs.is_implicit_VR = True

        # RS creation date/time
        date_time = datetime.datetime.now()
        self.ds_rs.ContentDate = date_time.strftime('%Y%m%d')

        time_str = date_time.strftime('%H%M%S')
        self.ds_rs.ContentTime = time_str

        # RS common tags
        for tag in COMMON_TAGS:
            if tag in self.ds_ct_reference:
                self.ds_rs[tag] = self.ds_ct_reference[tag]

        # RS series
        self.ds_rs.Modality = 'RTSTRUCT'
        self.ds_rs.SOPClassUID = UID('1.2.840.10008.5.1.4.1.1.481.3')
        self.ds_rs.SOPInstanceUID = generate_uid()
        self.ds_rs.ManufacturerModelName = "segmentation_RT"
        self.ds_rs.StructureSetLabel = 'RS: Unapproved'
        self.ds_rs.ApprovalStatus = 'UNAPPROVED'

        # RS empty sequences
        self.ds_rs.add_new('RTROIObservationsSequence', 'SQ', Sequence())
        self.ds_rs.add_new('StructureSetROISequence', 'SQ', Sequence())
        self.ds_rs.add_new('ROIContourSequence', 'SQ', Sequence())
        self.ds_rs.add_new('ReferencedFrameOfReferenceSequence', 'SQ', Sequence())

        # RS referenced frame of reference sequence
        self.add_referenced_frame_of_reference_sequence()
Exemplo n.º 12
0
 def DICOM_File_Meta_Information(ds):
     # File meta info data elements
     file_meta = FileMetaDataset()
     #     file_meta.FileMetaInformationGroupLength = 210
     #     file_meta.FileMetaInformationVersion = b'\x00\x01'
     file_meta.MediaStorageSOPClassUID = ds.SOPClassUID
     file_meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID
     file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.1'
     file_meta.ImplementationClassUID = '1.2.276.0.20.1.1.33.6.1.0'
     file_meta.ImplementationVersionName = 'PatientSelect6.1'
     file_meta.SourceApplicationEntityTitle = 'kESI'
     return file_meta
Exemplo n.º 13
0
    def setup(self):
        """Run prior to each test"""
        self.ae = None

        self.ds = Dataset()
        self.ds.file_meta = FileMetaDataset()
        self.ds.file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
        self.ds.SOPClassUID = CTImageStorage
        self.ds.SOPInstanceUID = '1.1.1'
        self.ds.PatientName = 'Test'
Exemplo n.º 14
0
    def setup(self):
        """Run prior to each test"""
        self.ae = None
        self.func = start_getscu_cli

        self.response = ds = Dataset()
        ds.file_meta = FileMetaDataset()
        ds.file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
        ds.SOPClassUID = CTImageStorage
        ds.SOPInstanceUID = "1.2.3.4"
        ds.PatientName = "Citizen^Jan"
Exemplo n.º 15
0
 def setup(self):
     """Setup the tests."""
     # Create a dataset skeleton for use in the cycle tests
     ds = Dataset()
     ds.file_meta = FileMetaDataset()
     ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
     ds.Rows = 2
     ds.Columns = 4
     ds.SamplesPerPixel = 3
     ds.PlanarConfiguration = 1
     self.ds = ds
Exemplo n.º 16
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
Exemplo n.º 17
0
    def _dicom(filename='image.dcm', **values):
        filename = str(tmpdir.join(filename))

        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, {},
                         file_meta=file_meta,
                         preamble=b'\0' * 128)
        ds.is_little_endian = True
        ds.is_implicit_VR = False

        ds.PatientName = 'Jonathan^Suever'
        ds.SeriesDescription = 'Dicom Sort Test Series'
        ds.SeriesNumber = 1

        ds.update(values)

        ds.save_as(filename)

        return filename, ds
Exemplo n.º 18
0
def _basic_file_meta(class_UID):
    """Create basic file meta for DICOM dataset."""
    # File meta info data elements
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = class_UID
    file_meta.MediaStorageSOPInstanceUID = generate_uid()
    file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
    return file_meta
Exemplo n.º 19
0
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
Exemplo n.º 20
0
def _create_temporary_dataset(shape=(100, 1024, 1024, 3), bit_depth=16):
    """Function to create a temporary dataset for use in testing.

    Parameters
    ----------
    shape : 4-tuple
        The (frames, rows, columns, channels) of the test dataset.
    bit_depth : int
        The BitsAllocated value to use for the dataset, one of 8, 16, 32, 64.

    Returns
    -------
    tempfile.TemporaryFile
        A created DICOM File Format conformant dataset.
    """
    ds = Dataset()
    ds.is_little_endian = True
    ds.is_implicit_VR = False
    ds.file_meta = FileMetaDataset()
    ds.file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
    ds.SOPClassUID = '1.2.3.4'
    ds.SOPInstanceUID = generate_uid()
    ds.BitsAllocated = bit_depth
    ds.PixelRepresentation = 0
    ds.PlanarConfiguration = 0
    ds.Rows = shape[1]
    ds.Columns = shape[2]
    ds.NumberOfFrames = shape[0]
    ds.SamplesPerPixel = shape[3]
    if shape[3] == 1:
        ds.PhotometricInterpretation = 'MONOCHROME2'
    elif shape[3] == 3:
        ds.PhotometricInterpretation = 'RGB'

    arr = np.zeros(shape, dtype='uint{}'.format(bit_depth))
    ds.PixelData = arr.tobytes()

    if len(ds.PixelData) % 2:
        ds.PixelData += b'\x00'

    tfile = TemporaryFile(mode='w+b')
    ds.save_as(tfile, write_like_original=False)
    tfile.seek(0)

    return tfile
    def handle_store(event):
        """Store the pydicom Dataset `ds`.

        Parameters
        ----------
        event : pydicom.event

        Returns
        -------
        status : int or pydicom.dataset.Dataset
            The status returned to the peer AE in the C-STORE response. Must be
            a valid C-STORE status value for the applicable Service Class as
            either an ``int`` or a ``Dataset`` object containing (at a
            minimum) a (0000,0900) *Status* element.
        """
        global scpdir
        ds = event.dataset
        context = event.context

        # logging.debug('on_c_store: info {}'.format(info))
        # calling_aet = info['requestor']['ae_title']
        # called_aet = info['acceptor']['ae_title']
        # logging.debug('on_c_store: calling_aet {}'.format(calling_aet))
        # logging.debug('on_c_store: called_aet {}'.format(called_aet))

        # Add the DICOM File Meta Information
        meta = FileMetaDataset()
        meta.MediaStorageSOPClassUID = ds.SOPClassUID
        meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID
        meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
        meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION
        meta.TransferSyntaxUID = context.transfer_syntax

        # Add the file meta to the dataset
        ds.file_meta = meta

        # Set the transfer syntax attributes of the dataset
        ds.is_little_endian = context.transfer_syntax.is_little_endian
        ds.is_implicit_VR = context.transfer_syntax.is_implicit_VR

        # Save the dataset using the SOP Instance UID as the filename
        ds.save_as(
            os.path.join(scpdir.name, ds.SOPInstanceUID),
            write_like_original=False)

        # Return a 'Success' status
        return 0x0000
Exemplo n.º 22
0
def DicomRT(path, file_name, region_number):
    file_path = path + 'Dicom/' + file_name
    dsorg = pydicom.read_file(file_path, force=True)

    dcmfiles = os.listdir(path + 'Dicom/')

    IOP = dsorg.ImageOrientationPatient
    plane = file_plane(IOP)
    planVal = dsorg.ImagePositionPatient[plane]
    planVal = float(planVal)

    xp_rt = dsorg.ImagePositionPatient[0]
    yp_rt = dsorg.ImagePositionPatient[1]

    x_rt = dsorg.Columns
    y_rt = dsorg.Rows

    uid1 = generate_uid()
    uid2 = generate_uid()
    # File meta info data elements
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationGroupLength = 182
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.3'
    file_meta.MediaStorageSOPInstanceUID = uid1  #'1.2.826.0.1.534147.578.2719282597.2020101685637449'
    file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.1'
    file_meta.ImplementationClassUID = '1.2.40.0.13.1.1'
    file_meta.ImplementationVersionName = 'dcm4che-2.0'

    ds = Dataset()

    # Main data elements
    ds = Dataset()
    ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.3'
    ds.SOPInstanceUID = uid1  #'1.2.826.0.1.534147.578.2719282597.2020101685637449'
    ds.StudyDate = dsorg.StudyDate  #'20450916'
    ds.StudyTime = dsorg.StudyTime  # '000000'
    ds.AccessionNumber = ''
    ds.Modality = 'RTSTRUCT'
    ds.Manufacturer = dsorg.Manufacturer  # 'SIEMENS'
    ds.ReferringPhysicianName = ''
    ds.OperatorsName = ''
    ds.ManufacturerModelName = dsorg.ManufacturerModelName  # SOMATOM Definition Edge'
    ds.PatientName = dsorg.PatientName  # 'Covid7175'
    ds.PatientID = dsorg.PatientID  # 'Covid7175'
    ds.PatientBirthDate = dsorg.PatientBirthDate  # '19300101'
    ds.PatientSex = dsorg.PatientSex  # 'F'
    ds.SoftwareVersions = dsorg.SoftwareVersions  # 'syngo CT VA48A'
    ds.StudyInstanceUID = dsorg.StudyInstanceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53221.0' # dsOrg.StudyInstanceUID
    ds.SeriesInstanceUID = uid2  #'1.2.826.0.1.534147.578.2719282597.2020101685637450'
    ds.StudyID = ''
    ds.SeriesNumber = None
    ds.FrameOfReferenceUID = dsorg.FrameOfReferenceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53224.0' # dsOrg.FrameOfReferenceUID
    ds.PositionReferenceIndicator = ''
    ds.StructureSetLabel = 'AIM_Multi3_' + str(
        dsorg.InstanceNumber) + '_' + str(region_number)  #Scaling04
    ds.StructureSetDate = '20201116'
    ds.StructureSetTime = '085637'

    # Referenced Frame of Reference Sequence
    refd_frame_of_ref_sequence = Sequence()
    ds.ReferencedFrameOfReferenceSequence = refd_frame_of_ref_sequence

    # Referenced Frame of Reference Sequence: Referenced Frame of Reference 1
    refd_frame_of_ref1 = Dataset()
    refd_frame_of_ref1.FrameOfReferenceUID = dsorg.FrameOfReferenceUID  # '1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53224.0'

    # RT Referenced Study Sequence
    rt_refd_study_sequence = Sequence()
    refd_frame_of_ref1.RTReferencedStudySequence = rt_refd_study_sequence

    # RT Referenced Study Sequence: RT Referenced Study 1
    rt_refd_study1 = Dataset()
    rt_refd_study1.ReferencedSOPClassUID = '1.2.840.10008.3.1.2.3.1'
    rt_refd_study1.ReferencedSOPInstanceUID = dsorg.StudyInstanceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53221.0' #

    # RT Referenced Series Sequence
    rt_refd_series_sequence = Sequence()
    rt_refd_study1.RTReferencedSeriesSequence = rt_refd_series_sequence

    # RT Referenced Series Sequence: RT Referenced Series 1
    rt_refd_series1 = Dataset()
    rt_refd_series1.SeriesInstanceUID = dsorg.SeriesInstanceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53222.0'

    # Contour Image Sequence
    contour_image_sequence = Sequence()
    rt_refd_series1.ContourImageSequence = contour_image_sequence

    # Contour Image Sequence: Contour Image 1 ********************************
    i = 0
    contour_image = []
    for dcmname in dcmfiles:
        if '.dcm' in dcmname:
            dsorg = pydicom.read_file(path + 'Dicom/' + dcmname, force=True)
            contour_image.append(Dataset())
            contour_image[i] = Dataset()
            contour_image[
                i].ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
            contour_image[
                i].ReferencedSOPInstanceUID = dsorg.SOPInstanceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53223.0'
            contour_image[i].ReferencedFrameNumber = "1"
            contour_image_sequence.append(contour_image[i])

            i = i + 1

    # contour_image1 = Dataset()
    # contour_image1.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
    # contour_image1.ReferencedSOPInstanceUID = dsorg.SOPInstanceUID #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53223.0'
    # contour_image1.ReferencedFrameNumber = "1"
    # contour_image_sequence.append(contour_image1)

    rt_refd_series_sequence.append(rt_refd_series1)
    rt_refd_study_sequence.append(rt_refd_study1)
    refd_frame_of_ref_sequence.append(refd_frame_of_ref1)

    # Structure Set ROI Sequence
    structure_set_roi_sequence = Sequence()
    ds.StructureSetROISequence = structure_set_roi_sequence

    # Structure Set ROI Sequence: Structure Set ROI 1
    structure_set_roi1 = Dataset()
    structure_set_roi1.ROINumber = "1"
    structure_set_roi1.ReferencedFrameOfReferenceUID = dsorg.FrameOfReferenceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53224.0' #
    structure_set_roi1.ROIName = 'TestScale'
    structure_set_roi1.ROIGenerationAlgorithm = ''
    structure_set_roi_sequence.append(structure_set_roi1)

    # ROI Contour Sequence
    roi_contour_sequence = Sequence()
    ds.ROIContourSequence = roi_contour_sequence

    # ROI Contour Sequence: ROI Contour 1
    roi_contour1 = Dataset()

    # Contour Sequence
    contour_sequence = Sequence()
    roi_contour1.ContourSequence = contour_sequence

    # Contour Sequence: Contour 1
    contour = []
    #dcmfiles = os.listdir(path+'Dicom/') came to beginig of the function
    i = 0
    for dcmname in dcmfiles:
        #print(dcmname)
        if '.dcm' in dcmname:
            pnyfiles = os.listdir(path + 'borders/')
            for pnyname in pnyfiles:
                if dcmname in pnyname:
                    #print(pnyname)
                    dsorg = pydicom.read_file(path + 'Dicom/' + dcmname,
                                              force=True)

                    IOP = dsorg.ImageOrientationPatient
                    plane = file_plane(IOP)
                    planVal = dsorg.ImagePositionPatient[plane]
                    planVal = float(planVal)

                    xp_rt = dsorg.ImagePositionPatient[0]
                    yp_rt = dsorg.ImagePositionPatient[1]

                    x_rt = dsorg.Columns
                    y_rt = dsorg.Rows
                    # Put Contoure pixel cordination Inside file
                    with open(path + 'Borders/' + pnyname, 'rb') as f:
                        num = np.load(f)
                    print(pnyname)
                    print(planVal)
                    borders = []
                    for t in range(len(num)):
                        #print(t,num[t])
                        if plane == 0:  #"Sagittal"
                            x = planVal
                            y = newPosition(num[t][1], 0, xp_rt, yp_rt, x_rt,
                                            y_rt)
                            z = newPosition(num[t][0], 1, xp_rt, yp_rt, x_rt,
                                            y_rt)
                        elif plane == 1:  #"Coronal"
                            x = newPosition(num[t][1], 0, xp_rt, yp_rt, x_rt,
                                            y_rt)
                            y = planVal
                            z = newPosition(num[t][0], 1, xp_rt, yp_rt, x_rt,
                                            y_rt)
                        elif plane == 2:  #  "Transverse"
                            x = newPosition(num[t][1], 0, xp_rt, yp_rt, x_rt,
                                            y_rt)
                            y = newPosition(num[t][0], 1, xp_rt, yp_rt, x_rt,
                                            y_rt)
                            z = planVal
                        borders.extend([x, y, z])

                    print(i)
                    contour.append(Dataset())
                    contour[i] = Dataset()

                    # Contour Image Sequence
                    contour_image_sequence = Sequence()
                    contour[i].ContourImageSequence = contour_image_sequence

                    # Contour Image Sequence: Contour Image 1
                    contour_image1 = Dataset()
                    contour_image1.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
                    contour_image1.ReferencedSOPInstanceUID = dsorg.SOPInstanceUID  #'1.2.826.0.1.3680043.9.3218.1.1.302475.1985.1592890895061.53223.0'
                    contour_image1.ReferencedFrameNumber = "1"
                    contour_image_sequence.append(contour_image1)

                    contour[i].ContourGeometricType = 'CLOSED_PLANAR'
                    contour[i].NumberOfContourPoints = len(borders) / 3  #"4"
                    contour[i].ContourNumber = "1"
                    contour[
                        i].ContourData = borders  # [-276.91503267973, -162.50000000000, 516.398692810457, 270.222222222222, -162.50000000000, 514.725490196078, 271.895424836601, -162.50000000000, -177.98039215686, -271.89542483660, -162.50000000000, -176.30718954248]
                    contour_sequence.append(contour[i])
                    i = i + 1

    roi_contour1.ReferencedROINumber = "1"
    roi_contour_sequence.append(roi_contour1)

    # RT ROI Observations Sequence
    rtroi_observations_sequence = Sequence()
    ds.RTROIObservationsSequence = rtroi_observations_sequence

    # RT ROI Observations Sequence: RT ROI Observations 1
    rtroi_observations1 = Dataset()
    rtroi_observations1.ObservationNumber = "1"
    rtroi_observations1.ReferencedROINumber = "1"
    rtroi_observations1.RTROIInterpretedType = ''
    rtroi_observations1.ROIInterpreter = ''
    rtroi_observations_sequence.append(rtroi_observations1)

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

    ds.save_as(path + 'RTSTRUCT/rt' + str(region_number) + '-' + file_name,
               write_like_original=False)
Exemplo n.º 23
0
def OnRest(output, uri, **request):
    config = orthancConfig
    try:
        worklistdir = config["Worklists"]["Database"]
        asnofile = os.sep.join([worklistdir, 'accessionid.conf'])
    except KeyError:
        output.AnswerBuffer('internal configuration error\n', 'text/plain')
        return

    try:
        today = datetime.today()

        try:
            with open(asnofile, 'r') as f:
                try:
                    asno = int(f.read())
                except ValueError:
                    asno = 1
        except OSError:
            asno = 1

        with open(asnofile, 'w') as f:
            f.write(str(asno + 1))

        # File meta info data elements
        file_meta = FileMetaDataset()
        file_meta.FileMetaInformationGroupLength = 202
        file_meta.FileMetaInformationVersion = b'\x00\x01'
        file_meta.MediaStorageSOPClassUID = '1.2.276.0.7230010.3.1.0.1'
        file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid(
            prefix=None)
        file_meta.TransferSyntaxUID = '1.2.840.10008.1.2.1'
        file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.1.0.0'
        file_meta.ImplementationVersionName = 'ORTHANC_RESTWORKLIST_1'

        # Main data elements
        ds = Dataset()
        ds.SpecificCharacterSet = 'ISO_IR 192'

        dcm_store_path = os.sep.join([
            worklistdir,
            'R{:010d}-{}.{}'.format(asno, today.strftime('%Y%m%d%H%M%S'), 'wl')
        ])
        ds.AccessionNumber = 'R{:010d}'.format(asno)
        try:
            ds.PatientName = '{}^{}'.format(request["get"]["lastname"],
                                            request["get"]["firstname"])
        except KeyError:
            ds.PatientName = '{}^{}'.format(
                request["get"]["name"], request["get"]["surname"]
            )  # old, buggy parameter naming -> for backwards compatibility
        ds.PatientID = request["get"]["id"]
        bdparts = request["get"]["birthdate"].split('.')
        ds.PatientBirthDate = '{2}{1}{0}'.format(*bdparts)
        ds.PatientSex = sexReplacement[request["get"][
            "sex"]]  # LUT for the sex identifier numbers used by Medical Office (0 = Other / Unknown, 1 = Male, 2 = Female, 3 = Other / Unknown)
        ds.StudyInstanceUID = pydicom.uid.generate_uid(prefix=None)
        try:
            ds.RequestedProcedureDescription = request["get"]["procedure"]
        except KeyError:
            pass  # optional argument, otherwise this tag remains empty

        # Scheduled Procedure Step Sequence
        scheduled_procedure_step_sequence = Sequence()
        ds.ScheduledProcedureStepSequence = scheduled_procedure_step_sequence

        # Scheduled Procedure Step Sequence: Scheduled Procedure Step 1
        scheduled_procedure_step1 = Dataset()
        try:
            scheduled_procedure_step1.Modality = request["get"]["modality"]
        except KeyError:
            scheduled_procedure_step1.Modality = 'US'  # fallback to default (backwards compatibility)

        try:
            scheduled_procedure_step1.ScheduledStationAETitle = request["get"][
                "scheduledStation"]
        except KeyError:
            scheduled_procedure_step1.ScheduledStationAETitle = 'US01'  # fallback to default (backwards compatibility)

        scheduled_procedure_step1.ScheduledProcedureStepStartDate = today.strftime(
            '%Y%m%d')
        scheduled_procedure_step1.ScheduledProcedureStepStartTime = today.strftime(
            '%H%M%S')

        try:
            scheduled_procedure_step1.ScheduledPerformingPhysicianName = request[
                "get"]["physician"]
        except KeyError:
            pass  # optional, leave empty if not specified

        scheduled_procedure_step_sequence.append(scheduled_procedure_step1)

        ds.file_meta = file_meta
        ds.is_implicit_VR = False
        ds.is_little_endian = True
        ds.save_as(dcm_store_path, write_like_original=False)
        output.AnswerBuffer(
            gdtResponse(request["get"]["id"], today, ds.AccessionNumber,
                        request["get"]["procedure"]), 'text/plain')

        if "UrlOnWorklistEntryAdded" in config["Worklists"]:
            with urllib.request.urlopen(
                    config["Worklists"]["UrlOnWorklistEntryAdded"]):
                orthanc.LogWarning("Called {} as configured.".format(
                    config["Worklists"]["UrlOnWorklistEntryAdded"]))
    except KeyError as e:
        output.AnswerBuffer('error: {}\n'.format(e), 'text/plain')
        raise
Exemplo n.º 24
0
import os
import tempfile
import datetime

import pydicom
from pydicom.dataset import Dataset, FileDataset, FileMetaDataset

# 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 = 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"

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"
Exemplo n.º 25
0
def generate_dicom_sr(file_path, img_ds, data, series_description):
    """
    Generates DICOM Structured Report files for the given file path.
    :param file_path: the file name and directory to save the DICOM
                      SR file in.
    :param img_ds: A CT or MR image from the dataset used to pull
                   general information for the DICOM SR.
    :param data: Text data to be written to the DICOM SR file.
    :param series_description: Description of text data written to SR.
    :return: dicom_sr, a dataset for the new DICOM SR file.
    """
    if img_ds is None:
        raise ValueError("No CT data to initialize RT SS")

    # Create file meta
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationGroupLength = 238
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.88.33'
    file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()
    file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
    validate_file_meta(file_meta)

    # Create dataset
    dicom_sr = pydicom.dataset.FileDataset(file_path, {},
                                           preamble=b"\0" * 128,
                                           file_meta=file_meta)
    dicom_sr.fix_meta_info()

    # Get current date and time
    now = datetime.datetime.now()
    dicom_date = now.strftime("%Y%m%d")
    dicom_time = now.strftime("%H%M")

    # List of tags to copy from CT/MR image
    top_level_tags_to_copy: list = [
        Tag("PatientName"),
        Tag("PatientID"),
        Tag("PatientBirthDate"),
        Tag("PatientSex"),
        Tag("StudyDate"),
        Tag("StudyTime"),
        Tag("ReferringPhysicianName"),
        Tag("StudyDescription"),
        Tag("StudyInstanceUID"),
        Tag("StudyID"),
        Tag("RequestingService"),
        Tag("PatientAge"),
        Tag("PatientSize"),
        Tag("PatientWeight"),
        Tag("MedicalAlerts"),
        Tag("Allergies"),
        Tag("PregnancyStatus"),
        Tag("InstitutionName"),
        Tag("InstitutionAddress")
    ]

    # Copy tags from CT/MR image
    for tag in top_level_tags_to_copy:
        if tag in img_ds:
            dicom_sr[tag] = deepcopy(img_ds[tag])

    dicom_sr.AccessionNumber = ""

    # == SR Document Series Module
    dicom_sr.SeriesDate = dicom_date
    dicom_sr.SeriesTime = dicom_time
    dicom_sr.Modality = "SR"
    dicom_sr.SeriesDescription = series_description
    # Can be empty
    referenced_performed_procedure_step_sequence = Sequence()
    dicom_sr.ReferencedPerformedProcedureStepSequence = \
        referenced_performed_procedure_step_sequence
    dicom_sr.SeriesInstanceUID = pydicom.uid.generate_uid()
    dicom_sr.SeriesNumber = 1

    # == General Equipment Module
    dicom_sr.Manufacturer = "OnkoDICOM"
    dicom_sr.ManufacturersModelName = "OnkoDICOM"
    # TODO: Pull this off build information in some way
    dicom_sr.SoftwareVersions = "2021"

    # == SR Document General Module
    dicom_sr.ContentDate = dicom_date
    dicom_sr.ContentTime = dicom_time

    dicom_sr.InstanceNumber = 1

    # Empty if unknown
    performed_procedure_code_sequence = Sequence()

    dicom_sr.PerformedProcedureCodeSequence = performed_procedure_code_sequence

    # Do not want to mark as complete in case it isn't!
    dicom_sr.CompletionFlag = "PARTIAL"
    dicom_sr.VerificationFlag = "UNVERIFIED"

    # == SR Document Content Module
    referenced_sop_sequence = Sequence([Dataset()])
    referenced_sop_sequence[0].ReferencedSOPClassUID = ''
    referenced_sop_sequence[0].ReferencedSOPInstanceUID = ''

    dicom_sr.ReferencedSOPSequence = referenced_sop_sequence
    dicom_sr.ValueType = "CONTAINER"

    dicom_sr.ContinuityOfContent = "CONTINUOUS"
    dicom_sr.TemporalRangeTime = ""
    dicom_sr.ReferencedTimeOffsets = ""
    dicom_sr.ReferencedDateTime = ""

    dicom_sr.MeasuredValueSequence = Sequence()
    og_frame_of_reference_UID = \
        deepcopy(img_ds[Tag("FrameOfReferenceUID")].value)
    dicom_sr.ReferencedFrameOfReferenceUID = og_frame_of_reference_UID

    # == Content Sequence
    content_sequence = Sequence([Dataset()])
    content_sequence[0].RelationshipType = 'CONTAINS'
    content_sequence[0].ValueType = 'TEXT'

    concept_name_code_sequence = Sequence([Dataset()])
    concept_name_code_sequence[0].CodeValue = ''
    concept_name_code_sequence[0].CodingSchemeDesignator = ''
    concept_name_code_sequence[0].CodeMeaning = ''
    content_sequence[0].ConceptNameCodeSequence = concept_name_code_sequence

    content_sequence[0].TextValue = data

    dicom_sr.ContentSequence = content_sequence

    # == SOP Common Module
    dicom_sr.SOPClassUID = '1.2.840.10008.5.1.4.1.1.88.33'
    dicom_sr.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID

    dicom_sr.is_little_endian = True
    dicom_sr.is_implicit_VR = True

    return dicom_sr
Exemplo n.º 26
0
    def anonymizeDicom(self, dcm, dict_study):
        '''
        Anonymize a dicom by pre-defined rules
        dcm: loaded dicom file to anonymize
        dict: additional information obtained outside the dicom, such as exam_id, series_id from directory
        return an anonymized dicom by creating a new one
        '''
        #         suffix = '.dcm'
        #         filename_little_endian = tempfile.NamedTemporaryFile(suffix=suffix).name
        #         print(dcm.file_meta)
        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"
        #         anonyDcmObj = pydicom.dataset.Dataset()
        anonyDcmObj = FileDataset([], {},
                                  file_meta=file_meta,
                                  preamble=b"\0" * 128)
        #         print(anonyDcmObj.file_meta)
        #         FileDataset(filename_little_endian, {},
        #                  file_meta=file_meta, preamble=b"\0" * 128)

        # copy pixel_array
        arr = dcm.pixel_array
        anonyDcmObj.PixelData = arr.tobytes()

        # set the required fields
        anonyDcmObj.preamble = dcm.preamble

        anonyDcmObj.file_meta = file_meta  #dcm.file_meta
        anonyDcmObj.is_little_endian = dcm.is_little_endian
        anonyDcmObj.is_implicit_VR = dcm.is_implicit_VR

        # Test
        #anonyDcmObj.file_meta.MediaStorageSOPClassUID = []

        for sTag in self.tagsHandler:

            vr = self.lookupTable["dictionary_vr"][sTag]
            tag = self.str2tag(sTag)

            if self.tagsHandler[sTag]["method"] == "keep":
                if tag in dcm:
                    elem = dcm[tag]
                    anonyDcmObj.add(elem)
                elif tag in dcm.file_meta:
                    elem = dcm.file_meta[tag]
                    #                     setattr(anonyDcmObj.file_meta, tag, elem)
                    anonyDcmObj.file_meta.add(elem)
                    # because file_meta has already been copied
                    pass
            elif self.tagsHandler[sTag]["method"] == "const":
                if tag in dcm or tag in dcm.file_meta:
                    if tag in dcm:
                        elem = dcm[tag]
                        elem.value = self.tagsHandler[sTag]["value"]
                        anonyDcmObj.add(elem)
                    else:
                        elem = dcm.file_meta[tag]
                        elem.value = self.tagsHandler[sTag]["value"]
                        #                         setattr(anonyDcmObj.file_meta, tag, elem.value)
                        anonyDcmObj.file_meta.add(elem)
                        # The tag belongs to file_meta
#                         anonyDcmObj.file_meta[tag].value = self.tagsHandler[sTag]["value"]

            elif self.tagsHandler[sTag]["method"] == "lookup":
                if tag in dcm:
                    tagName = self.lookupTable["Tag2Name"][str(tag).replace(
                        " ", "")]
                    elem = dcm[tag]
                    if tagName == 'PatientName':
                        tagVal = 'Lrm_' + str(
                            dcm[tag].value).split('_')[1] + '_assess'
                    else:
                        tagVal = str(dcm[tag].value)
                    elem.value = self.lookupTable[tagName][tagVal]
                    anonyDcmObj.add(elem)
            elif self.tagsHandler[sTag]["method"] == "less_than":
                if tag in dcm:
                    sVal = dcm[tag].value
                    iVal = int(self.extractDigits(sVal))
                    maxVal = int(self.tagsHandler[sTag]["value"])
                    if iVal > maxVal:
                        modifiedVal = maxVal
                    else:
                        modifiedVal = iVal
                    elem = dcm[tag]
                    elem.value = "{:03d}Y".format(modifiedVal)
                    anonyDcmObj.add(elem)

            elif self.tagsHandler[sTag]["method"] == "random":

                if tag in dcm or tag in dcm.file_meta:

                    if self.tagsHandler[sTag][
                            "tagID"] == "0020,000e":  #SeriesInstanceUID
                        rand_str = '.'.join([
                            dict_study['rand_6_SeriesInstanceUID'],
                            dict_study['rand_5_SeriesInstanceUID'], '2.1.1',
                            dict_study['rand_tail_SeriesInstanceUID']
                        ])
                    elif self.tagsHandler[sTag][
                            "tagID"] == "0008,0018":  #SOPInstanceUID
                        rand_str = '.'.join([
                            dict_study['rand_6_SOPInstanceUID'],
                            dict_study['rand_5_SOPInstanceUID'], '2.1.3',
                            dict_study['rand_tail_SOPInstanceUID']
                        ])
                    elif self.tagsHandler[sTag][
                            "tagID"] == "0020,000d":  #StudyInstanceUID
                        rand_str = '.'.join([
                            dict_study['rand_6_StudyInstanceUID'],
                            dict_study['rand_5_StudyInstanceUID'], '2.1.1',
                            dict_study['rand_tail_StudyInstanceUID']
                        ])
                    elif self.tagsHandler[sTag][
                            "tagID"] == "0002,0003":  #MediaStorageSOPInstanceUID
                        rand_str = '.'.join([
                            dict_study['rand_6_MediaStorageSOPInstanceUID'],
                            dict_study['rand_5_MediaStorageSOPInstanceUID'],
                            '2.1.3',
                            dict_study['rand_tail_MediaStorageSOPInstanceUID']
                        ])

                    if tag in dcm:
                        elem = dcm[tag]
                        elem.value = rand_str
                        anonyDcmObj.add(elem)
                    elif tag in dcm.file_meta:
                        elem = dcm.file_meta[tag]
                        elem.value = rand_str
                        anonyDcmObj.file_meta.add(elem)

            else:
                raise NameError('Unknown Method')
        return anonyDcmObj
Exemplo n.º 27
0
  else:
    endIndex = len(seriesDCM) - z - 1
    break

smask = np.zeros((seg_mask.shape[0], seg_mask.shape[1], endIndex-startIndex+1))
for z in range(startIndex, endIndex + 1):
  for r in range(seg_mask.shape[0]):
    for c in range(seg_mask.shape[1]):
      smask[r][c][z - startIndex] = seg_mask[r][c][z]

print("Seg_mask array created")

stop = timeit.default_timer()
print("Runtime (mask creation): " + str(stop-start) + "s")

file_meta = FileMetaDataset()

file_meta.MediaStorageSOPClassUID='1.2.840.10008.5.1.4.1.1.66.4'
dicomuid = generate_uid()
instanceuid=dicomuid
file_meta.MediaStorageSOPInstanceUID=instanceuid
file_meta.TransferSyntaxUID=ExplicitVRLittleEndian
file_meta.ImplementationClassUID='1.2.840.10008.5.1.4.1.1.66.4'
file_meta.ImplementationVersionName='ePAD_matlab_1.0'

suffix = '.dcm'
info = seriesDCM[0]
info_mask = FileDataset('output/' + str(name) + str(suffix), {},
                  file_meta=file_meta, preamble=b"\0" * 128)
info_mask.StudyDescription=info.StudyDescription
info_mask.is_little_endian = False
Exemplo n.º 28
0
def create_file_meta(
    *,
    sop_class_uid: UID,
    sop_instance_uid: UID,
    transfer_syntax: UID,
    implementation_uid: UID = PYNETDICOM_IMPLEMENTATION_UID,
    implementation_version: str = PYNETDICOM_IMPLEMENTATION_VERSION,
) -> FileMetaDataset:
    """Return a new file meta dataset

    .. versionadded:: 2.0

    Parameters
    ----------
    sop_class_uid : pydicom.uid.UID
        The value for the *Media Storage SOP Class UID*.
    sop_instance_uid : pydicom.uid.UID
        The value for the *Media Storage SOP Instance UID*.
    transfer_syntax : pydicom.uid.UID
        The value for the *Transfer Syntax UID*.
    implementation_uid : pydicom.uid.UID, optional
        The value for the *Implementation Class UID*.
    implementation_version : str, optional
        The value for the *Implementation Version Name*.

    Returns
    -------
    pydicom.dataset.FileMetaDataset
        The File Meta dataset
    """
    file_meta = FileMetaDataset()

    file_meta.FileMetaInformationGroupLength = 0
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = sop_class_uid
    file_meta.MediaStorageSOPInstanceUID = sop_instance_uid
    file_meta.TransferSyntaxUID = transfer_syntax
    file_meta.ImplementationClassUID = implementation_uid
    file_meta.ImplementationVersionName = implementation_version

    # File Meta Information is always encoded as Explicit VR Little Endian
    file_meta.is_little_endian = True
    file_meta.is_implicit_VR = False

    return file_meta
Exemplo n.º 29
0
def write_file_meta_info(fp: DicomIO,
                         file_meta: FileMetaDataset,
                         enforce_standard: bool = True) -> None:
    """Write the File Meta Information elements in `file_meta` to `fp`.

    If `enforce_standard` is ``True`` then the file-like `fp` should be
    positioned past the 128 byte preamble + 4 byte prefix (which should
    already have been written).

    **DICOM File Meta Information Group Elements**

    From the DICOM standard, Part 10,
    :dcm:`Section 7.1<part10/chapter_7.html#sect_7.1>`,  any DICOM file shall
    contain a 128-byte preamble, a 4-byte DICOM prefix 'DICM' and (at a
    minimum) the following Type 1 DICOM Elements (from
    :dcm:`Table 7.1-1<part10/chapter_7.html#table_7.1-1>`):

    * (0002,0000) *File Meta Information Group Length*, UL, 4
    * (0002,0001) *File Meta Information Version*, OB, 2
    * (0002,0002) *Media Storage SOP Class UID*, UI, N
    * (0002,0003) *Media Storage SOP Instance UID*, UI, N
    * (0002,0010) *Transfer Syntax UID*, UI, N
    * (0002,0012) *Implementation Class UID*, UI, N

    If `enforce_standard` is ``True`` then (0002,0000) will be added/updated,
    (0002,0001) and (0002,0012) will be added if not already present and the
    other required elements will be checked to see if they exist. If
    `enforce_standard` is ``False`` then `file_meta` will be written as is
    after minimal validation checking.

    The following Type 3/1C Elements may also be present:

    * (0002,0013) *Implementation Version Name*, SH, N
    * (0002,0016) *Source Application Entity Title*, AE, N
    * (0002,0017) *Sending Application Entity Title*, AE, N
    * (0002,0018) *Receiving Application Entity Title*, AE, N
    * (0002,0102) *Private Information*, OB, N
    * (0002,0100) *Private Information Creator UID*, UI, N

    If `enforce_standard` is ``True`` then (0002,0013) will be added/updated.

    *Encoding*

    The encoding of the *File Meta Information* shall be *Explicit VR Little
    Endian*.

    Parameters
    ----------
    fp : file-like
        The file-like to write the File Meta Information to.
    file_meta : pydicom.dataset.Dataset
        The File Meta Information elements.
    enforce_standard : bool
        If ``False``, then only the *File Meta Information* elements already in
        `file_meta` will be written to `fp`. If ``True`` (default) then a DICOM
        Standards conformant File Meta will be written to `fp`.

    Raises
    ------
    ValueError
        If `enforce_standard` is ``True`` and any of the required *File Meta
        Information* elements are missing from `file_meta`, with the
        exception of (0002,0000), (0002,0001) and (0002,0012).
    ValueError
        If any non-Group 2 Elements are present in `file_meta`.
    """
    validate_file_meta(file_meta, enforce_standard)

    if enforce_standard and 'FileMetaInformationGroupLength' not in file_meta:
        # Will be updated with the actual length later
        file_meta.FileMetaInformationGroupLength = 0

    # Write the File Meta Information Group elements
    # first write into a buffer to avoid seeking back, that can be
    # expansive and is not allowed if writing into a zip file
    buffer = DicomBytesIO()
    buffer.is_little_endian = True
    buffer.is_implicit_VR = False
    write_dataset(buffer, file_meta)

    # If FileMetaInformationGroupLength is present it will be the first written
    #   element and we must update its value to the correct length.
    if 'FileMetaInformationGroupLength' in file_meta:
        # Update the FileMetaInformationGroupLength value, which is the number
        #   of bytes from the end of the FileMetaInformationGroupLength element
        #   to the end of all the File Meta Information elements.
        # FileMetaInformationGroupLength has a VR of 'UL' and so has a value
        #   that is 4 bytes fixed. The total length of when encoded as
        #   Explicit VR must therefore be 12 bytes.
        file_meta.FileMetaInformationGroupLength = buffer.tell() - 12
        buffer.seek(0)
        write_data_element(buffer, file_meta[0x00020000])

    fp.write(buffer.getvalue())
Exemplo n.º 30
0
def create_initial_rtss_from_ct(img_ds: pydicom.dataset.Dataset,
                                filepath: Path,
                                uid_list: list) -> pydicom.dataset.FileDataset:
    """
    Pre-populate an RT Structure Set based on a single CT (or MR) and a
    list of image UIDs The caller should update the Structure Set Label,
    Name, and Description, which are set to "OnkoDICOM" plus the StudyID
    from the CT, and must add Structure Set ROI Sequence, ROI Contour
    Sequence, and RT ROI Observations Sequence
    Parameters
    ----------
    img_ds : pydicom.dataset.Dataset
        A CT or MR image that the RT Structure Set will be "drawn" on
    uid_list : list
        list of UIDs (as strings) of the entire image volume that the
        RT SS references
    filepath: str
        A path where the RTStruct will be saved
    Returns
    -------
    pydicom.dataset.FileDataset
        the half-baked RT SS, ready for Structure Set ROI Sequence,
        ROI Contour Sequence, and RT ROI Observations Sequence
    Raises
    ------
    ValueError
        [description]
    """

    if img_ds is None:
        raise ValueError("No CT data to initialize RT SS")

    now = datetime.datetime.now()
    dicom_date = now.strftime("%Y%m%d")
    dicom_time = now.strftime("%H%M")

    # File Meta module
    file_meta = FileMetaDataset()
    file_meta.FileMetaInformationGroupLength = 238
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.3'
    file_meta.MediaStorageSOPInstanceUID = generate_uid()
    file_meta.TransferSyntaxUID = ImplicitVRLittleEndian
    validate_file_meta(file_meta)

    rt_ss = pydicom.dataset.FileDataset(filepath, {},
                                        preamble=b"\0" * 128,
                                        file_meta=file_meta)
    rt_ss.fix_meta_info()

    top_level_tags_to_copy: list = [
        Tag("PatientName"),
        Tag("PatientID"),
        Tag("PatientBirthDate"),
        Tag("PatientSex"),
        Tag("StudyDate"),
        Tag("StudyTime"),
        Tag("AccessionNumber"),
        Tag("ReferringPhysicianName"),
        Tag("StudyDescription"),
        Tag("StudyInstanceUID"),
        Tag("StudyID"),
        Tag("RequestingService"),
        Tag("PatientAge"),
        Tag("PatientSize"),
        Tag("PatientWeight"),
        Tag("MedicalAlerts"),
        Tag("Allergies"),
        Tag("PregnancyStatus"),
        Tag("FrameOfReferenceUID"),
        Tag("PositionReferenceIndicator"),
        Tag("InstitutionName"),
        Tag("InstitutionAddress"),
        Tag("OperatorsName")
    ]

    for tag in top_level_tags_to_copy:
        if tag in img_ds:
            rt_ss[tag] = deepcopy(img_ds[tag])

    if rt_ss.StudyInstanceUID == "":
        raise ValueError(
            "The given dataset is missing a required tag 'StudyInstanceUID'")

    # RT Series Module
    rt_ss.SeriesDate = dicom_date
    rt_ss.SeriesTime = dicom_time
    rt_ss.Modality = "RTSTRUCT"
    rt_ss.OperatorsName = ""
    rt_ss.SeriesInstanceUID = pydicom.uid.generate_uid()
    rt_ss.SeriesNumber = "1"

    # General Equipment Module
    rt_ss.Manufacturer = "OnkoDICOM"
    rt_ss.ManufacturerModelName = "OnkoDICOM"
    # TODO: Pull this off build information in some way
    rt_ss.SoftwareVersions = "2021"

    # Frame of Reference module
    rt_ss.FrameOfReferenceUID = img_ds.FrameOfReferenceUID
    rt_ss.PositionReferenceIndicator = ""

    # Structure Set module
    # Best to modify the Structure Set Label with something more
    # interesting in the application. and populate the Name and
    # Description from the application also.
    rt_ss.StructureSetLabel = "OnkoDICOM rtss"
    rt_ss.StructureSetName = rt_ss.StructureSetLabel
    rt_ss.StructureSetDescription = "OnkoDICOM rtss of " + rt_ss.StudyID
    rt_ss.StructureSetDate = dicom_date
    rt_ss.StructureSetTime = dicom_time

    # Contour Image Sequence
    contour_image_sequence = []
    for uid in uid_list:
        contour_image_sequence_item = pydicom.dataset.Dataset()
        contour_image_sequence_item.ReferencedSOPClassUID = img_ds.SOPClassUID
        contour_image_sequence_item.ReferencedSOPInstanceUID = uid
        contour_image_sequence.append(contour_image_sequence_item)

    # RT Referenced Series Sequence
    rt_referenced_series = pydicom.dataset.Dataset()
    rt_referenced_series.SeriesInstanceUID = img_ds.SeriesInstanceUID
    rt_referenced_series.ContourImageSequence = contour_image_sequence
    rt_referenced_series_sequence = [rt_referenced_series]

    # RT Referenced Study Sequence
    rt_referenced_study = pydicom.dataset.Dataset()
    rt_referenced_study.ReferencedSOPClassUID = "1.2.840.10008.3.1.2.3.1"
    rt_referenced_study.ReferencedSOPInstanceUID = img_ds.StudyInstanceUID
    rt_referenced_study.RTReferencedSeriesSequence = \
        rt_referenced_series_sequence
    rt_referenced_study_sequence = [rt_referenced_study]

    # RT Referenced Frame Of Reference Sequence, Structure Set Module
    referenced_frame_of_reference = pydicom.dataset.Dataset()
    referenced_frame_of_reference.FrameOfReferenceUID = \
        img_ds.FrameOfReferenceUID
    referenced_frame_of_reference.RTReferencedStudySequence = \
        rt_referenced_study_sequence
    rt_ss.ReferencedFrameOfReferenceSequence = [referenced_frame_of_reference]

    # Sequence modules
    rt_ss.StructureSetROISequence = []
    rt_ss.ROIContourSequence = []
    rt_ss.RTROIObservationsSequence = []

    # SOP Common module
    rt_ss.SOPClassUID = rt_ss.file_meta.MediaStorageSOPClassUID
    rt_ss.SOPInstanceUID = rt_ss.file_meta.MediaStorageSOPInstanceUID

    # Add required elements
    rt_ss.InstanceCreationDate = dicom_date
    rt_ss.InstanceCreationTime = dicom_time

    rt_ss.is_little_endian = True
    rt_ss.is_implicit_VR = True
    return rt_ss