Skip to content

Commit

Permalink
test databasis and instance diff test
Browse files Browse the repository at this point in the history
  • Loading branch information
lmdulz committed Sep 28, 2023
1 parent 3751750 commit c09cc97
Show file tree
Hide file tree
Showing 3 changed files with 369 additions and 1 deletion.
237 changes: 237 additions & 0 deletions tests/data_for_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
import { data } from "dcmjs";
import * as fs from "fs";

export function loadInstance(
patientNumber = 1,
studyNumber = 1,
seriesNumber = 1,
instanceNumber = 1
): data.DicomDict {
const dataset = loadMinimalInstance();
_setPatientAttributes(dataset, patientNumber);
_setStudyAttributes(dataset, patientNumber, studyNumber);
_setSeriesAttributes(dataset, patientNumber, studyNumber, seriesNumber);
_setInstanceAttributes(dataset, patientNumber, studyNumber, seriesNumber, instanceNumber);
return dataset;
}

export function loadMinimalInstance(): data.DicomDict {
const filePath_dicom = "./samples";
const files: string[] = fs.readdirSync(filePath_dicom);
const fileBuffer = fs.readFileSync(filePath_dicom + "/" + files[0]).buffer;
return data.DicomMessage.readFile(fileBuffer);
}

export function loadTestInstance(): data.DicomDict {
const dataset = loadMinimalInstance();
const sourceImageDataset = new data.DicomDict({});
populateTag(sourceImageDataset, "ReferencedSOPClassUID", "1.2.3.0.1");
populateTag(sourceImageDataset, "ReferencedSOPInstanceUID", "1.2.3.1.1");
populateTag(dataset, "SourceImageSequence", [sourceImageDataset.dict]);

populateTag(dataset, "OperatorsName", "OPERATOR^FIRST^MIDDLE");
populateTag(dataset, "NameOfPhysiciansReadingStudy", "READING^FIRST^MIDDLE");
populateTag(dataset, "PerformingPhysicianName", "PERFORMING^FIRST^MIDDLE");
populateTag(dataset, "ReferringPhysicianName", "REFERRING^FIRST^MIDDLE");
populateTag(dataset, "RequestingPhysician", "REQUESTING^FIRST^MIDDLE");
populateTag(dataset, "ResponsiblePerson", "RESPONSIBLE^FIRST^MIDDLE");
populateTag(dataset, "PatientBirthName", "PBN");
populateTag(dataset, "PatientMotherBirthName", "PMBN");

populateTag(dataset, "PatientAddress", "10 REAL STREET");
populateTag(dataset, "RegionOfResidence", "BROAD COVE");
populateTag(dataset, "CountryOfResidence", "GERMANY");

populateTag(dataset, "IssuerOfPatientID", "ISSUEROFPATIENTID");
populateTag(dataset, "OtherPatientIDs", "OTHERPATIENTID");
populateTag(dataset, "PerformedProcedureStepID", "PERFORMEDID");
populateTag(dataset, "ScheduledProcedureStepID", "SCHEDULEDID");

populateTag(dataset, "FillerOrderNumberImagingServiceRequest", "");
populateTag(dataset, "PlacerOrderNumberImagingServiceRequest", "");

populateTag(dataset, "Occupation", "VIGILANTE");
const codeDataset = new data.DicomDict({});
populateTag(codeDataset, "CodeValue", "VALUE");
populateTag(codeDataset, "CodingSchemeDesignator", "DESIGNATOR");
populateTag(codeDataset, "CodeMeaning", "MEANING");
populateTag(dataset, "PatientInsurancePlanCodeSequence", codeDataset.dict);
populateTag(dataset, "MilitaryRank", "YEOMAN");
populateTag(dataset, "BranchOfService", "COAST GUARD");
populateTag(dataset, "PatientTelephoneNumbers", "123-456-7890");
populateTag(dataset, "PatientTelecomInformation", "123-456-7890");
populateTag(dataset, "PatientReligiousPreference", "PRIVATE");
populateTag(dataset, "MedicalRecordLocator", "FILING CABINET 1");

const referenced_sop_item = new data.DicomDict({});
populateTag(referenced_sop_item, "ReferencedSOPClassUID", "2.3.4.5.6.7");
populateTag(referenced_sop_item, "ReferencedSOPInstanceUID", "2.3.4.5.6.7.1.2.3");
const item = new data.DicomDict({});
populateTag(item, "TypeOfInstances", "DICOM");
populateTag(item, "StudyInstanceUID", "1.2.3.4.5.6");
populateTag(item, "SeriesInstanceUID", "1.2.3.4.5.6.1");
populateTag(item, "ReferencedSOPSequence", referenced_sop_item.dict);
populateTag(dataset, "ReferencedPatientPhotoSequence", item.dict);

populateTag(dataset, "ResponsibleOrganization", "RESPONSIBLE ORGANIZATION");

const other_patient_id_item0 = new data.DicomDict({});
populateTag(other_patient_id_item0, "PatientID", "opi-0-ID");
populateTag(other_patient_id_item0, "IssuerOfPatientID", "ISSUER");
const other_patient_id_item1 = new data.DicomDict({});
populateTag(other_patient_id_item1, "PatientID", "opi-1-ID");
populateTag(other_patient_id_item1, "IssuerOfPatientID", "ISSUER");
populateTag(dataset, "OtherPatientIDsSequence", [
other_patient_id_item0.dict,
other_patient_id_item1.dict,
]);

const request_attribute_item = new data.DicomDict({});
populateTag(request_attribute_item, "RequestedProcedureID", "rai-0-REQID");
populateTag(request_attribute_item, "ScheduledProcedureStepID", "rai-0-SCHEDID");
populateTag(dataset, "RequestAttributesSequence", request_attribute_item.dict);

populateTag(dataset, "InstitutionName", "INSTITUTIONNAME");
populateTag(dataset, "InstitutionAddress", "INSTITUTIONADDRESS");
populateTag(dataset, "InstitutionalDepartmentName", "INSTITUTIONALDEPARTMENTNAME");
populateTag(dataset, "StationName", "STATIONNAME");

populateTag(dataset, "RequestingService", "REQESTINGSERVICE");
populateTag(dataset, "CurrentPatientLocation", "PATIENTLOCATION");

return dataset;
}

