예제 #1
0
    def find_study_by_patient_id_and_accession_number(self, patient_id,
                                                      accession_number):
        studies = []
        assoc = self._setup_c_find_assoc()
        if assoc.is_established:
            ds = Dataset()
            ds.PatientID = patient_id
            ds.StudyInstanceUID = ''
            ds.StudyDate = ''
            ds.StudyTime = ''
            if len(accession_number):
                ds.AccessionNumber = accession_number
            ds.QueryRetrieveLevel = "STUDY"
            response = assoc.send_c_find(ds, query_model='S')
            for (status, identifier) in response:
                if status.get(0x00000900).value == 65280:
                    studies.append(identifier)
                    # studies.append(identifier.get_item(0x0020000D).value)

            assoc.release()
            if len(studies) == 0:
                logger.info("can't find studies with search conditions")
            else:
                latest_study_date = studies[0].get_item(0x00080020).value
                latest_study_uid = studies[0].get_item(0x0020000D).value
                for study in studies:
                    if study.get_item(0x00080020).value > latest_study_date:
                        latest_study_uid = study.get_item(0x0020000D).value
        else:
            logger.error("find_studies_by_patient_id association failed")
        return latest_study_uid
예제 #2
0
    def get_clean_worklist(self):
        """ Generates a clean worklist """

        worklist_item = Dataset()
        worklist_item.StudyInstanceUID = generate_uid(prefix='1.2.840.113619.2.391.6789.', entropy_srcs=[_create_random_ascii_string(10), _create_random_ascii_string(10)])
        worklist_item.Modality = 'US'
        worklist_item.SpecificCharacterSet = self._specific_charset
        worklist_item.AccessionNumber = '123'
        worklist_item.PatientBirthDate = '19901015'
        worklist_item.PatientName = 'Clean^Exam'
        worklist_item.PatientID = _create_random_ascii_string(64)
        worklist_item.IssuerOfPatientID = 'Issuer of patient id: Bob'
        worklist_item.PatientWeight = str(100.0)
        worklist_item.PatientSize = str(2.1)
        worklist_item.AdmissionID = 'Admission id 3'
        worklist_item.RequestedProcedureID = 'Step id 2'
        worklist_item.RequestedProcedureDescription = 'Step description Clean Exam'

        otherPatientIdsSq = [Dataset(), Dataset()]
        for otherPatientId in otherPatientIdsSq:
            otherPatientId.PatientID = 'Bob123'
            otherPatientId.IssuerOfPatientID = 'Issuer of patient id: Arne'
            otherPatientId.TypeOfPatientID = 'TEXT'

        worklist_item.OtherPatientIDsSequence = otherPatientIdsSq

        step = Dataset()
        step.ScheduledPerformingPhysicianName = 'Ola Nordmann'
        step.ScheduledProcedureStepStartDate = '20201224'
        step.ScheduledProcedureStepStartTime = '121212'
        step.ScheduledProcedureStepDescription = 'Scheduled procedure step description '
        step.CommentsOnTheScheduledProcedureStep = 'Scheduled step comments '
        worklist_item.ScheduledProcedureStepSequence = [step]

        return worklist_item
예제 #3
0
def get_basedataset():
    ds = Dataset()
    ds.PatientName = ''
    ds.PatientID = ''
    ds.StudyInstanceUID = ''
    ds.SeriesUID = ''
    ds.AccessionNumber = ''
    ds.QueryRetrieveLevel = ''
    ds.PatientSize = ''
    ds.ModalitiesInStudy = ''
    ds.SOPClassesInStudy = ''
    ds.StudyDescription = '*'
    ds.SeriesDescription = ''
    ds.FailedSOPSequence = ''
    ds.DerivationCodeSequence = ''
    ds.PatientSpeciesCodeSequence = ''
    ds.Series = ''
    ds.TransferSyntaxUID = ''
    ds.SeriesInStudy = ''
    ds.SeriesNumber = ''
    ds.ImagesInSeries = ''
    ds.SeriesInstanceUID = ''
    ds.NumberOfSeriesRelatedInstances = ''
    ds.StudyDate = ''

    return ds
예제 #4
0
def query_study(localAE, localPort, destIP, destAE, destPort, patientID,
                accessionNumber, studyInstanceUID, moodality, studyDateStart,
                studyDateEnd):
    # Prepare local information
    ae = AE(ae_title=localAE)
    ae.acse_timeout = 30

    # Add a requested presentation context
    ae.add_requested_context(StudyRootQueryRetrieveInformationModelFind)

    # Create local Identifier dataset
    ds = Dataset()
    ds.PatientName = ''
    ds.PatientID = patientID
    ds.StudyInstanceUID = studyInstanceUID
    ds.AccessionNumber = accessionNumber
    ds.Modality = moodality
    ds.StudyDate = studyDateStart + '-' + studyDateEnd
    ds.QueryRetrieveLevel = 'STUDY'

    # Associate with Peer
    assoc = ae.associate(destIP, destPort, ae_title=destAE)

    # Result list
    studyList = []

    if assoc.is_established:
        # Find information from Peer
        responses = assoc.send_c_find(
            ds, StudyRootQueryRetrieveInformationModelFind)

        # Check find result one by one
        for (status, identifier) in responses:
            if status:
                #print('C-FIND Status:0x{0:04x}'.format(status.Status))
                # Add result into list when status is pending or success
                if status.Status in (0xFF00, 0xFF01):
                    print('Pick up Study information: %s' %
                          identifier.PatientID)
                    studyList.append(identifier)
            else:
                print(
                    'Connection timed out, was aborted or received invalid response'
                )

        assoc.release()
    else:
        print('Association rejected, aborted or never connected')

    return studyList
예제 #5
0
def retrieve(
    accession,
    patient_id,
    ae_title='GEPACSD042',
):
    ae = AE('RESEARCH')
    ae.add_requested_context(StudyRootQueryRetrieveInformationModelFind)
    ae.add_requested_context(StudyRootQueryRetrieveInformationModelMove,
                             transfer_syntax=ts)
    assoc = ae.associate(__getattr__('ae_titles')[ae_title][0],
                         __getattr__('ae_titles')[ae_title][1],
                         ae_title=ae_title)
    logger.debug(str(assoc))
    try:
        # get study id
        ds = Dataset()
        ds.AccessionNumber = accession
        ds.PatientID = patient_id
        ds.QueryRetrieveLevel = 'STUDY'
        ds.StudyInstanceUID = ''
        StudyInstanceUID = [i.StudyInstanceUID for i in cfind(ds, assoc)][0]
        identifiers = [StudyInstanceUID]
        ds.StudyInstanceUID = StudyInstanceUID
        cmove(ds, assoc)

        # get series id
        #ds.QueryRetrieveLevel = 'SERIES'
        #ds.StudyInstanceUID = StudyInstanceUID
        #ds.SeriesInstanceUID = ''
        #ds.SeriesDescription = ''
        #ds.ImageType = ''
        #ds.KVP = ''
        #identifiers = cfind(ds, assoc, )
        #logger.debug ('Num series found: {}'.format(len(identifiers)))
        #logger.debug (identifiers)

        # move series
        #for id in identifiers:
        #    ds.SeriesInstanceUID = id.SeriesInstanceUID
        #    cmove(ds, assoc, )

        assoc.release()
    except Exception as e:
        assoc.release()
        raise e
    assert len(identifiers) > 0, "No studies found for {} from {}".format(
        accession, ae_title)
    return identifiers
