Mercurial > hg > orthanc-tests
changeset 770:2c169065aab7 default tip
tools/find: fix query by ModalitiesInStudy with pagination
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Wed, 08 Jan 2025 15:19:04 +0100 |
parents | f3376bc9f514 |
children | |
files | Tests/Tests.py |
diffstat | 1 files changed, 223 insertions(+), 139 deletions(-) [+] |
line wrap: on
line diff
--- a/Tests/Tests.py Thu Dec 26 13:09:05 2024 +0100 +++ b/Tests/Tests.py Wed Jan 08 15:19:04 2025 +0100 @@ -2120,18 +2120,28 @@ def test_rest_find(self): - def CheckFind(query, expectedAnswers, executeCountResources = True): - a = DoPost(_REMOTE, '/tools/find', query) - self.assertEqual(expectedAnswers, len(a)) - - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and executeCountResources: - if 'CaseSensitive' in query: - del query['CaseSensitive'] + def CheckFind(query, expectedAnswers, shouldThrow = False): + + if not shouldThrow: + a = DoPost(_REMOTE, '/tools/find', query) + self.assertEqual(expectedAnswers, len(a)) + return a + else: + self.assertRaises(Exception, lambda: DoPost(_REMOTE, '/tools/find', query)) + + + + def CheckCount(query, expectedAnswers, shouldThrow = False): + if not shouldThrow: b = DoPost(_REMOTE, '/tools/count-resources', query) self.assertEqual(1, len(b)) self.assertEqual(expectedAnswers, b['Count']) - - return a + return b + else: + self.assertRaises(Exception, lambda: DoPost(_REMOTE, '/tools/count-resources', query)) + + + # Upload 12 instances for i in range(3): @@ -2148,6 +2158,28 @@ 'StudyDate': '20080819' }} CheckFind(query, 1) + CheckCount(query, 1, True) # tools/count does not support CaseSensitive + + query = { 'Level' : 'Study', + 'CaseSensitive' : False, + 'Query' : { + 'PatientName' : '*NE*', + 'StudyDate': '20080819' + }} + CheckFind(query, 1) + CheckCount(query, 1) + + query = { 'Level' : 'Study', + 'CaseSensitive' : False, + 'Query' : { + 'PatientName' : '*NE*', + 'StudyDate': '20080819' + }, + 'Since' : 1 + } + if HasExtendedFind(_REMOTE): # usage of 'Since' is not reliable without ExtendedFind + CheckFind(query, 0) + CheckCount(query, 1) # Since is ignored in tools/count-resources query = { 'Level' : 'Study', 'CaseSensitive' : True, @@ -2157,6 +2189,39 @@ 'PatientSex': '0000' }} CheckFind(query, 1) + CheckCount(query, 1, True) # tools/count-resources does not support CaseSensitive + + query = { 'Level' : 'Study', + 'CaseSensitive' : True, + 'Query' : { + 'PatientName' : '*NE*', + 'PatientBirthDate': '20080101-20081231', + 'PatientSex': '0000' + }, + 'Since': 1} + if HasExtendedFind(_REMOTE): # usage of 'Since' is not reliable without ExtendedFind + CheckFind(query, 0, True) # 'CaseSensitive' can not be combined with 'Since' + CheckCount(query, 0, True) # tools/count-resources does not support CaseSensitive + + query = { 'Level' : 'Study', + 'CaseSensitive' : True, + 'Query' : { + 'PatientName' : '*ne*', + 'PatientBirthDate': '20080101-20081231', + 'PatientSex': '0000' + } + } + CheckFind(query, 0) + + query = { 'Level' : 'Study', + 'CaseSensitive' : True, + 'Query' : { + 'PatientName' : '*ne*', + 'PatientBirthDate': '20080101-20081231', + 'PatientSex': '0000' + }, + 'Since': 1} + CheckFind(query, 0, True) # 'CaseSensitive' can not be combined with 'Since' when searching for lower case (because the DicomIdentifiers are stored in UPPERCASE) query = { 'Level' : 'Series', 'CaseSensitive' : True, @@ -2164,6 +2229,7 @@ 'StudyInstanceUID' : '2.16.840.1.113669.632.20.121711.10000160881' }} CheckFind(query, 2) + CheckCount(query, 2, True) # tools/count-resources does not support CaseSensitive query = { 'Level' : 'Instance', 'CaseSensitive' : True, @@ -2172,6 +2238,7 @@ 'SeriesInstanceUID': '1.3.46.670589.11.17521.5.0.3124.2008081908564160709' }} CheckFind(query, 3) + CheckCount(query, 3, True) # tools/count-resources does not support CaseSensitive query = { 'Level' : 'Series', 'CaseSensitive' : True, @@ -2180,6 +2247,7 @@ 'Modality': 'MR' }} CheckFind(query, 2) + CheckCount(query, 2, True) # tools/count-resources does not support CaseSensitive query = { 'Level' : 'Study', 'CaseSensitive' : True, @@ -2187,27 +2255,43 @@ 'StudyDate' : '20080818-', 'ModalitiesInStudy': 'MR' }} - CheckFind(query, 1, False) # "ModalitiesInStudy" is not a main DICOM tag, so unavailable in "/tools/count-resources" + CheckFind(query, 1) + + query = { 'Level' : 'Study', + 'CaseSensitive' : False, + 'Query' : { + 'StudyDate' : '20080818-', + 'ModalitiesInStudy': 'MR' + }, + 'Since': 1} + + if HasExtendedFind(_REMOTE): # usage of 'Since' is not reliable without ExtendedFind + CheckFind(query, 0) + CheckCount(query, 1) # Since is ignored in tools/count-resources query = { 'Level' : 'Patient', 'CaseSensitive' : False, 'Query' : { 'PatientName' : 'BRAINIX' }} CheckFind(query, 1) + CheckCount(query, 1) query = { 'Level' : 'Patient', 'CaseSensitive' : False, 'Query' : { 'PatientName' : 'BRAINIX\\KNEE\\NOPE' }} CheckFind(query, 2) + CheckCount(query, 2) query = { 'Level' : 'Patient', 'CaseSensitive' : False, 'Query' : { 'PatientName' : '*n*' }} CheckFind(query, 2) + CheckCount(query, 2) query = { 'Level' : 'Patient', 'CaseSensitive' : True, 'Query' : { 'PatientName' : '*n*' }} - CheckFind(query, 0, False) # "CaseSensitive" is not available in "/tools/count-resources" + CheckFind(query, 0) + CheckCount(query, 0, True) # "CaseSensitive" is not available in "/tools/count-resources" query = { 'Expand' : True, 'Level' : 'Patient', @@ -2219,7 +2303,7 @@ query = { 'Level' : 'Patient', 'CaseSensitive' : True, 'Query' : { 'PatientName' : '*ne*' }} - CheckFind(query, 0, False) # "CaseSensitive" is not available in "/tools/count-resources" + CheckFind(query, 0) query = { 'Level' : 'Study', 'CaseSensitive' : True, @@ -2255,7 +2339,7 @@ self.assertEqual('BRAINIX', a[0]['PatientMainDicomTags']['PatientName']) query = { 'Level' : 'Study', - 'Expand' : True, + 'Expand' : True, 'Query' : { 'StudyDate' : '20061201-20091201' }} a = CheckFind(query, 2) for i in range(2): @@ -11405,109 +11489,109 @@ self.assertEqual(14, len(DoGet(_REMOTE, '/series'))) - knixInstancesNoLimit = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Instances', - 'Query' : { - 'PatientName' : 'KNIX' - }, - 'Expand': False - }) - - # pprint.pprint(knixInstancesNoLimit) - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): - self.assertEqual(20, len(knixInstancesNoLimit)) - else: - self.assertEqual(21, len(knixInstancesNoLimit)) - - knixInstancesSince5Limit20 = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Instances', - 'Query' : { - 'PatientName' : 'KNIX' - }, - 'Expand': False, - 'Since': 5, - 'Limit': 20 - }) - # pprint.pprint(knixInstancesSince5Limit20) - - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5): - self.assertEqual(20, len(knixInstancesSince5Limit20)) # Orthanc actually returns LimitFindInstances + 1 resources - # the first 5 from previous call shall not be in this answer - for i in range(0, 5): - self.assertNotIn(knixInstancesNoLimit[i], knixInstancesSince5Limit20) - # the last 4 from last call shall not be in the first answer - for i in range(16, 20): - self.assertNotIn(knixInstancesSince5Limit20[i], knixInstancesNoLimit) - - # request more instances than LimitFindInstances - knixInstancesSince0Limit23 = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Instances', - 'Query' : { - 'PatientName' : 'KNIX' - }, - 'Expand': False, - 'Since': 0, - 'Limit': 23 - }) - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): - self.assertEqual(20, len(knixInstancesSince0Limit23)) - - seriesNoLimit = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Series', - 'Query' : { - 'PatientName' : '*' - }, - 'Expand': False - }) - - # pprint.pprint(seriesNoLimit) - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): - self.assertEqual(10, len(seriesNoLimit)) - else: - self.assertEqual(11, len(seriesNoLimit)) - - seriesSince8Limit6 = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Series', - 'Query' : { - 'PatientName' : '*' - }, - 'Expand': False, - 'Since': 8, - 'Limit': 6 - }) - - # pprint.pprint(seriesSince8Limit6) - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): # TODO: remove HasExtendedFind once find-refactoring branch has been merged and supported by all DB plugins !!! - self.assertEqual(6, len(seriesSince8Limit6)) - - # the first 7 from previous call shall not be in this answer - for i in range(0, 7): - self.assertNotIn(seriesNoLimit[i], seriesSince8Limit6) - # the last 3 from last call shall not be in the first answer - for i in range(3, 5): - self.assertNotIn(seriesSince8Limit6[i], seriesNoLimit) - - if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): - # query by a tag that is not in the DB (there are 27 instances from Knix/Loc + 10 instances from other series that satisfies this criteria) - a = DoPost(_REMOTE, '/tools/find', { - 'Level' : 'Instances', - 'Query' : { - 'PhotometricInterpretation' : 'MONOCHROME*' - }, - 'Expand': True, - 'OrderBy' : [ - { - 'Type': 'DicomTag', - 'Key': 'InstanceNumber', - 'Direction': 'ASC' - } - ]}) - - # pprint.pprint(a) - # print(len(a)) - # TODO: we should have something in the response that notifies us that the response is not "complete" - # TODO: we should receive an error if we try to use "since" in this kind of search ? - self.assertEqual(17, len(a)) # the fast DB filtering returns 20 instances -> only 17 of them meet the criteria but this is not really correct !!! + # knixInstancesNoLimit = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Instances', + # 'Query' : { + # 'PatientName' : 'KNIX' + # }, + # 'Expand': False + # }) + + # # pprint.pprint(knixInstancesNoLimit) + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): + # self.assertEqual(20, len(knixInstancesNoLimit)) + # else: + # self.assertEqual(21, len(knixInstancesNoLimit)) + + # knixInstancesSince5Limit20 = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Instances', + # 'Query' : { + # 'PatientName' : 'KNIX' + # }, + # 'Expand': False, + # 'Since': 5, + # 'Limit': 20 + # }) + # # pprint.pprint(knixInstancesSince5Limit20) + + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5): + # self.assertEqual(20, len(knixInstancesSince5Limit20)) # Orthanc actually returns LimitFindInstances + 1 resources + # # the first 5 from previous call shall not be in this answer + # for i in range(0, 5): + # self.assertNotIn(knixInstancesNoLimit[i], knixInstancesSince5Limit20) + # # the last 4 from last call shall not be in the first answer + # for i in range(16, 20): + # self.assertNotIn(knixInstancesSince5Limit20[i], knixInstancesNoLimit) + + # # request more instances than LimitFindInstances + # knixInstancesSince0Limit23 = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Instances', + # 'Query' : { + # 'PatientName' : 'KNIX' + # }, + # 'Expand': False, + # 'Since': 0, + # 'Limit': 23 + # }) + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): + # self.assertEqual(20, len(knixInstancesSince0Limit23)) + + # seriesNoLimit = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Series', + # 'Query' : { + # 'PatientName' : '*' + # }, + # 'Expand': False + # }) + + # # pprint.pprint(seriesNoLimit) + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): + # self.assertEqual(10, len(seriesNoLimit)) + # else: + # self.assertEqual(11, len(seriesNoLimit)) + + # seriesSince8Limit6 = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Series', + # 'Query' : { + # 'PatientName' : '*' + # }, + # 'Expand': False, + # 'Since': 8, + # 'Limit': 6 + # }) + + # # pprint.pprint(seriesSince8Limit6) + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): # TODO: remove HasExtendedFind once find-refactoring branch has been merged and supported by all DB plugins !!! + # self.assertEqual(6, len(seriesSince8Limit6)) + + # # the first 7 from previous call shall not be in this answer + # for i in range(0, 7): + # self.assertNotIn(seriesNoLimit[i], seriesSince8Limit6) + # # the last 3 from last call shall not be in the first answer + # for i in range(3, 5): + # self.assertNotIn(seriesSince8Limit6[i], seriesNoLimit) + + # if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): + # # query by a tag that is not in the DB (there are 27 instances from Knix/Loc + 10 instances from other series that satisfies this criteria) + # a = DoPost(_REMOTE, '/tools/find', { + # 'Level' : 'Instances', + # 'Query' : { + # 'PhotometricInterpretation' : 'MONOCHROME*' + # }, + # 'Expand': True, + # 'OrderBy' : [ + # { + # 'Type': 'DicomTag', + # 'Key': 'InstanceNumber', + # 'Direction': 'ASC' + # } + # ]}) + + # # pprint.pprint(a) + # # print(len(a)) + # # TODO: we should have something in the response that notifies us that the response is not "complete" + # # TODO: we should receive an error if we try to use "since" in this kind of search ? + # self.assertEqual(17, len(a)) # the fast DB filtering returns 20 instances -> only 17 of them meet the criteria but this is not really correct !!! if IsOrthancVersionAbove(_REMOTE, 1, 12, 5) and HasExtendedFind(_REMOTE): # make sur an error is returned when using Since or Limit when querying a tag that is not in DB @@ -11518,35 +11602,35 @@ 'Since': 2 })) - # make sur an error is returned when using Since or Limit when querying a tag that is not in DB + # make sur an error is returned when using Since when querying a tag that is not in DB self.assertRaises(Exception, lambda: DoPost(_REMOTE, '/tools/find', {'Level' : 'Instances', 'Query' : { 'PhotometricInterpretation' : 'MONOCHROME*' }, - 'Limit': 10 + 'Since': 10 })) - # disabled while waiting for https://github.com/orthanc-server/orthanc-explorer-2/issues/73 to be fixed - # if IsOrthancVersionAbove(_REMOTE, 1, 12, 6) and HasExtendedFind(_REMOTE): - # # make sur no error is returned when using Since or Limit when querying against ModalitiesInStudy - # a = DoPost(_REMOTE, '/tools/find', {'Level' : 'Studies', - # 'Query' : { - # 'ModalitiesInStudy' : 'CT\\MR' - # }, - # 'Since': 2, - # 'Limit': 3, - # 'Expand': True, - # 'OrderBy': [ - # { - # 'Type': 'DicomTag', - # 'Key': 'StudyDate', - # 'Direction': 'ASC' - # } - # ]}) - # # pprint.pprint(a) - # self.assertEqual('20050927', a[0]['MainDicomTags']['StudyDate']) - # self.assertEqual('20061201', a[1]['MainDicomTags']['StudyDate']) - # self.assertEqual('20070101', a[2]['MainDicomTags']['StudyDate']) + # https://github.com/orthanc-server/orthanc-explorer-2/issues/73 + if IsOrthancVersionAbove(_REMOTE, 1, 12, 6) and HasExtendedFind(_REMOTE): + # make sur no error is returned when using Since or Limit when querying against ModalitiesInStudy + a = DoPost(_REMOTE, '/tools/find', {'Level' : 'Studies', + 'Query' : { + 'ModalitiesInStudy' : 'CT\\MR' + }, + 'Since': 2, + 'Limit': 3, + 'Expand': True, + 'OrderBy': [ + { + 'Type': 'DicomTag', + 'Key': 'StudyDate', + 'Direction': 'ASC' + } + ]}) + # pprint.pprint(a) + self.assertEqual('20050927', a[0]['MainDicomTags']['StudyDate']) + self.assertEqual('20061201', a[1]['MainDicomTags']['StudyDate']) + self.assertEqual('20070101', a[2]['MainDicomTags']['StudyDate']) def test_attachment_range(self):