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
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
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
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
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
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()
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
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
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()
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
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
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
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)
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
# 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 = ''
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)
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)
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
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)
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) ###
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
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)
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)
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)