예제 #6
0
def retrieve_study(cfg, acc_no, output_dir):
    if not os.path.exists(output_dir):
        try:
            os.makedirs(output_dir)
        except OSError as exc:  # Guard against race condition
            if exc.errno != errno.EEXIST:
                raise

    ae = AE(ae_title=cfg['pacs']['my']['aet'])
    ae.requested_contexts = QueryRetrievePresentationContexts
    assoc = ae.associate(cfg['pacs']['called']['ip'],
                         cfg['pacs']['called']['port'])
    ds = Dataset()
    ds.AccessionNumber = acc_no
    ds.QueryRetrieveLevel = "SERIES"
    ds.Modality = ""
    responses = assoc.send_c_find(ds, query_model='P')
    for (status, dataset) in responses:
        if status.Status in (0xFF00, 0xFF01):
            modality = dataset.Modality
            if modality not in ('CR', 'DX'):
                continue

            p_id = dataset.PatientID
            study_uid = dataset.StudyInstanceUID
            series_uid = dataset.SeriesInstanceUID

            cmd_str = r'''movescu {pacs_ip} {pacs_port} +P {port} +xa -aec {pacs_aet} -aet {aet} \
                          -k QueryRetrieveLevel=SERIES \
                          -k PatientID={p_id} \
                          -k StudyInstanceUID={study_uid} \
                          -k SeriesInstanceUID={series_uid} \
                          -od {output_dir} \
                        '''.format(pacs_ip=cfg['pacs']['called']['ip'],
                                   pacs_port=cfg['pacs']['called']['port'],
                                   pacs_aet=cfg['pacs']['called']['aet'],
                                   aet=cfg['pacs']['my']['aet'],
                                   port=cfg['pacs']['my']['port'],
                                   p_id=p_id,
                                   study_uid=study_uid,
                                   series_uid=series_uid,
                                   output_dir=output_dir)
            #print(cmd_str)
            os.system(cmd_str)
            print("Success. acc_no={}".format(acc_no))
        elif status.Status != 0x0:
            print("acc_no={}, status={}".format(acc_no, hex(status.Status)))
    assoc.release()
예제 #7
0
def pacs_find(hostname, port, host_ae_title, user_ae_title,
              query_retrieve_level, accession_number, patient_id):
    ae = AE(ae_title=user_ae_title)
    ae.add_requested_context(StudyRootQueryRetrieveInformationModelFind)
    ds = Dataset()
    ds.AccessionNumber = accession_number
    ds.PatientID = patient_id
    ds.PatientBirthDate = ''
    ds.StudyDescription = ''
    ds.StudyInstanceUID = ''
    ds.StudyDate = ''
    ds.StudyTime = ''
    ds.ModalitiesInStudy = ''
    ds.StationName = ''
    ds.NumberOfStudyRelatedInstances = ''
    ds.QueryRetrieveLevel = query_retrieve_level
    assoc = ae.associate(hostname, port, ae_title=host_ae_title)

    a = None
    matches = 0
    msg = None
    if assoc.is_established:
        responses = assoc.send_c_find(
            ds, StudyRootQueryRetrieveInformationModelFind)
        for (status, identifier) in responses:
            if matches == 2:
                a = None
                ae.shutdown()
                msg = 'Multiple studies found for this query.'
                break
            if status:
                msg = find_status_dict[status.Status][1]
                if status.Status in (0xFF00, 0xFF01):
                    a = identifier
                    matches += 1
                if status.Status == 0x0000 and a is None:
                    msg = 'No study found for this query.'
            else:
                msg = 'Connection timed out, was aborted or received invalid response.'
        assoc.release()
    else:
        msg = 'Association rejected, aborted or never connected.'
        matches = None
    return a, matches, msg
예제 #8
0
    def get_random_worklist(self):
        """ Generate a random worklist """

        worklist_item = Dataset()
        worklist_item.StudyInstanceUID = generate_uid(prefix='1.2.840.113619.2.391.6789.', entropy_srcs=[_random_unicode_string(10, _get_random_language_string()), _random_unicode_string(10, _get_random_language_string())])
        worklist_item.Modality = 'US'
        worklist_item.SpecificCharacterSet = self._specific_charset
        worklist_item.CurrentPatientLocation = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
        worklist_item.AccessionNumber = _random_unicode_string(16, _get_random_language_string())
        worklist_item.PatientBirthDate = _random_dicom_date_after_1900()
        worklist_item.PatientName = self._get_person_name()
        worklist_item.PatientID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)

        self._fault_provider._sleep_random() #Possible delay

        worklist_item.IssuerOfPatientID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
        worklist_item.PatientWeight = str(random.uniform(10.0, 150.0))[:16]
        worklist_item.PatientSize = str(random.uniform(1.0, 2.5))[:16]
        worklist_item.AdmissionID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
        worklist_item.RequestedProcedureID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(16), self._fault_provider._return_None_string)
        worklist_item.RequestedProcedureDescription = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
        worklist_item.ReferringPhysicianName = self._get_person_name()

        otherPatientIdsSq = [Dataset(), Dataset()]
        for otherPatientId in otherPatientIdsSq:
            otherPatientId.PatientID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
            otherPatientId.IssuerOfPatientID = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
            otherPatientId.TypeOfPatientID = 'TEXT'

        worklist_item.OtherPatientIDsSequence = otherPatientIdsSq

        step = Dataset()
        step.ScheduledPerformingPhysicianName = self._get_person_name()
        step.ScheduledProcedureStepStartDate = _random_dicom_date_after_1900()
        step.ScheduledProcedureStepStartTime = _random_dicom_time()
        step.ScheduledProcedureStepDescription = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(64), self._fault_provider._return_None_string)
        step.CommentsOnTheScheduledProcedureStep = _extend_with_random_to_length('', self._fault_provider. _get_random_string_length(10240), self._fault_provider._return_None_string)
        worklist_item.ScheduledProcedureStepSequence = [step]

        return worklist_item
예제 #9
0
def retrieve_study(cfg, acc_no, output_dir):
    if not os.path.exists(output_dir):
        try:
            os.makedirs(output_dir)
        except OSError as exc:  # Guard against race condition
            if exc.errno != errno.EEXIST:
                raise

    ae = AE(ae_title=cfg['pacs']['my']['aet'])
    ae.requested_contexts = QueryRetrievePresentationContexts
    assoc_cf = ae.associate(cfg['pacs']['called']['ip'],
                            cfg['pacs']['called']['port'])
    assoc_cm = ae.associate(cfg['pacs']['called']['ip'],
                            cfg['pacs']['called']['port'])
    ds_q = Dataset()
    ds_q.AccessionNumber = acc_no
    ds_q.QueryRetrieveLevel = "SERIES"
    ds_q.Modality = ""
    responses_cf = assoc_cf.send_c_find(ds_q, query_model='P')
    for (status_cf, dataset_cf) in responses_cf:
        if status_cf.Status in (0xFF00, 0xFF01):
            modality = dataset_cf.Modality
            if modality not in ('CR', 'DX'):
                continue

            responses_cm = assoc_cm.send_c_move(dataset_cf,
                                                cfg['pacs']['my']['aet'],
                                                query_model='P')
            for (status_cm, dataset_cm) in responses_cm:
                if (status_cm.Status == 0x0):
                    pass
                else:
                    print('status: {}; dataset: {}'.format(
                        status_cm, dataset_cm))
        elif status_cf.Status != 0x0:
            print("acc_no={}, status={}".format(acc_no, hex(status_cf.Status)))
    assoc_cf.release()
    assoc_cm.release()
예제 #10
0
ds = Dataset()
ds.file_meta = get_file_meta(dcms)
ds.is_implicit_VR = True
ds.is_little_endian = True
ds.fix_meta_info(enforce_standard=True)