function _setPatientAttributes(dataset: data.DicomDict, patientNumber: number): void {
populateTag(dataset, "PatientAddress", `${123 + patientNumber} Fake Street`);
populateTag(dataset, "PatientBirthDate", `${19830213 + patientNumber}`);
populateTag(dataset, "PatientBirthTime", `13140${patientNumber}`);
populateTag(dataset, "PatientID", `4MR${patientNumber}`);
populateTag(dataset, "PatientName", `CompressedSamples^MR${patientNumber}`);
populateTag(dataset, "OtherPatientIDs", `OTH${dataset.dict["00100020"].Value[0]}`); //PatientID
const other_patient_id_item = new data.DicomDict({});
populateTag(other_patient_id_item, "PatientID", `OTHSEQ${dataset.dict["00100020"].Value[0]}`); //PatientID
populateTag(dataset, "OtherPatientIDsSequence", other_patient_id_item.dict);

populateTag(dataset, "OtherPatientNames", `Other${dataset.dict["00100010"].Value[0]}`); //PatientName
populateTag(dataset, "PatientBirthName", `Birth${dataset.dict["00100010"].Value[0]}`); //PatientName
populateTag(dataset, "PatientMotherBirthName", `Mother${dataset.dict["00100010"].Value[0]}`); //PatientName
populateTag(dataset, "ResponsiblePerson", `Responsible${dataset.dict["00100010"].Value[0]}`); //PatientName
}

function _setStudyAttributes(
dataset: data.DicomDict,
patientNumber: number,
studyNumber: number
): void {
populateTag(dataset, "StudyID", `FOR4MR${patientNumber}.${studyNumber}`);
populateTag(dataset, "AccessionNumber", `ACC${dataset.dict["00200010"].Value[0]}`); //StudyID
populateTag(
dataset,
"StudyDate",
new Date(2004, patientNumber, studyNumber).toISOString().substring(0, 10).replace(/-/g, "")
);
populateTag(dataset, "StudyTime", `0${patientNumber * 5 + studyNumber}0000`);
populateTag(
dataset,
"StudyInstanceUID",
`1.3.6.1.4.1.5962.20040827145012.5458.${patientNumber}.${studyNumber}`
);
populateTag(
dataset,
"NameOfPhysiciansReadingStudy",
`READING^FIRST^${dataset.dict["00200010"].Value[0]}`
); //StudyID
populateTag(
dataset,
"RequestingPhysician",
`REQUESTING1^FIRST^${dataset.dict["00200010"].Value[0]}`
); //StudyID
populateTag(
dataset,
"ReferringPhysicianName",
`REFERRING1^FIRST^${dataset.dict["00200010"].Value[0]}`
); //StudyID
}

