# HG changeset patch # User amazy # Date 1567513724 -7200 # Node ID 02c3d91b155c210ad5fcfe23ed55b57d3213eddb # Parent 05b77ade5e1dcdd93402eabd43e90ebec5baacbe added anonymization test for RTH data (currently failing) diff -r 05b77ade5e1d -r 02c3d91b155c Database/HierarchicalAnonymization/RTH/CT01.dcm Binary file Database/HierarchicalAnonymization/RTH/CT01.dcm has changed diff -r 05b77ade5e1d -r 02c3d91b155c Database/HierarchicalAnonymization/RTH/RT.dcm Binary file Database/HierarchicalAnonymization/RTH/RT.dcm has changed diff -r 05b77ade5e1d -r 02c3d91b155c Database/README.txt --- a/Database/README.txt Wed Aug 28 16:50:36 2019 +0200 +++ b/Database/README.txt Tue Sep 03 14:28:44 2019 +0200 @@ -61,6 +61,7 @@ - Comunix/* : From OsiriX, "COMUNIX" (sample of PET/CT study). - DummyCT.dcm : From Osirix, "KNIX" with PixelData removed. - HierarchicalAnonymization/StructuredReports/* : Courtesy of Collective Minds Radiology AB +- HierarchicalAnonymization/RTH/* : From https://wiki.cancerimagingarchive.net/display/Public/Lung+CT+Segmentation+Challenge+2017 - Issue16.dcm : From Chris Hafey on Google Code (AT VR's are not returned properly as JSON) - Issue19.dcm : From Chris Hafey on Google Code (YBR_FULL are not decoded incorrectly) - Issue22.dcm : From Emsy Chan on Google Code (Error decoding multi-frame instances) diff -r 05b77ade5e1d -r 02c3d91b155c Tests/Tests.py --- a/Tests/Tests.py Wed Aug 28 16:50:36 2019 +0200 +++ b/Tests/Tests.py Tue Sep 03 14:28:44 2019 +0200 @@ -4669,6 +4669,81 @@ cr[0]['MainDicomTags']['SeriesInstanceUID']) + def test_anonymize_relationships_5(self): + ct1 = UploadInstance(_REMOTE, 'HierarchicalAnonymization/RTH/CT01.dcm') + rt1 = UploadInstance(_REMOTE, 'HierarchicalAnonymization/RTH/RT.dcm') + oStudyId = ct1['ParentStudy'] + oCtInstanceId = ct1['ID'] + oRtInstanceId = rt1['ID'] + + oCtTags = DoGet(_REMOTE, '/instances/%s/tags?simplify' % oCtInstanceId) + oRtTags = DoGet(_REMOTE, '/instances/%s/tags?simplify' % oRtInstanceId) + + # first validate the relationships in the source data + oStudyUID = oCtTags['StudyInstanceUID'] + oRtSeriesUID = oRtTags['SeriesInstanceUID'] + oRtInstanceUID = oRtTags['SOPInstanceUID'] + oRtFrameOfReferenceUID = oRtTags['ReferencedFrameOfReferenceSequence'][0]['FrameOfReferenceUID'] + oCtSeriesUID = oCtTags['SeriesInstanceUID'] + oCtInstanceUID = oCtTags['SOPInstanceUID'] + oCtFrameOfReferenceUID = oCtTags['FrameOfReferenceUID'] + + oContourSequenceCount = len(oRtTags['ROIContourSequence'][0]['ContourSequence']) + self.assertEqual(oCtFrameOfReferenceUID, oRtFrameOfReferenceUID) + self.assertEqual(oStudyUID, oRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['ReferencedSOPInstanceUID']) + self.assertEqual(oCtSeriesUID, oRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['RTReferencedSeriesSequence'][0]['SeriesInstanceUID']) + self.assertEqual(oCtInstanceUID, oRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['RTReferencedSeriesSequence'][0]['ContourImageSequence'][0]['ReferencedSOPInstanceUID']) + self.assertEqual(oCtInstanceUID, oRtTags['ROIContourSequence'][0]['ContourSequence'][oContourSequenceCount-1]['ContourImageSequence'][0]['ReferencedSOPInstanceUID']) + + ### anonymize + + aStudyId = DoPost(_REMOTE, '/studies/%s/anonymize' % oStudyId, '{}', + 'application/json')['ID'] + + ### validate + + aSeries = DoGet(_REMOTE, '/studies/%s/series' % aStudyId) + self.assertEqual(2, len(aSeries)) + + aCt = list(filter(lambda x: x['MainDicomTags']['Modality'] == 'CT', aSeries)) + aRt = list(filter(lambda x: x['MainDicomTags']['Modality'] == 'RTSTRUCT', aSeries)) + + aCtInstanceId = aCt[0]['Instances'][0] + aRtInstanceId = aRt[0]['Instances'][0] + + aCtTags = DoGet(_REMOTE, '/instances/%s/tags?simplify' % aCtInstanceId) + aRtTags = DoGet(_REMOTE, '/instances/%s/tags?simplify' % aRtInstanceId) + + # now validate the relationships in the anonymized data + aStudyUID = aCtTags['StudyInstanceUID'] + aRtSeriesUID = aRtTags['SeriesInstanceUID'] + aRtInstanceUID = aRtTags['SOPInstanceUID'] + aRtFrameOfReferenceUID = aRtTags['ReferencedFrameOfReferenceSequence'][0]['FrameOfReferenceUID'] + aCtSeriesUID = aCtTags['SeriesInstanceUID'] + aCtInstanceUID = aCtTags['SOPInstanceUID'] + aCtFrameOfReferenceUID = aCtTags['FrameOfReferenceUID'] + + aContourSequenceCount = len(aRtTags['ROIContourSequence'][0]['ContourSequence']) + # make sure all UIDs have been updated + self.assertNotEqual(oStudyUID, aStudyUID) + self.assertNotEqual(oRtSeriesUID, aRtSeriesUID) + self.assertNotEqual(oRtInstanceUID, aRtInstanceUID) + self.assertNotEqual(oRtFrameOfReferenceUID, aRtFrameOfReferenceUID) + self.assertNotEqual(oCtSeriesUID, aCtSeriesUID) + self.assertNotEqual(oCtInstanceUID, aCtInstanceUID) + self.assertNotEqual(oCtFrameOfReferenceUID, aCtFrameOfReferenceUID) + + # validate the relationships + self.assertEqual(oContourSequenceCount, aContourSequenceCount) + self.assertEqual(aCtFrameOfReferenceUID, aRtFrameOfReferenceUID) + # fails !!! self.assertEqual(aStudyUID, aRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['ReferencedSOPInstanceUID']) + # fails !!! self.assertEqual(aCtSeriesUID, aRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['RTReferencedSeriesSequence'][0]['SeriesInstanceUID']) + self.assertEqual(aCtInstanceUID, aRtTags['ReferencedFrameOfReferenceSequence'][0]['RTReferencedStudySequence'][0]['RTReferencedSeriesSequence'][0]['ContourImageSequence'][0]['ReferencedSOPInstanceUID']) + self.assertEqual(aCtInstanceUID, aRtTags['ROIContourSequence'][0]['ContourSequence'][aContourSequenceCount-1]['ContourImageSequence'][0]['ReferencedSOPInstanceUID']) + + + + @unittest.skip('Not fixed yet in Orthanc') def test_bitbucket_issue_140(self): source = UploadInstance(_REMOTE, 'Issue140.dcm') ['ID']