dt = datetime.datetime.now()

ds.InstanceCreationDate = dt.strftime("%Y%m%d")
ds.InstanceCreationTime = dt.strftime("%H%M%S.%f")
ds.InstanceCreatorUID = "Anonymous"  # TODO
ds.SOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID
ds.SOPClassUID = ds.file_meta.MediaStorageSOPClassUID
ds.StudyDate = dcm.StudyDate
ds.StudyTime = dcm.StudyTime
ds.AccessionNumber = dcm.AccessionNumber
ds.Modality = "RTSTRUCT"
ds.Manufacturer = dcm.Manufacturer
ds.ReferringPhysicianName = dcm.ReferringPhysicianName
ds.InstitutionalDepartmentName = "Anonymous"  # TODO
ds.ManufacturerModelName = dcm.ManufacturerModelName
ds.PatientName = dcm.PatientName
ds.PatientID = dcm.PatientID
ds.PatientBirthDate = dcm.PatientBirthDate
ds.PatientSex = dcm.PatientSex
ds.StudyInstanceUID = dcm.StudyInstanceUID
ds.StudyID = "Anonymous"  # TODO
ds.SeriesNumber = "1"  # TODO
ds.StructureSetLabel = "STRCTRLABEL"
ds.StructureSetName = "STRCTRNAME"
ds.StructureSetDate = ds.InstanceCreationDate
예제 #11
0
def dcm_initialise():

    ### This function based on pydicom codify output

    # File meta info data elements
    file_meta = Dataset()
    # file_meta.FileMetaInformationGroupLength = 194 ### REQUIRES DEFINITION
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
    # file_meta.MediaStorageSOPInstanceUID = '1.2.40.0.13.1.75591523476291404472265359935487530723' ### REQUIRES DEFINITION
    file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
    file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.3.6.1'
    file_meta.ImplementationVersionName = 'PERINATAL_CUSTOM_PYDICOM'

    # Main data elements
    ds = Dataset()
    ds.SpecificCharacterSet = 'ISO_IR 100'
    # ds.ImageType = ['ORIGINAL', 'PRIMARY', 'M_FFE', 'M', 'FFE'] ### REQUIRES DEFINITION
    ds.InstanceCreationDate = ''
    ds.InstanceCreationTime = ''
    ds.InstanceCreatorUID = '1.2.40.0.13.1.203399489339977079628124438700844270739'  ### TODO: determine if required
    ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
    # ds.SOPInstanceUID = '1.2.40.0.13.1.75591523476291404472265359935487530723' ### REQUIRES DEFINITION
    ds.StudyDate = ''
    ds.SeriesDate = ''
    ds.AcquisitionDate = ''
    ds.ContentDate = ''
    ds.StudyTime = ''
    ds.SeriesTime = ''  # '182511.32000'
    ds.AcquisitionTime = ''  # '182511.32'
    ds.ContentTime = ''  # '182511.32'
    ds.AccessionNumber = ''
    ds.Modality = 'MR'
    ds.Manufacturer = 'Philips Healthcare'
    ds.CodeValue = ''
    ds.CodingSchemeDesignator = 'DCM'
    ds.CodeMeaning = ''

    # Procedure Code Sequence
    procedure_code_sequence = Sequence()
    ds.ProcedureCodeSequence = procedure_code_sequence

    # Procedure Code Sequence: Procedure Code 1
    procedure_code1 = Dataset()
    procedure_code1.CodeValue = ''  # 'RA.MRAAOT'
    procedure_code1.CodingSchemeDesignator = ''  # '99ORBIS'
    procedure_code1.CodeMeaning = ''  # 'CE-MRA Aorta thorakal'
    procedure_code1.ContextGroupExtensionFlag = 'N'
    procedure_code_sequence.append(procedure_code1)

    ds.OperatorsName = ''
    ds.AdmittingDiagnosesDescription = ''
    ds.ManufacturerModelName = 'Ingenia'

    # Referenced Performed Procedure Step Sequence
    refd_performed_procedure_step_sequence = Sequence()
    ds.ReferencedPerformedProcedureStepSequence = refd_performed_procedure_step_sequence

    # Referenced Performed Procedure Step Sequence: Referenced Performed Procedure Step 1
    refd_performed_procedure_step1 = Dataset()
    refd_performed_procedure_step1.InstanceCreationDate = ''
    refd_performed_procedure_step1.InstanceCreationTime = ''
    refd_performed_procedure_step1.InstanceCreatorUID = '1.2.40.0.13.1.203399489339977079628124438700844270739'  ### TODO: determine if required
    refd_performed_procedure_step1.ReferencedSOPClassUID = '1.2.840.10008.3.1.2.3.3'
    refd_performed_procedure_step1.ReferencedSOPInstanceUID = '1.3.46.670589.11.17204.5.0.6524.2012082117320696006'
    refd_performed_procedure_step1.InstanceNumber = "0"
    refd_performed_procedure_step_sequence.append(
        refd_performed_procedure_step1)

    # 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.4'
    refd_image1.ReferencedSOPInstanceUID = '1.2.40.0.13.1.89078282904346598403696206113943676723'
    refd_image_sequence.append(refd_image1)

    # Referenced Image Sequence: Referenced Image 2
    refd_image2 = Dataset()
    refd_image2.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
    refd_image2.ReferencedSOPInstanceUID = '1.2.40.0.13.1.295129673873169057216869911833080985343'
    refd_image_sequence.append(refd_image2)

    # Referenced Image Sequence: Referenced Image 3
    refd_image3 = Dataset()
    refd_image3.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
    refd_image3.ReferencedSOPInstanceUID = '1.2.40.0.13.1.37560432539838529536104187971339317428'
    refd_image_sequence.append(refd_image3)

    ds.PatientName = 'Not Specified'
    ds.PatientID = 'Not Specified'
    ds.PrivateCreator = 'Philips Imaging'
    ds.IssuerOfPatientID = ''
    ds.PatientBirthDate = ''
    ds.OtherPatientIDs = ''
    ds.OtherPatientNames = ''
    ds.PatientMotherBirthName = ''
    # ds.PregnancyStatus = 4
    ds.ScanningSequence = 'kt bFFE'  # 'GR'
    ds.SequenceVariant = ''  # 'SP'
    ds.ScanOptions = ''  # 'FC'
    ds.MRAcquisitionType = '3D'
    ds.SequenceName = ''
    ds.SliceThickness = ''
    ds.RepetitionTime = "3.8"
    ds.EchoTime = "1.9"
    ds.NumberOfAverages = "1"
    ds.ImagingFrequency = "127.768401"
    ds.ImagedNucleus = '1H'
    ds.EchoNumbers = "1"
    ds.MagneticFieldStrength = "1.5"
    ds.SpacingBetweenSlices = ""
    ds.NumberOfPhaseEncodingSteps = ""  # "143"
    ds.EchoTrainLength = ""  # "3"
    ds.PercentSampling = ""  # "98.4375"
    ds.PercentPhaseFieldOfView = ""  # "86.4864871376439"
    ds.PixelBandwidth = ""  # "3284"
    ds.SoftwareVersions = ['5.1.7', '5.1.7.2']
    ds.ProtocolName = 'Not Specified'
    # ds.TriggerTime = "622" ### REQUIRES DEFINITION
    # ds.LowRRValue = "632" # Not sure if needed
    # ds.HighRRValue = "733" # Not sure if needed
    ds.IntervalsAcquired = ""  # "1132"
    ds.IntervalsRejected = ""  # "20"
    ds.HeartRate = ""
    ds.ReconstructionDiameter = ""  # "379.999992370605"
    ds.ReceiveCoilName = 'MULTI COIL'
    ds.TransmitCoilName = 'B'
    # ds.AcquisitionMatrix = [0, 148, 143, 0] # TODO: Determine if required
    ds.InPlanePhaseEncodingDirection = ''  # 'ROW'
    ds.FlipAngle = "60"
    ds.SAR = ""
    ds.dBdt = ""
    ds.PatientPosition = ''  # 'HFS' TODO: Determine if important/required
    # ds.AcquisitionDuration = 459.6679992675781 # TODO: Determine if important/required
    ds.DiffusionBValue = 0.0
    ds.DiffusionGradientOrientation = [0.0, 0.0, 0.0]
    ds.StudyInstanceUID = '1.2.40.0.13.1.333311361771566580913219583914625766216'  # TODO: determine if needs generating
    ds.SeriesInstanceUID = '1.2.40.0.13.1.286595144572817015845933344548631223145'  # TODO: determine if needs generating
    ds.StudyID = '513842.201207030'  # TODO: determine if needs generating
    ds.SeriesNumber = ""
    ds.AcquisitionNumber = ""  # "10"
    # ds.InstanceNumber = "319" ### REQUIRES DEFINITION
    # ds.ImagePositionPatient = ['-56.040032677094', '-189.81796011867', '225.026188065538'] ### REQUIRES DEFINITION
    # ds.ImageOrientationPatient = ['0.51319164037704', '0.85772150754928', '-0.0307911429554', '-0.0599991045892', '6.4554493292E-05', '-0.9981984496116'] ### TODO: decide if need to match Nifti affine
    ds.FrameOfReferenceUID = '1.2.40.0.13.1.168070265634523572089252568290704983898'  # TODO: determine if required
    ds.TemporalPositionIdentifier = ""  # "1"
    ds.NumberOfTemporalPositions = ""  # "1"
    ds.PositionReferenceIndicator = ''
    # ds.SliceLocation = "38.9999961150011" ### REQUIRES DEFINITION
    ds.SamplesPerPixel = 1
    ds.PhotometricInterpretation = 'MONOCHROME2'
    # ds.Rows = 192 ### REQUIRES DEFINITION
    # ds.Columns = 192 ### REQUIRES DEFINITION
    # ds.PixelSpacing = ['1.97916662693023', '1.97916662693023'] ### REQUIRES DEFINITION
    ds.BitsAllocated = 16
    ds.BitsStored = 12
    ds.HighBit = 11
    ds.PixelRepresentation = 0
    # ds.WindowCenter = "213.04" ### REQUIRES DEFINITION
    # ds.WindowWidth = "370.49" ### REQUIRES DEFINITION
    ds.LossyImageCompression = '00'
    ds.RequestingPhysician = ''
    ds.RequestingService = ''
    ds.RequestedProcedureDescription = 'FCMR 4D FLOW MRI'
    ds.PerformedStationAETitle = ''
    ds.PerformedProcedureStepStartDate = ''  # '20120821'
    ds.PerformedProcedureStepStartTime = ''  # '173207'
    ds.PerformedProcedureStepEndDate = ''  # '20120821'
    ds.PerformedProcedureStepEndTime = ''  # '173207'
    ds.PerformedProcedureStepID = ''  # '398712726'
    ds.PerformedProcedureStepDescription = ''  # 'CE-MRA Aorta thorakal'

    # Performed Protocol Code Sequence
    performed_protocol_code_sequence = Sequence()
    ds.PerformedProtocolCodeSequence = performed_protocol_code_sequence

    # Performed Protocol Code Sequence: Performed Protocol Code 1
    performed_protocol_code1 = Dataset()
    performed_protocol_code1.CodeValue = ''  # 'RA.MRAAOT'
    performed_protocol_code1.CodingSchemeDesignator = ''  # '99ORBIS'
    performed_protocol_code1.CodeMeaning = ''  # 'CE-MRA Aorta thorakal'
    performed_protocol_code1.ContextGroupExtensionFlag = 'N'
    performed_protocol_code_sequence.append(performed_protocol_code1)

    # Film Consumption Sequence
    film_consumption_sequence = Sequence()
    ds.FilmConsumptionSequence = film_consumption_sequence

    ds.RequestedProcedureID = '513842.201207030'

    # Real World Value Mapping Sequence
    real_world_value_mapping_sequence = Sequence()
    ds.RealWorldValueMappingSequence = real_world_value_mapping_sequence

    # Real World Value Mapping Sequence: Real World Value Mapping 1
    real_world_value_mapping1 = Dataset()
    real_world_value_mapping1.RealWorldValueIntercept = 0.0
    real_world_value_mapping1.RealWorldValueSlope = 0.0  # 4.280830280830281
    real_world_value_mapping_sequence.append(real_world_value_mapping1)

    ds.PresentationLUTShape = 'IDENTITY'

    return file_meta, ds
