changeset 255:02c3d91b155c

added anonymization test for RTH data (currently failing)
author amazy
date Tue, 03 Sep 2019 14:28:44 +0200
parents 05b77ade5e1d
children 397bcd1d16b2
files Database/HierarchicalAnonymization/RTH/CT01.dcm Database/HierarchicalAnonymization/RTH/RT.dcm Database/README.txt Tests/Tests.py
diffstat 4 files changed, 76 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file Database/HierarchicalAnonymization/RTH/CT01.dcm has changed
Binary file Database/HierarchicalAnonymization/RTH/RT.dcm has changed
--- 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)
--- 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']