function _setSeriesAttributes(
dataset: data.DicomDict,
patientNumber: number,
studyNumber: number,
seriesNumber: number
): void {
const seriesSuffix = `${patientNumber}-${studyNumber}-${seriesNumber}`;
populateTag(dataset, "SeriesInstanceUID", `${dataset.dict["0020000D"].Value[0]}.${seriesNumber}`); //StudyInstanceUID
populateTag(
dataset,
"FrameOfReferenceUID",
`${dataset.dict["0020000E"].Value[0]}.0.${seriesNumber}`
); //SeriesInstanceUID
populateTag(dataset, "PerformedProcedureStepID", `PERFSTEP${seriesSuffix}`);
populateTag(dataset, "RequestedProcedureID", `REQSTEP${seriesSuffix}`);
populateTag(dataset, "ScheduledProcedureStepID", `SCHEDSTEP${seriesSuffix}`);

populateTag(dataset, "SeriesDate", dataset.dict["00080020"].Value[0]); //StudyDate
populateTag(dataset, "SeriesTime", `${patientNumber}${studyNumber}${seriesNumber}0000`);
populateTag(dataset, "StationName", `STATIONNAME${patientNumber}.${studyNumber}.${seriesNumber}`);
populateTag(dataset, "OperatorsName", `OPERATOR^FIRST^${seriesSuffix}`);
populateTag(dataset, "PerformingPhysicianName", `PERFORMING1^FIRST^${seriesSuffix}`);

const requestAttributeItem = new data.DicomDict({});
populateTag(requestAttributeItem, "RequestedProcedureID", `REQSTEP${seriesSuffix}`);
populateTag(requestAttributeItem, "ScheduledProcedureStepID", `SCHEDSTEP${seriesSuffix}`);
populateTag(dataset, "RequestAttributesSequence", requestAttributeItem.dict);

populateTag(dataset, "InstitutionName", `INSTITUTIONNAME${seriesSuffix}`);
populateTag(dataset, "InstitutionAddress", `INSTITUTIONADDRESS${seriesSuffix}`);
populateTag(dataset, "InstitutionalDepartmentName", `INSTITUTIONALDEPARTMENTNAME${seriesSuffix}`);
populateTag(dataset, "StationName", `STATIONNAME${seriesSuffix}`);
}

function _setInstanceAttributes(
dataset: data.DicomDict,
patientNumber: number,
studyNumber: number,
seriesNumber: number,
instanceNumber: number
): void {
populateTag(dataset, "SOPInstanceUID", `${dataset.dict["0020000E"].Value[0]}.${instanceNumber}`); //SeriesInstanceUID
populateMetaTag(dataset, "MediaStorageSOPInstanceUID", dataset.dict["00080018"].Value[0]); //SOPInstanceUID
populateTag(dataset, "InstanceCreationDate", dataset.dict["00080021"].Value[0]); //SeriesDate
const creationTime = new Date();
creationTime.setHours(patientNumber, studyNumber, 7 * seriesNumber + instanceNumber);
populateTag(
dataset,
"InstanceCreationTime",
creationTime.toTimeString().slice(0, 8).replace(/:/g, "")
);
}

function populateTag(
dataset: data.DicomDict,
tagName: string,
...values: string[] | object[]
): void {
const tagDict = data.DicomMetaDictionary.nameMap[tagName];
tagDict.tag = data.DicomMetaDictionary.unpunctuateTag(tagDict.tag);
dataset.upsertTag(tagDict.tag, tagDict.vr, values);
}

function populateMetaTag(
dataset: data.DicomDict,
tagName: string,
...values: string[] | object[]
): void {
const tagDict = data.DicomMetaDictionary.nameMap[tagName];
tagDict.tag = data.DicomMetaDictionary.unpunctuateTag(tagDict.tag);

if (dataset.meta[tagDict.tag]) {
dataset.meta[tagDict.tag].Value = values;
} else {
dataset.meta[tagDict.tag] = { vr: tagDict.vr, Value: values };
}
}

// // Usage example
// const instance = loadInstance(1, 1, 1, 1);
// console.log(instance);
131 changes: 131 additions & 0 deletions tests/test_anonymize_one_series_two_instances.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Import your Anonymizer class
import { data } from "dcmjs";
import { describe, expect, it, test } from "vitest";
// Import your data_for_tests module
import { Anonymizer } from "../src/anonymizer";
// Replace with your testing library imports
import { loadInstance } from "./data_for_tests";

// Replace with the actual structure of your dataset

class OneSeriesTwoInstances {
dataset1: data.DicomDict;
dataset2: data.DicomDict;

constructor() {
this.dataset1 = loadInstance(1, 1);
this.dataset2 = loadInstance(1, 2);

const anonymizer = new Anonymizer("");
anonymizer.anonymize(this.dataset1);
anonymizer.anonymize(this.dataset2);
}
}