예제 #12
0
파일: _dicom.py 프로젝트: abukaj/kESI
        def DICOM_MR_backbone(self, SeriesInstanceUID):
            # Main data elements
            ds = Dataset()
            ds.SpecificCharacterSet = 'ISO_IR 101'  # latin-2
            ds.ImageType = ['ORIGINAL', 'PRIMARY', 'OTHER']
            ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.4'  # MR
            ds.SOPInstanceUID = f'2.5.{uuid.uuid4().int:d}'

            ds.StudyDate = ''  # YYYYMMDD
            ds.StudyTime = ''  # HHMMSS

            ds.AccessionNumber = ''
            ds.Modality = 'MR'
            ds.Manufacturer = 'Jakub Dzik'

            ds.ReferringPhysicianName = ''

            ds.PatientName = 'Anonymized'
            ds.PatientID = '1234'
            ds.PatientBirthDate = ''
            ds.PatientSex = ''

            ds.ContrastBolusAgent = ''

            ds.ScanningSequence = 'EP'
            ds.SequenceVariant = 'NONE'
            ds.ScanOptions = ''
            ds.MRAcquisitionType = '3D'

            ds.EchoTime = ''

            ds.EchoTrainLength = ''

            ds.PatientPosition = ''

            ds.StudyInstanceUID = self.StudyInstanceUID
            ds.SeriesInstanceUID = SeriesInstanceUID
            ds.StudyID = ''

            ds.AcquisitionNumber = ''

            ds.FrameOfReferenceUID = self.FrameOfReferenceUID
            ds.Laterality = ''

            ds.PositionReferenceIndicator = ''

            ds.SamplesPerPixel = 1
            ds.PhotometricInterpretation = 'MONOCHROME2'

            ds.CommentsOnThePerformedProcedureStep = ''
            ds.RequestedProcedureID = 'MOZGOWIE'
            ds.ReasonForTheRequestedProcedure = ''
            ds.RequestedProcedurePriority = ''
            ds.PatientTransportArrangements = ''
            ds.RequestedProcedureLocation = ''
            ds.RequestedProcedureComments = ''
            ds.ReasonForTheImagingServiceRequest = ''
            ds.IssueDateOfImagingServiceRequest = '20210222'
            ds.IssueTimeOfImagingServiceRequest = '084604.947'
            ds.OrderEntererLocation = ''
            ds.OrderCallbackPhoneNumber = ''
            ds.ImagingServiceRequestComments = ''
            ds.PresentationLUTShape = 'IDENTITY'

            ds.is_implicit_VR = False
            ds.is_little_endian = True
            return ds
