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
Exemple #2
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
Exemple #3
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
    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
Exemple #5
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
Exemple #6
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
    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
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
Exemple #8
0
      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
info_mask.is_explicit_VR = False

if 'ImageOrientationPatient' in info:
  ds = Dataset()
  ds2 = Dataset()
  ds2.ImageOrientationPatient = info.ImageOrientationPatient
  ds.SliceThickness = info.SliceThickness
  ds.PixelSpacing = info.PixelSpacing
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)
Exemple #10
0
    def generate_dicom(self, file_out_name: str, gantry_angle: float = 0.0, coll_angle: float = 0.0,
                       table_angle: float = 0.0):
        file_meta = FileMetaDataset()
        file_meta.FileMetaInformationGroupLength = 196
        file_meta.FileMetaInformationVersion = b'\x00\x01'
        file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.1'
        file_meta.MediaStorageSOPInstanceUID = '1.2.246.352.64.1.5468686515961995030.4457606667843517571'
        file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
        file_meta.ImplementationClassUID = '1.2.246.352.70.2.1.120.1'
        file_meta.ImplementationVersionName = 'MergeCOM3_410'

        # Main data elements
        ds = Dataset()
        ds.SpecificCharacterSet = 'ISO_IR 100'
        ds.ImageType = ['ORIGINAL', 'PRIMARY', 'PORTAL']
        ds.InstanceCreationDate = '20161230'
        ds.InstanceCreationTime = '215510'
        ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.1'
        ds.SOPInstanceUID = '1.2.246.352.64.1.5468686515961995030.4457606667843517571'
        ds.StudyDate = '20161230'
        ds.ContentDate = '20161230'
        ds.StudyTime = '215441.936'
        ds.ContentTime = '215441.936'
        ds.AccessionNumber = ''
        ds.Modality = 'RTIMAGE'
        ds.ConversionType = ''
        ds.Manufacturer = 'Varian Medical Systems'
        ds.ReferringPhysicianName = ''
        ds.StationName = 'NDS-WKS-SN9999'
        ds.OperatorsName = 'King Kong'
        ds.ManufacturerModelName = 'VMS.XI.Service'
        ds.PatientName = 'Grace Hopper'
        ds.PatientID = 'VMS.XI.Service'
        ds.PatientBirthDate = '19000101'
        ds.PatientBirthTime = '000000'
        ds.PatientSex = ''
        ds.SoftwareVersions = '2.5.13.2'
        ds.StudyInstanceUID = '1.2.246.352.64.4.5644626269434644263.1905029945372990626'
        ds.SeriesInstanceUID = '1.2.246.352.64.2.5508761605912087323.11665958260371685307'
        ds.StudyID = 'fdd794f2-8520-4c4a-aecc-e4446c1730ff'
        ds.SeriesNumber = None
        ds.AcquisitionNumber = "739774555"
        ds.InstanceNumber = "1"
        ds.PatientOrientation = ''
        ds.FrameOfReferenceUID = '1.2.246.352.64.3.4714322356925391886.9391210174715030407'
        ds.PositionReferenceIndicator = ''
        ds.SamplesPerPixel = 1
        ds.PhotometricInterpretation = 'MONOCHROME1'
        ds.PlanarConfiguration = 0
        ds.Rows = self.shape[0]
        ds.Columns = self.shape[1]
        ds.BitsAllocated = 16
        ds.BitsStored = 16
        ds.HighBit = 15
        ds.PixelRepresentation = 0
        ds.WindowCenter = "32767.0"
        ds.WindowWidth = "65535.0"
        ds.RescaleIntercept = "0.0"
        ds.RescaleSlope = "1.0"
        ds.RescaleType = 'US'
        ds.RTImageLabel = 'MV_180'
        ds.RTImageDescription = ""
        ds.ReportedValuesOrigin = 'ACTUAL'
        ds.RTImagePlane = 'NORMAL'
        ds.XRayImageReceptorTranslation = [0.00, 0.00, 1000 - self.sid]
        ds.XRayImageReceptorAngle = "0.0"
        ds.RTImageOrientation = [1, 0, 0, 0, -1, 0]
        ds.ImagePlanePixelSpacing = [self.pixel_size, self.pixel_size]
        ds.RTImagePosition = [-214.872, 214.872]
        ds.RadiationMachineName = 'TrueBeam from Hell'
        ds.RadiationMachineSAD = "1000.0"
        ds.RTImageSID = self.sid
        ds.PrimaryDosimeterUnit = 'MU'
        ds.GantryAngle = str(gantry_angle)
        ds.BeamLimitingDeviceAngle = str(coll_angle)
        ds.PatientSupportAngle = str(table_angle)
        ds.TableTopVerticalPosition = "-24.59382842824"
        ds.TableTopLongitudinalPosition = "200.813502948597"
        ds.TableTopLateralPosition = "3.00246706215532"
        ds.PixelData = self.image  # XXX Array of 3276800 bytes excluded

        ds.file_meta = file_meta
        ds.is_implicit_VR = True
        ds.is_little_endian = True
        ds.save_as(file_out_name, write_like_original=False)