# HG changeset patch # User Alain Mazy # Date 1726664087 -7200 # Node ID 79c06b1ed0a85e7da1939534fff10ac55083bc8d # Parent 84b7444330a25b821c656a6c4cde3621939fb6d3 check storage access counts diff -r 84b7444330a2 -r 79c06b1ed0a8 NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py --- a/NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py Wed Sep 18 09:36:52 2024 +0200 +++ b/NewTests/ExtraMainDicomTags/test_extra_main_dicom_tags.py Wed Sep 18 14:54:47 2024 +0200 @@ -28,7 +28,8 @@ "Series" : [ "RequestAttributesSequence" ], - "Study": [], + "Study": [ + ], "Patient": [] }, "OverwriteInstances": True, @@ -99,123 +100,148 @@ self.assertIn("Rows", instance["MainDicomTags"]) self.assertIn("PerformedProtocolCodeSequence", instance["MainDicomTags"]) + def get_storage_access_count(self): + mm = self.o.get_binary("/tools/metrics-prometheus").decode("utf-8") + + mm = [x.split(" ") for x in mm.split("\n")] + + count = 0 + for m in mm: + if m[0] == 'orthanc_storage_cache_hit_count': + # print(f"orthanc_storage_cache_hit_count = {m[1]}") + count += int(m[1]) + if m[0] == 'orthanc_storage_cache_miss_count': + # print(f"orthanc_storage_cache_miss_count = {m[1]}") + count += int(m[1]) + + print(f"storage access count = {count}") + return count + def test_tools_find(self): + if self.o.is_orthanc_version_at_least(12, 5, 0): - # upload a study - self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm") + # upload a study + self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm") - # instance level, only extra main dicom tags from that level - r = self.o.post( - endpoint="tools/find", - json={ - "Level": "Instances", - "Query": { - "PatientID": "5Yp0E" - }, - "Expand": True, - "RequestedTags" : [ - "Rows", # in the ExtraMainDicomTags at instance level - "PerformedProtocolCodeSequence" # in the ExtraMainDicomTags at instance level - ] - } - ) + # instance level, only extra main dicom tags from that level + c = self.get_storage_access_count() + r = self.o.post( + endpoint="tools/find", + json={ + "Level": "Instances", + "Query": { + "PatientID": "5Yp0E" + }, + "Expand": True, + "RequestedTags" : [ + "Rows", # in the ExtraMainDicomTags at instance level + "PerformedProtocolCodeSequence" # in the ExtraMainDicomTags at instance level + ] + } + ) - instances = r.json() - self.assertEqual(1, len(instances)) - self.assertIn("Rows", instances[0]["RequestedTags"]) - self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) - # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk + instances = r.json() + self.assertEqual(1, len(instances)) + self.assertIn("Rows", instances[0]["RequestedTags"]) + self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) + self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk - # instance level, only extra main dicom tags from that level + a tag from disk - r = self.o.post( - endpoint="tools/find", - json={ - "Level": "Instances", - "Query": { - "PatientID": "5Yp0E" - }, - "Expand": True, - "RequestedTags" : [ - "Rows", # in the ExtraMainDicomTags at instance level - "PerformedProtocolCodeSequence", # in the ExtraMainDicomTags at instance level - "ReferencedStudySequence" # "ReferencedStudySequence" is not stored in MainDicomTags ! - ] - } - ) + # instance level, only extra main dicom tags from that level + a tag from disk + c = self.get_storage_access_count() + r = self.o.post( + endpoint="tools/find", + json={ + "Level": "Instances", + "Query": { + "PatientID": "5Yp0E" + }, + "Expand": True, + "RequestedTags" : [ + "Rows", # in the ExtraMainDicomTags at instance level + "PerformedProtocolCodeSequence", # in the ExtraMainDicomTags at instance level + "ReferencedStudySequence" # "ReferencedStudySequence" is not stored in MainDicomTags ! + ] + } + ) - instances = r.json() - self.assertEqual(1, len(instances)) - self.assertIn("Rows", instances[0]["RequestedTags"]) - self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) - self.assertIn("ReferencedStudySequence", instances[0]["RequestedTags"]) - # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk + instances = r.json() + self.assertEqual(1, len(instances)) + self.assertIn("Rows", instances[0]["RequestedTags"]) + self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) + self.assertIn("ReferencedStudySequence", instances[0]["RequestedTags"]) + self.assertEqual(c + 1, self.get_storage_access_count()) + # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk - # instance level, extra main dicom tags from that level + a sequence from upper level - r = self.o.post( - endpoint="tools/find", - json={ - "Level": "Instances", - "Query": { - "PatientID": "5Yp0E" - }, - "Expand": True, - "RequestedTags" : [ - "Rows", # in the ExtraMainDicomTags at instance level - "PerformedProtocolCodeSequence", # in the ExtraMainDicomTags at instance level 0040,0260 - "RequestAttributesSequence" # in the ExtraMainDicomTags at series level 0040,0275 - ] - } - ) + # instance level, extra main dicom tags from that level + a sequence from upper level + c = self.get_storage_access_count() + r = self.o.post( + endpoint="tools/find", + json={ + "Level": "Instances", + "Query": { + "PatientID": "5Yp0E" + }, + "Expand": True, + "RequestedTags" : [ + "Rows", # in the ExtraMainDicomTags at instance level + "PerformedProtocolCodeSequence", # in the ExtraMainDicomTags at instance level 0040,0260 + "RequestAttributesSequence" # in the ExtraMainDicomTags at series level 0040,0275 + ] + } + ) - instances = r.json() - self.assertEqual(1, len(instances)) - self.assertIn("Rows", instances[0]["RequestedTags"]) - self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) - self.assertIn("RequestAttributesSequence", instances[0]["RequestedTags"]) # note that, as of 1.12.5, Orthanc reads this from the disk ! - # TO test manually: nothing should be read from disk + instances = r.json() + self.assertEqual(1, len(instances)) + self.assertIn("Rows", instances[0]["RequestedTags"]) + self.assertIn("PerformedProtocolCodeSequence", instances[0]["RequestedTags"]) + self.assertIn("RequestAttributesSequence", instances[0]["RequestedTags"]) # note that, as of 1.12.5, Orthanc reads this from the disk ! + self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk - # series level, request a sequence - r = self.o.post( - endpoint="tools/find", - json={ - "Level": "Series", - "Query": { - "PatientID": "5Yp0E" - }, - "Expand": True, - "RequestedTags" : [ - "RequestAttributesSequence" # in the ExtraMainDicomTags at series level - ] - } - ) + # series level, request a sequence + c = self.get_storage_access_count() + r = self.o.post( + endpoint="tools/find", + json={ + "Level": "Series", + "Query": { + "PatientID": "5Yp0E" + }, + "Expand": True, + "RequestedTags" : [ + "RequestAttributesSequence" # in the ExtraMainDicomTags at series level + ] + } + ) - series = r.json() - self.assertEqual(1, len(series)) - self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"]) - # TO test manually: nothing should be read from disk + series = r.json() + self.assertEqual(1, len(series)) + self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"]) + self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk - # series level, request a sequence + a tag from disk - r = self.o.post( - endpoint="tools/find", - json={ - "Level": "Series", - "Query": { - "PatientID": "5Yp0E" - }, - "Expand": True, - "RequestedTags" : [ - "RequestAttributesSequence", # in the ExtraMainDicomTags at series level - "ReferencedStudySequence" # "ReferencedStudySequence" is not stored in MainDicomTags ! - ] - } - ) + # series level, request a sequence + a tag from disk + c = self.get_storage_access_count() + r = self.o.post( + endpoint="tools/find", + json={ + "Level": "Series", + "Query": { + "PatientID": "5Yp0E" + }, + "Expand": True, + "RequestedTags" : [ + "RequestAttributesSequence", # in the ExtraMainDicomTags at series level + "ReferencedStudySequence" # "ReferencedStudySequence" is not stored in MainDicomTags ! + ] + } + ) - series = r.json() - self.assertEqual(1, len(series)) - self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"]) - self.assertIn("ReferencedStudySequence", series[0]["RequestedTags"]) - # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk + series = r.json() + self.assertEqual(1, len(series)) + self.assertIn("RequestAttributesSequence", series[0]["RequestedTags"]) + self.assertIn("ReferencedStudySequence", series[0]["RequestedTags"]) + self.assertEqual(c + 1, self.get_storage_access_count()) + # TO test manually: ReferencedStudySequence 0008,1110 should be read from disk def test_dicom_web_metadata(self): @@ -230,4 +256,22 @@ self.assertEqual(1, len(metadata)) self.assertIn("00280010", metadata[0]) # Rows self.assertNotIn("00280011", metadata[0]) # Columns should not be stored ! - self.assertIn("00400260", metadata[0]) # PerformedProtocolCodeSequence \ No newline at end of file + self.assertIn("00400260", metadata[0]) # PerformedProtocolCodeSequence + + def test_storage_accesses_for_dicom_web(self): + if self.o.is_orthanc_version_at_least(12, 5, 0): + + # upload a study + self.o.upload_file(here / "../../Database/Brainix/Flair/IM-0001-0001.dcm") + + # study level, only tags that are in DB (note, since 1.12.5, TimezoneOffsetFromUTC is a standard MainDicomTags) + c = self.get_storage_access_count() + r = self.o.get_json("/dicom-web/studies?PatientID=5Yp0E") + self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk + + # series level, only tags that are in DB (note, since 1.12.5, TimezoneOffsetFromUTC is a standard MainDicomTags) + c = self.get_storage_access_count() + r = self.o.get_json("/dicom-web/series?PatientID=5Yp0E") + self.assertEqual(c, self.get_storage_access_count()) # nothing should be read from disk + + diff -r 84b7444330a2 -r 79c06b1ed0a8 Tests/Tests.py --- a/Tests/Tests.py Wed Sep 18 09:36:52 2024 +0200 +++ b/Tests/Tests.py Wed Sep 18 14:54:47 2024 +0200 @@ -1303,7 +1303,10 @@ self.assertTrue('LastUpdate' in m) m = DoGet(_REMOTE, '/series/%s/metadata' % series) - if IsOrthancVersionAbove(_REMOTE, 1, 11, 0): + if IsOrthancVersionAbove(_REMOTE, 1, 12, 5): + self.assertEqual(4, len(m)) + self.assertTrue('MainDicomSequences' in m) # since RequestAttributeSequence is now in the MainDicomTags + elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0): self.assertEqual(3, len(m)) self.assertTrue('MainDicomTagsSignature' in m) else: @@ -1560,7 +1563,10 @@ series = DoGet(_REMOTE, '/series')[0] m = DoGet(_REMOTE, '/series/%s/metadata' % series) - if IsOrthancVersionAbove(_REMOTE, 1, 11, 0): + if IsOrthancVersionAbove(_REMOTE, 1, 12, 5): + self.assertEqual(4, len(m)) + self.assertTrue('MainDicomSequences' in m) # since RequestAttributeSequence is now in the MainDicomTags + elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0): self.assertEqual(3, len(m)) self.assertTrue('MainDicomTagsSignature' in m) else: @@ -10513,6 +10519,9 @@ self.assertEqual('Instance', instance['Type']) self.assertEqual(1, instance['IndexInSeries']) self.assertEqual(0, len(instance['Labels'])) + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5): + # self.assertEqual(8, len(instance['MainDicomTags'])) # since we have added SOPClassUID + # else: self.assertEqual(7, len(instance['MainDicomTags'])) self.assertEqual('1', instance['MainDicomTags']['AcquisitionNumber']) self.assertEqual('0.999841\\0.000366209\\0.0178227\\-0.000427244\\0.999995\\0.00326545', instance['MainDicomTags']['ImageOrientationPatient'])