예제 #13
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)
예제 #14
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
예제 #15
0
# Set creation date/time
ds.SOPClassUID = 'RT Image Storage'
ds.SOPInstanceUID = "1.2.826.0.1.3680043.8.937.1.20170926.8691"
ds.ImageType = ['ORIGINAL', 'PRIMARY', 'PORTAL', '']
dt = datetime.datetime.now()
ds.StudyDate = dt.strftime('%Y%m%d')
ds.SeriesDate = dt.strftime('%Y%m%d')
ds.AcquisitionDate = dt.strftime('%Y%m%d')
ds.ContentDate = dt.strftime('%Y%m%d')
timeStr = dt.strftime('%H%M%S.%f')  # long format with micro seconds
ds.StudyTime = timeStr
ds.SeriesTime = timeStr
ds.AcquisitionTime = timeStr
ds.ContentTime = timeStr
ds.AccessionNumber = ''
ds.Modality = 'RTImage'
ds.ConversionType = 'DI'
ds.Manufacturer = "GATE"
ds.ReferringPhysiciansName = ''
ds.StationName = "GATE Dose Actor"
ds.PatientName = "Phantom name"
#ds.PatientName = raw_input('Give your DICOM a name: ')
ds.PatientID = "123456"
ds.PatientBirthDate = ''
ds.PatientSex = ''
ds.DeviceSerialNumber = '9101060'
ds.StudyInstanceUID = '1.2.826.0.1.3680043.2.1125.1.35859627302800520295369011388644332'
ds.SeriesInstanceUID = '1.2.826.0.1.3680043.2.1125.1.81507923164692601234912200876243257'
ds.StudyID = ''
ds.SeriesNumber = ''
예제 #16
0
def query_worklist(request):

    if request.method == 'POST':
        accession = request.POST['accession']

        # Query Worklist by accession
        scu_ae = WorkstationConfigs.objects.get(id=1).workstation_ae

        # SCU
        ae = AE(ae_title=scu_ae)

        ae.add_requested_context(ModalityWorklistInformationFind)

        ds = Dataset()
        ds.PatientName = '*'
        ds.AccessionNumber = accession
        ds.PatientID = ''
        ds.StudyInstanceUID = ''
        ds.QueryRetrieveLevel = 'STUDY'
        ds.ScheduledProcedureStepSequence = [Dataset()]
        item = ds.ScheduledProcedureStepSequence[0]
        item.modality = 'US'

        # associate with SCP
        scp = WorklistConfigs.objects.get(id=1)
        scp_ip = scp.worklist_ip
        scp_ae = scp.worklist_ae
        scp_port = scp.worklist_port
        assoc = ae.associate(scp_ip, scp_port, ae_title=scp_ae)

        if assoc.is_established:
            responses = assoc.send_c_find(ds, ModalityWorklistInformationFind)

            for (status, identifier) in responses:
                if status:
                    print('C-FIND query status: 0x{0:04x}'.format(
                        status.Status))

                    if status.Status in (0xFF00, 0xFF01) and identifier:
                        study_data = identifier

                        query_form = TechNoteForm()

                        context = {
                            'study_data':
                            study_data,
                            'patient_name':
                            study_data[0x10, 0x10].value,
                            'patient_id':
                            study_data[0x10, 0x20].value,
                            'accession':
                            study_data[0x08, 0x50].value,
                            'StudyInstanceUID':
                            study_data[0x20, 0x0d].value,
                            'modality':
                            study_data.ScheduledProcedureStepSequence[0][
                                0x08, 0x60].value,
                            'study_date':
                            study_data.ScheduledProcedureStepSequence[0][
                                0x40, 0x02].value,
                            'study_description':
                            study_data.ScheduledProcedureStepSequence[0][
                                0x40, 0x07].value,
                            'query_form':
                            query_form,
                        }

                        return render(request,
                                      'tech_forms/query_worklist.html',
                                      context)

                    else:
                        error = 'No match found'

                else:
                    error = "Connection timed out, was aborted or receieved invalid response"
            assoc.release()
        else:
            error = 'Associated rejected, aborted or never connected'

        context = {
            'error': error,
        }

        return render(request, 'tech_forms/query_worklist_error.html', context)

    else:

        form = QueryWorklistForm()

        context = {"form": form}

        return render(request, 'tech_forms/query_worklist.html', context)
예제 #17
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)
예제 #18
0
def generate_rtplan_skeleton():

    ds = Dataset()

    # ----- File meta -----
    file_meta = generate_rtplan_file_meta()
    ds.file_meta = file_meta

    # ----- Patient Module -----
    ds.PatientName = 'PyMedPhys'  # Required - can be empty - could fill in?
    ds.PatientID = 'PMP'  # Required - can be empty - could fill in?
    ds.PatientSex = 'O'  # Required - can be empty
    ds.PatientBirthDate = ''  # Required - can be empty TODO: check if RS happy

    ds.StudyInstanceUID = pydicom.uid.generate_uid()
    ds.StudyDate = ''  # Required - can be empty
    ds.StudyTime = ''  # Required - can be empty'
    ds.ReferringPhysicianName = ''  # Required - can be empty'
    ds.StudyID = ''  # Required - can be empty'
    ds.AccessionNumber = ''  # Required - can be empty'

    # ----- RT Series Module -----
    ds.Modality = 'RTPLAN'
    ds.SeriesInstanceUID = pydicom.uid.generate_uid()
    ds.SeriesNumber = ""  # Required - can be empty'
    ds.OperatorsName = ''  # Required - can be empty'

    # ----- Frame of Reference Module -----
    ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
    ds.PositionReferenceIndicator = ''  # Required - can be empty'

    # ----- General Equipment Module -----
    ds.Manufacturer = ''  # Required - can be empty TODO: Check if RS is happy'
    # ds.ManufacturerModelName = '' # Optional TODO: Check if RS is happy'

    # ----- RT General Plan Module -----
    ds.RTPlanLabel = 'PyMedPhys'  # Set from field definition?
    ds.RTPlanName = 'PyMedPhys'  # Optional, Set from field definition?
    ds.RTPlanDescription = 'PyMedPhys'  # Optional, Set from field definition?
    # Required - can be empty TODO: Check if RS is happy
    ds.RTPlanDate = datetime.now().strftime("%Y%m%d")
    # Required - can be empty TODO: Check if RS is happy
    ds.RTPlanTime = datetime.now().strftime("%H%M%S")
    ds.PlanIntent = 'VERIFICATION'
    ds.RTPlanGeometry = 'TREATMENT_DEVICE'  # Structure Set will probably not exist

    # ----- RT Patient Setup Sequence & Patient Setup -----
    patient_setup_sequence = Sequence()
    ds.PatientSetupSequence = patient_setup_sequence

    patient_setup = Dataset()
    patient_setup.PatientSetupNumber = '1'  # or "ASYMX"
    patient_setup.PatientPosition = "HFS"
    patient_setup_sequence.append(patient_setup)

    # ----- SOP Common Module -----
    ds.SpecificCharacterSet = 'ISO_IR 192'
    ds.InstanceCreationDate = ''  # Optional, could fill in?
    ds.InstanceCreationTime = ''  # Optional, could fill in?'
    ds.SOPClassUID = file_meta.MediaStorageSOPClassUID
    ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
    ds.ApprovalStatus = 'UNAPPROVED'

    return ds
