def _update_deidentification_method(self, dataset: pydicom.dataset.Dataset) -> None: if "DeidentificationMethod" not in dataset: dataset.DeidentificationMethod = "DICOGNITO" return existing_element = dataset.data_element("DeidentificationMethod") assert existing_element is not None # satisfy mypy existing_value = existing_element.value if isinstance(existing_value, pydicom.multival.MultiValue): if "DICOGNITO" not in existing_value: existing_value.append("DICOGNITO") elif existing_value != "DICOGNITO": existing_element.value = [existing_value, "DICOGNITO"]
def anonymize(self, dataset: pydicom.dataset.Dataset) -> None: """\ Anonymize a dataset in place. Replaces all PNs, UIs, dates and times, and known identifiying attributes with other vlaues. Parameters ---------- dataset : pydicom.dataset.Dataset A DICOM dataset to anonymize. """ dataset.file_meta.walk(self._anonymize_element) dataset.walk(self._anonymize_element) self._update_deidentification_method(dataset) self._update_patient_identity_removed(dataset)
def _set_study_attributes(dataset: pydicom.dataset.Dataset, patient_number: int, study_number: int) -> None: dataset.StudyID = "STUDYFOR4MR" + str(patient_number) + "." + str(study_number) dataset.AccessionNumber = "ACC" + dataset.StudyID dataset.StudyDate = datetime.date(2004, patient_number, study_number).strftime("%Y%m%d") dataset.StudyTime = datetime.time(patient_number * 5 + study_number, 0, 0).strftime("%H%M%S") dataset.StudyInstanceUID = "1.3.6.1.4.1.5962.20040827145012.5458." + str(patient_number) + "." + str(study_number) dataset.NameOfPhysiciansReadingStudy = "READING^FIRST^" + dataset.StudyID dataset.RequestingPhysician = "REQUESTING1^FIRST^" + dataset.StudyID dataset.ReferringPhysicianName = "REFERRING1^FIRST^" + dataset.StudyID
def anonymize_institution_name(self, dataset: pydicom.dataset.Dataset, data_element: pydicom.DataElement) -> None: region = self.address_anonymizer.get_region(data_element.value) street_address = self.address_anonymizer.get_street_address( data_element.value) street = street_address.split(" ", 1)[1] dataset.InstitutionAddress = ", ".join([ street_address, region, self.address_anonymizer.get_country(data_element.value) ]) data_element.value = region + "'S " + street + " CLINIC"
def _anonymize_date_and_time(self, dataset: pydicom.dataset.Dataset, data_element: pydicom.DataElement) -> None: date_value = data_element.value if isinstance(data_element.value, pydicom.multival.MultiValue): dates = list([v for v in data_element.value]) else: dates = [data_element.value] times = [] time_name = data_element.keyword.replace("Date", "Time") if time_name in dataset: time_element = dataset.data_element(time_name) time_value = time_element.value # type: ignore[union-attr] if time_value: if isinstance(time_value, pydicom.multival.MultiValue): times = list([v for v in time_value]) else: times = [time_value] new_dates = [] new_times = [] for i in range(len(dates)): date_value = dates[i] date_format = "%Y%m%d"[: len(date_value) - 2] old_date = datetime.datetime.strptime(date_value, date_format).date() time_value = "" old_hours = datetime.time() if i < len(times): time_value = times[i] if time_value: old_hours = datetime.datetime.strptime(time_value[:2], "%H").time() else: old_hours = datetime.time() old_datetime = datetime.datetime.combine(old_date, old_hours) new_datetime = old_datetime + self.offset new_dates.append(new_datetime.strftime(date_format)) new_times.append(new_datetime.strftime("%H") + time_value[2:]) new_dates_string = "\\".join(new_dates) new_times_string = "\\".join(new_times) data_element.value = new_dates_string if times: time_element.value = new_times_string # type: ignore[union-attr]
def get_new_ds(ds: pydicom.dataset.Dataset, name: str): """ Create a new dicom header. Creates a new dataset object and sets all existing fields in ds. :param ds: old dataset to base this new one off of :param name: name for this file :return: The new dicom dataset object with all header information. No pixel data. """ file_meta = ds.file_meta new_ds = pydicom.dataset.FileDataset( name, {}, file_meta=file_meta, preamble=b"\0" * 128, is_implicit_VR=ds.is_implicit_VR, is_little_endian=ds.is_little_endian) a = [ attr for attr in dir(ds) if not attr.startswith('__') and not callable(getattr(ds, attr)) ] for attr in a: if attr in [ '_character_set', 'is_original_encoding', 'pixel_array', 'BitsAllocated', 'BitsStored', 'HighBit', 'PixelRepresentation', 'PixelData' ]: continue else: new_ds.__setattr__(attr, ds.__getattr__(attr)) # fix bits new_ds.BitsAllocated = 8 new_ds.BitsStored = 8 new_ds.HighBit = 7 new_ds.PixelRepresentation = 0 return new_ds
def _set_series_attributes( dataset: pydicom.dataset.Dataset, patient_number: int, study_number: int, series_number: int ) -> None: series_suffix = "%(patient_number)-d%(study_number)-d%(series_number)d" % vars() dataset.SeriesInstanceUID = dataset.StudyInstanceUID + "." + str(series_number) dataset.FrameOfReferenceUID = dataset.SeriesInstanceUID + ".0." + str(series_number) dataset.PerformedProcedureStepID = "PERFSTEP" + series_suffix dataset.RequestedProcedureID = "REQSTEP" + series_suffix dataset.ScheduledProcedureStepID = "SCHEDSTEP" + series_suffix dataset.SeriesDate = dataset.StudyDate dataset.SeriesTime = datetime.time(patient_number, study_number, series_number).strftime("%H%M%S") dataset.StationName = "STATIONNAME" + str(patient_number) + "." + str(study_number) + "." + str(series_number) dataset.OperatorsName = "OPERATOR^FIRST^" + series_suffix dataset.PerformingPhysicianName = "PERFORMING1^FIRST^" + series_suffix request_attribute_item = pydicom.dataset.Dataset() request_attribute_item.RequestedProcedureID = dataset.RequestedProcedureID request_attribute_item.ScheduledProcedureStepID = dataset.ScheduledProcedureStepID dataset.RequestAttributesSequence = pydicom.sequence.Sequence([request_attribute_item]) dataset.InstitutionName = "INSTITUTIONNAME" + series_suffix dataset.InstitutionAddress = "INSTITUTIONADDRESS" + series_suffix dataset.InstitutionalDepartmentName = "INSTITUTIONALDEPARTMENTNAME" + series_suffix dataset.StationName = "STATIONNAME" + series_suffix
def _set_patient_attributes(dataset: pydicom.dataset.Dataset, patient_number: int) -> None: dataset.PatientAddress = str(123 + patient_number) + " Fake Street" dataset.PatientBirthDate = str(19830213 + patient_number) dataset.PatientBirthTime = "13:14:0" + str(patient_number) dataset.PatientID = "4MR" + str(patient_number) dataset.PatientName = "CompressedSamples^MR" + str(patient_number) dataset.OtherPatientIDs = "OTH" + dataset.PatientID dataset.OtherPatientIDsSequence = [pydicom.dataset.Dataset()] dataset.OtherPatientIDsSequence[0].PatientID = "OTHSEQ" + dataset.PatientID dataset.OtherPatientNames = "Other" + str(dataset.PatientName) dataset.PatientBirthName = "Birth" + str(dataset.PatientName) dataset.PatientMotherBirthName = "Mother" + str(dataset.PatientName) dataset.ResponsiblePerson = "Responsible" + str(dataset.PatientName)
def _update_patient_identity_removed(self, dataset: pydicom.dataset.Dataset) -> None: if dataset.get("BurnedInAnnotation", "YES") == "NO": dataset.PatientIdentityRemoved = "YES"
def _should_assume_annotation(self, dataset: pydicom.dataset.Dataset) -> bool: burned_in_annotation = dataset.get("BurnedInAnnotation") return (self.assume_if == "if-yes" and burned_in_annotation == "YES") or (self.assume_if == "unless-no" and burned_in_annotation != "NO")