describe("patient", () => {
it("should anonymize patient, study, and series attributes the same", () => {
const diffInstances = new OneSeriesTwoInstances();
const dataset1 = diffInstances.dataset1;
const dataset2 = diffInstances.dataset2;
const elementPaths: string[][] = [
// patient
["dict", "00100020"], // PatientID
["dict", "00101000"], // OtherPatientIDs
["dict", "00101002", "00100020"], // OtherPatientIDsSequence[0].PatientID
["dict", "00101001"], // OtherPatientNames
["dict", "00101040"], // PatientAddress
["dict", "00100030"], // PatientBirthDate
["dict", "00101005"], // PatientBirthName
["dict", "00100032"], // PatientBirthTime
["dict", "00101060"], // PatientMotherBirthName
["dict", "00100010"], // PatientName
["dict", "00102297"], // ResponsiblePerson
];

for (const elementPath of elementPaths) {
if (elementPath.length == 2) {
console.log(elementPath);
const value1 = dataset1[elementPath[0]][elementPath[1]].Value[0];
const value2 = dataset2[elementPath[0]][elementPath[1]].Value[0];
expect(value1).toBe(value2);
} else {
const value1 = dataset1[elementPath[0]][elementPath[1]].Value[0][elementPath[2]].Value[0];
const value2 = dataset2[elementPath[0]][elementPath[1]].Value[0][elementPath[2]].Value[0];
expect(value1).toEqual(value2);
}
}
});

it("should anonymize instance attributes differently", () => {
const diffInstances = new OneSeriesTwoInstances();
const dataset1 = diffInstances.dataset1;
const dataset2 = diffInstances.dataset2;
const elementPaths = [
// study
["dict", "0020000D"], // StudyInstanceUID
["dict", "00081060"], // NameOfPhysiciansReadingStudy
["dict", "00080090"], // ReferringPhysicianName
["dict", "00321032"], // RequestingPhysician
["dict", "00080050"], // AccessionNumber
["dict", "00080020"], // StudyDate
["dict", "00200010"], // StudyID
["dict", "00080030"], // StudyTime
// series
["dict", "0020000E"], // SeriesInstanceUID
["dict", "00081070"], // OperatorsName
["dict", "00081050"], // PerformingPhysicianName
["dict", "00400275", "00401001"], // RequestAttributesSequence[0].RequestedProcedureID
["dict", "00400275", "00400009"], // RequestAttributesSequence[0].ScheduledProcedureStepID
["dict", "00200052"], // FrameOfReferenceUID
["dict", "00080081"], // InstitutionAddress
["dict", "00080080"], // InstitutionName
["dict", "00400253"], // PerformedProcedureStepID
["dict", "00401001"], // RequestedProcedureID
["dict", "00400009"], // ScheduledProcedureStepID
["dict", "00080021"], // SeriesDate
["dict", "00080031"], // SeriesTime
// instance
["dict", "00080018"], //SOPInstanceUID
["meta", "00020003"], //MediaStorageSOPInstanceUID
["dict", "00080012"], //InstanceCreationDate
["dict", "00080013"], //InstanceCreationTime
];

for (const elementPath of elementPaths) {
if (elementPath.length == 2) {
const value1 = dataset1[elementPath[0]][elementPath[1]].Value[0];
const value2 = dataset2[elementPath[0]][elementPath[1]].Value[0];
expect(value1).not.toEqual(value2);
} else {
const value1 = dataset1[elementPath[0]][elementPath[1]].Value[0][elementPath[2]].Value[0];
const value2 = dataset2[elementPath[0]][elementPath[1]].Value[0][elementPath[2]].Value[0];
expect(value1).not.toEqual(value2);
}
}
});
});

// function testWalk(set1: data.DicomDict, set2: data.DicomDict, tags2Check){
// const tagList1 = Object.keys(set1.dict);
// const tagList2 = Object.keys(set2.dict);
// expect(tagList1).toEqual(tagList2)

// for (const tag of tagList1) {
// if (elementPaths.includes(tag)) {
// const element1 = set1.dict[tag];
// const element2 = set2.dict[tag];
// expect(element1).toBe(element2)

// // If the element is a sequence, recursively walk through its items
// if (element1.vr === "SQ" && element2.vr === "SQ") {
// for (let i = 0; i < element1.Value.length; i++) {
// const sequence1 = element1.Value;
// const sequence2 = element2.Value;
// for (const item of sequence) {
// this.walk(item, handler);
// }
// }
// }
// }
// }
// }
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
"target": "ES2015",
"tsBuildInfoFile": ".tsbuildinfo"
},
"include": ["src/**/*", "types/**/*", "tests/*"],
"include": ["src/**/*", "types/**/*", "tests/**/*"],
"exclude": ["node_modules"]
}

0 comments on commit c09cc97

Please sign in to comment.