예제 #19
0
    def generate_dicom(self, file_out_name: str, gantry_angle: float = 0.0, coll_angle: float = 0.0,
                       table_angle: float = 0.0):
        # make image look like an EPID with flipped data (dose->low)
        flipped_image = -self.image + self.image.max() + self.image.min()

        file_meta = FileMetaDataset()
        # Main data elements
        ds = Dataset()
        ds.ImageType = ['DERIVED', 'SECONDARY', 'PORTAL']
        ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.1'
        ds.SOPInstanceUID = '1.2.840.113854.141883099300381770008774160544352783139.1.1'
        ds.StudyDate = '20150212'
        ds.ContentDate = '20150212'
        ds.StudyTime = '124120'
        ds.ContentTime = '124120'
        ds.AccessionNumber = ''
        ds.Modality = 'RTIMAGE'
        ds.ConversionType = 'WSD'
        ds.Manufacturer = 'IMPAC Medical Systems, Inc.'
        ds.ReferringPhysicianName = ''
        ds.StudyDescription = 'QA'
        ds.SeriesDescription = 'D + Gantry_0'
        ds.PhysiciansOfRecord = 'Awesome Physician'
        ds.OperatorsName = ''
        ds.ManufacturerModelName = 'MOSAIQ'
        ds.PatientName = 'Lutz^Test Tool'
        ds.PatientID = 'zzzBAC_Lutz'
        ds.PatientBirthDate = ''
        ds.SoftwareVersions = '2.41.01J0'
        ds.StudyInstanceUID = '1.2.840.113854.141883099300381770008774160544352783139'
        ds.SeriesInstanceUID = '1.2.840.113854.141883099300381770008774160544352783139.1'
        ds.StudyID = '348469'
        ds.SeriesNumber = "4597199"
        ds.InstanceNumber = "0"
        ds.PatientOrientation = ''
        ds.PositionReferenceIndicator = ''
        ds.SamplesPerPixel = 1
        ds.PhotometricInterpretation = 'MONOCHROME2'
        ds.Rows = self.image.shape[0]
        ds.Columns = self.image.shape[1]
        ds.BitsAllocated = 16
        ds.BitsStored = 16
        ds.HighBit = 15
        ds.PixelRepresentation = 0
        ds.RTImageLabel = 'D'
        ds.RTImagePlane = 'NORMAL'
        ds.XRayImageReceptorAngle = "0.0"
        ds.ImagePlanePixelSpacing = [self.pixel_size, self.pixel_size]
        ds.RTImagePosition = [-200.70400, 150.52800]
        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.PixelData = flipped_image  # XXX Array of 393216 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)
예제 #20
0
def write_dicom_dose_template(rtplan,beamnr,filename,phantom=False):
    """
    Create a template DICOM file for storing a dose distribution corresponding to a given treatment plan.
    * rtplan: a pydicom Dataset object containing a PBS ion beam plan.
    * beamnr: a *string* containing the beam number to be used for referral. Should contain "PLAN" for plan dose files.
    * filename: file path of the desired output DICOM file
    * phantom: boolean flag to indicate whether this is for a CT (False) or phantom dose (True).
    """
    unique_id = pydicom.uid.generate_uid() # create a new unique UID
    plandose = beamnr.upper() == 'PLAN'

    # File meta info data elements
    file_meta = Dataset()
    file_meta.FileMetaInformationGroupLength = 200 # maybe 210 for phantoms (can also be RS6 vs RS5)
    file_meta.FileMetaInformationVersion = b'\x00\x01'
    file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2'
    file_meta.MediaStorageSOPInstanceUID = unique_id
    file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
    #FIXME: we probably need to apply for an official UID here
    file_meta.ImplementationClassUID = '1.2.826.0.1.3680043.1.2.100.6.40.0.76'
    if sys.version_info.major == 3:
        file_meta.ImplementationVersionName = 'DicomObjects.NET'
    else:
        file_meta.ImplementationVersionName = u'DicomObjects.NET'

    # Main data elements
    now = datetime.now()
    ds = Dataset()

    ds.AccessionNumber = ''
    ds.Manufacturer = 'ACMIT Gmbh and EBG MedAustron GmbH and Medical University of Vienna' ###
    ds.ManufacturerModelName = "IDEAL"  ###
    ds.SoftwareVersions = ideal_version.tag ###
    ds.PositionReferenceIndicator = ''

    ds.SpecificCharacterSet = 'ISO_IR 100'
    ds.InstanceCreationDate = now.strftime("%Y%m%d") #'20171121' ###
    ds.InstanceCreationTime = now.strftime("%H%M%S") # '120041' ###
    ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.2'
    ds.SOPInstanceUID = unique_id # '1.2.752.243.1.1.20180817170901595.1980.23430' ###
    ds.StudyDate = str(rtplan.StudyDate) # '20171103' ###
    ds.StudyTime = str(rtplan.StudyTime) # '153709' ###
    ds.Modality = 'RTDOSE'
    ds.ReferringPhysicianName = str(rtplan.ReferringPhysicianName) # 'Anonymized' ###
    if "SeriesDescription" in rtplan:
        ds.SeriesDescription = str(rtplan.SeriesDescription) ###
    if "OperatorsName" in rtplan:
        ds.OperatorsName = str(rtplan.OperatorsName) ###
    if "PatientName" in rtplan:
        ds.PatientName = str(rtplan.PatientName) ###
    if "PatientID" in rtplan:
        ds.PatientID = str(rtplan.PatientID) ###
    if "PatientBirthDate" in rtplan:
        ds.PatientBirthDate = str(rtplan.PatientBirthDate) ###
    if "PatientSex" in rtplan:
        ds.PatientSex = str(rtplan.PatientSex) ###
    ds.SliceThickness = str("1") ### overwrite by postprocessing
    ds.StudyInstanceUID = rtplan.StudyInstanceUID.strip() ###
    ds.SeriesInstanceUID = rtplan.SeriesInstanceUID.strip() ###
    if hasattr(rtplan,"StudyDescription"):
        ### absent for phantom/commissioning
        ds.StudyDescription = str(rtplan.StudyDescription)
    if hasattr(rtplan,"PatientIdentityRemoved"):
        ds.PatientIdentityRemoved = str(rtplan.PatientIdentityRemoved) ### absent for phantom/commsissioning plans
        ds.DeidentificationMethod = str(rtplan.DeidentificationMethod) ### absent for phantom/commsissioning plans
    if hasattr(rtplan,"StudyID"):
        ds.StudyID = rtplan.StudyID ###
    if hasattr(rtplan,"SeriesNumber"):
        ds.SeriesNumber = rtplan.SeriesNumber ###
    if phantom:
        ds.InstanceNumber = 0 # str("0") ### only for phantom/commissioning
        ds.PatientOrientation = str('') ### only for phantom/commissioning
    ds.ImagePositionPatient = [str(-999.999), str(-999.999), str(-999.999)] ### overwrite by postprocessing
    ds.ImageOrientationPatient = [str(float(c)) for c in '100010']
    ds.FrameOfReferenceUID = rtplan.FrameOfReferenceUID.strip() ###
    ds.SamplesPerPixel = 1
    ds.PhotometricInterpretation = 'MONOCHROME2'
    ds.NumberOfFrames = str(9) ### overwrite by postprocessing
    ds.FrameIncrementPointer = pydicom.tag.BaseTag(0x3004000c) # That is the tag corresponding to the "GridFrameOffsetVector". All RS dose files do it like this.
    ds.Rows = 9 ### overwrite by postprocessing
    ds.Columns = 9 ### overwrite by postprocessing
    ds.PixelSpacing = [str('9'), str('9')] ### overwrite by postprocessing
    ds.BitsAllocated = 16
    ds.BitsStored = 16
    ds.HighBit = 15
    ds.PixelRepresentation = 0
    ds.DoseUnits = 'GY'
    ds.DoseType = 'PHYSICAL' ### TODO: for RBE we may want "effective"
    ds.DoseSummationType = 'PLAN' if plandose else 'BEAM' ### beam/plan difference
    ds.GridFrameOffsetVector = [str(c) for c in range(9) ]
    ds.DoseGridScaling = 0.999999 ### overwrite by postprocessing

    # Referenced RT Plan Sequence
    refd_rt_plan_sequence = Sequence()
    ds.ReferencedRTPlanSequence = refd_rt_plan_sequence

    # Referenced RT Plan Sequence: Referenced RT Plan 1
    refd_rt_plan1 = Dataset()
    refd_rt_plan1.ReferencedSOPClassUID = '1.2.840.10008.5.1.4.1.1.481.8' ### different for phantoms??? check
    refd_rt_plan1.ReferencedSOPInstanceUID = rtplan.SOPInstanceUID.strip()

    if not plandose:
        # Referenced Fraction Group Sequence ## ONLY FOR BEAMS
        refd_frxn_gp_sequence = Sequence() ## ONLY FOR BEAMS
        refd_rt_plan1.ReferencedFractionGroupSequence = refd_frxn_gp_sequence ## ONLY FOR BEAMS

        # Referenced Fraction Group Sequence: Referenced Fraction Group 1 ## ONLY FOR BEAMS
        refd_frxn_gp1 = Dataset() ## ONLY FOR BEAMS

        # Referenced Beam Sequence ## ONLY FOR BEAMS
        refd_beam_sequence = Sequence() ## ONLY FOR BEAMS
        refd_frxn_gp1.ReferencedBeamSequence = refd_beam_sequence ## ONLY FOR BEAMS

        # Referenced Beam Sequence: Referenced Beam 1 ## ONLY FOR BEAMS
        refd_beam1 = Dataset() ## ONLY FOR BEAMS
        refd_beam1.ReferencedBeamNumber = beamnr ### ## ONLY FOR BEAMS
        refd_beam_sequence.append(refd_beam1) ## ONLY FOR BEAMS

        refd_frac_grp_nr = None
        for f in rtplan.FractionGroupSequence:
            fnr = str(f.FractionGroupNumber)
            if refd_frac_grp_nr is None:
                # In case the beam number is not actually found, this is a bit of a lie.
                # But we have to survive somehow when the user feeds us illegal DICOM plan files from PDM.
                refd_frac_grp_nr = fnr
            for refb in f.ReferencedBeamSequence:
                if str(refb.ReferencedBeamNumber) == str(beamnr):
                    refd_frac_grp_nr = fnr
                    break
        refd_frxn_gp1.ReferencedFractionGroupNumber = refd_frac_grp_nr ## ONLY FOR BEAMS
        refd_frxn_gp_sequence.append(refd_frxn_gp1) ## ONLY FOR BEAMS
    refd_rt_plan_sequence.append(refd_rt_plan1)

    ds.PixelData = np.ones((9,9,9),dtype=np.uint16).tobytes() ### overwrite by postprocessing

    ds.file_meta = file_meta
    ds.is_implicit_VR = True
    ds.is_little_endian = True
    ds.save_as(filename, write_like_original=False) ###
예제 #21
0
def create_rtss_dataset(dicoms_sorted, structure_label):
    rf = dicoms_sorted[0]['dataset']

    SOP_class_UID = '1.2.840.10008.5.1.4.1.1.481.3'
    SOP_inst_UID, ser_inst_UID = generate_uid(), generate_uid()
    dt0 = datetime.min
    date0, time0 = dt0.strftime("%Y%m%d"), dt0.strftime("%H%M%S")
    dt = datetime.now()
    date, time = dt.strftime("%Y%m%d"), dt.strftime("%H%M%S")

    meta = Dataset()
    meta.FileMetaInformationGroupLength = 198
    meta.FileMetaInformationVersion = bytes('01', 'utf-8')  # '\x00\x01'
    meta.MediaStorageSOPClassUID = SOP_class_UID
    meta.MediaStorageSOPInstanceUID = SOP_inst_UID
    meta.TransferSyntaxUID = '1.2.840.10008.1.2'
    meta.ImplementationClassUID = '1.2.40.0.13.1.1.1'
    meta.ImplementationVersionName = u'1.0'

    r = Dataset()
    r.Manufacturer, r.StructureSetLabel, r.file_meta = u'NRG', structure_label, meta
    r.OperatorsName = u'nifti2rtss'
    r.is_implicit_VR, r.is_little_endian = True, True
    r.SpecificCharacterSet = 'ISO_IR 100'
    r.InstanceCreationDate = date
    r.InstanceCreationTime = time
    r.SOPClassUID = SOP_class_UID
    r.SOPInstanceUID = SOP_inst_UID
    r.InstanceNumber = '1'
    r.SeriesNumber = None

    r.StudyDate = rf.StudyDate if 'StudyDate' in rf else date0
    r.StudyTime = rf.StudyTime if 'StudyTime' in rf else time0

    r.AccessionNumber = rf.AccessionNumber if 'AccessionNumber' in rf else None
    r.StudyDescription, r.StudyInstanceUID, r.StudyID = rf.StudyDescription, rf.StudyInstanceUID, rf.StudyID

    r.PatientName, r.PatientID = rf.PatientName, rf.PatientID
    r.PatientBirthDate = ''
    r.PatientSex, r.ReferringPhysicianName = rf.PatientSex, rf.ReferringPhysicianName

    r.Modality = 'RTSTRUCT'
    r.SeriesInstanceUID = ser_inst_UID
    r.SeriesDescription = u'RTSS generated by nifti2rtss'
    r.SeriesDate, r.SeriesTime = date, time
    r.StructureSetDate, r.StructureSetTime = date, time

    #1. referenced frame of reference sequence
    referenced_frame_of_ref_seq = Sequence()
    r.ReferencedFrameOfReferenceSequence = referenced_frame_of_ref_seq

    #2. Referenced frame of reference #1
    referenced_frame_of_ref1 = Dataset()
    referenced_frame_of_ref1.FrameOfReferenceUID = rf.FrameOfReferenceUID

    #3. RT referenced study sequence
    rt_referenced_study_seq = Sequence()
    referenced_frame_of_ref1.RTReferencedStudySequence = rt_referenced_study_seq

    #4. RT referenced study sequence, study #1
    rt_referenced_study1 = Dataset()
    rt_referenced_study1.ReferencedSOPClassUID = rf.SOPClassUID
    rt_referenced_study1.ReferencedSOPInstanceUID = rf.StudyInstanceUID

    #5. RT referenced series sequence
    rt_referenced_series_seq = Sequence()
    rt_referenced_study1.RTReferencedSeriesSequence = rt_referenced_series_seq

    #6. RT referenced series 1
    rt_referenced_series1 = Dataset()
    rt_referenced_series1.SeriesInstanceUID = rf.SeriesInstanceUID

    #7. Contour image sequence
    contour_image_sequence = Sequence()
    rt_referenced_series1.ContourImageSequence = contour_image_sequence

    #Loop over all DICOM images
    for dcms in dicoms_sorted:  #range(1,numberOfDicomImages+1):
        dstemp = dcms['dataset']
        # Contour Image Sequence: Contour Image
        contour_image = Dataset()
        contour_image.ReferencedSOPClassUID = dstemp.SOPClassUID
        contour_image.ReferencedSOPInstanceUID = dstemp.SOPInstanceUID
        contour_image_sequence.append(contour_image)

    #append all sequences
    rt_referenced_series_seq.append(rt_referenced_series1)
    #print('rt_referenced_series_seq', rt_referenced_series_seq)
    rt_referenced_study_seq.append(rt_referenced_study1)
    referenced_frame_of_ref_seq.append(referenced_frame_of_ref1)

    #8. Structure set ROI sequence
    structure_set_roi_sequence = Sequence()
    r.StructureSetROISequence = structure_set_roi_sequence

    # Structure set ROI #1
    #structure_set_roi1=Dataset(); ssr1=structure_set_roi1
    #ssr1.ROINumber,ROIName,ROIDescription="1","na","na"
    #ssr1.ROIGenerationAlgorithm='AUTOMATIC'
    #structure_set_roi_sequence.append(ssr1)

    return r
예제 #22
0
logging.basicConfig(filename='pynetdicom_query.log',
                    filemode='w',
                    format='%(name)s - %(levelname)s - %(message)s')
LOGGER = logging.getLogger('pynetdicom')
LOGGER.setLevel(logging.DEBUG)

scu_ae = os.environ.get('AE_TITLE')

ae = AE(ae_title=scu_ae)  # SCU

ae.add_requested_context(ModalityWorklistInformationFind)

ds = Dataset()
ds.PatientName = '*'
ds.StudyDate = ''
ds.AccessionNumber = '2198270A'
ds.PatientID = ''
ds.StudyInstanceUID = ''
ds.QueryRetrieveLevel = 'STUDY'
ds.ScheduledProcedureStepSequence = [Dataset()]
item = ds.ScheduledProcedureStepSequence[0]
item.modality = ''

# associate with SCP
scp_ip = os.environ.get('SCP_IP')
scp_ae = os.environ.get('SCP_AE')
assoc = ae.associate(scp_ip, 5010, ae_title=scp_ae)

if assoc.is_established:
    responses = assoc.send_c_find(ds, ModalityWorklistInformationFind)
예제 #23
0
def handle_find(event):
    print("cfind fired")
    #    """Handle a C-FIND request event."""
    ds = event.identifier
    print("Query:")
    for elem in ds:
        print(elem)

    if 'QueryRetrieveLevel' not in ds:
        print("fail!")
        # Failure
        yield 0xC000, None
        return
    #===================================================================================
    #print(instances)
    if ds.QueryRetrieveLevel == 'PATIENT':
        if 'PatientName' in ds:
            if ds.PatientName not in ['*', '', '?']:
                matching = [
                    inst for inst in instances if inst.PatientName == ds.PatientName
                ]
    #====================================================================================
    if ds.QueryRetrieveLevel == 'STUDY':
        print("context=Study")
        identifier = Dataset()
        identifier.PatientName ='DUMMY'
        identifier.QueryRetrieveLevel = ds.QueryRetrieveLevel
        yield (0xFF00, identifier)
    #====================================================================================
    if ds.QueryRetrieveLevel == 'WORKLIST':
        print("context=worklist")
        #posible keys
        print("modality: ["+str(ds.Modality)+"]")
        print("studyDate: ["+str(ds.StudyDate)+"]")
        #print("StudyDesciption: "+str(ds.StudyDesciption))
        # TODO 
        # Procesador del query
        # generar un dataset menor cuando se procesan el query, recorriendo ese dataset y generaldo la salida
        # usar los datos de entrada

        for st in DB:
            # Check if C-CANCEL has been received
            if event.is_cancelled:
                yield (0xFE00, None)
                return
            # ver match de modalidad
            #print(st['mod'])
            now = datetime.datetime.now()
            #--conditionals
            
            if st['mod'] == ds.Modality and st['fecha']==now.strftime("%Y-%m-%d"):
                print("biuld...")
                #print(str(st['fecha']))
                identifier = Dataset()
                identifier.QueryRetrieveLevel = ds.QueryRetrieveLevel
                identifier.PatientName =str(st['dicomname'])
                identifier.AccessionNumber =str(st['AccessionNumber'])
                identifier.PatientSex=str(st['patient_sex'])
                identifier.StudyDescription=str(st['procedure'])
                #
                identifier.StudyDate=str(st['fecha'].replace("-",''))
                #identifier.PatientID =
                identifier.Modality =str(st['mod'])
                yield (0xFF00, identifier)
        yield(0x0000,NULL)
예제 #24
0
    def generate_dicom(self, file_out_name: str, gantry_angle: float = 0.0, coll_angle: float = 0.0,
                       table_angle: float = 0.0):
        # make image look like an EPID with flipped data (dose->low)
        flipped_image = -self.image + self.image.max() + self.image.min()

        # File meta info data elements
        file_meta = FileMetaDataset()

        # Main data elements
        ds = Dataset()
        ds.ImageType = ['DERIVED', 'SECONDARY', 'PORTAL']
        ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.481.1'
        ds.SOPInstanceUID = '1.2.840.113854.323870129946883845737820671794195198978.1.1'
        ds.StudyDate = '20140819'
        ds.ContentDate = '20140819'
        ds.StudyTime = '130944'
        ds.ContentTime = '130944'
        ds.AccessionNumber = ''
        ds.Modality = 'RTIMAGE'
        ds.ConversionType = 'WSD'
        ds.Manufacturer = 'IMPAC Medical Systems, Inc.'
        ds.ReferringPhysicianName = ''
        ds.StudyDescription = 'QA'
        ds.SeriesDescription = 'Q + Couch_270'
        ds.PhysiciansOfRecord = 'I am king'
        ds.OperatorsName = ''
        ds.ManufacturerModelName = 'MOSAIQ'
        ds.PatientName = 'Albert Einstein'
        ds.PatientID = 'abc123'
        ds.PatientBirthDate = ''
        ds.SoftwareVersions = '2.41.01J0'
        ds.StudyInstanceUID = '1.2.840.113854.323870129946883845737820671794195198978'
        ds.SeriesInstanceUID = '1.2.840.113854.323870129946883845737820671794195198978.1'
        ds.StudyID = '348469'
        ds.SeriesNumber = "4290463"
        ds.InstanceNumber = "0"
        ds.PatientOrientation = ''
        ds.PositionReferenceIndicator = ''
        ds.SamplesPerPixel = 1
        ds.PhotometricInterpretation = 'MONOCHROME2'
        ds.Rows = self.shape[0]
        ds.Columns = self.shape[1]
        ds.BitsAllocated = 16
        ds.BitsStored = 16
        ds.HighBit = 15
        ds.PixelRepresentation = 0
        ds.RTImageLabel = 'Q'
        ds.RTImagePlane = 'NORMAL'
        ds.XRayImageReceptorAngle = "0.0"
        ds.ImagePlanePixelSpacing = [self.pixel_size, self.pixel_size]
        ds.RTImagePosition = [-200.70400, 150.523400]
        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.CurveDimensions = 2
        # ds.NumberOfPoints = 4
        # ds.TypeOfData = 'ROI'
        # ds.CurveDescription = 'VContour 30'
        # ds.AxisUnits = ['PIXL', 'PIXL']
        # ds.DataValueRepresentation = 3
        # ds.CurveLabel = 'Field Edge (Q:MV)'
        # ds.CurveData = b'\x00\x00\x00\x00 .\x81@\x00\x00\x00\x00\x10\\z@\x00\x00\x00\x00 .\x81@\x00\x00\x00\x00\x90\x93u@\x00\x00\x00\x00\xc0\x93}@\x00\x00\x00\x00\x90\x93u@\x00\x00\x00\x00\xc0\x93}@\x00\x00\x00\x00\x10\\z@'
        ds.PixelData = flipped_image  # XXX Array of 1572864 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)