comparison OrthancServer/Sources/ResourceFinder.cpp @ 5666:aa231c18b9d2 find-refactoring

adding computed tags
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 04 Jul 2024 18:31:54 +0200
parents d8c86698110c
children 93dff1fccf36
comparison
equal deleted inserted replaced
5665:d8c86698110c 5666:aa231c18b9d2
33 #include "ServerIndex.h" 33 #include "ServerIndex.h"
34 34
35 35
36 namespace Orthanc 36 namespace Orthanc
37 { 37 {
38 void ResourceFinder::ConfigureChildrenCountComputedTag(DicomTag tag,
39 ResourceType parentLevel,
40 ResourceType childLevel)
41 {
42 if (request_.GetLevel() == parentLevel)
43 {
44 requestedComputedTags_.insert(tag);
45 hasRequestedTags_ = true;
46 request_.GetChildrenRetrieveSpecification(childLevel).SetRetrieveCount(true);
47 }
48 }
49
50
51 void ResourceFinder::InjectChildrenCountComputedTag(DicomMap& requestedTags,
52 DicomTag tag,
53 const FindResponse::Resource& resource,
54 ResourceType level) const
55 {
56 if (IsRequestedComputedTag(tag))
57 {
58 const std::set<std::string>& children = resource.GetChildrenIdentifiers(level);
59 requestedTags.SetValue(tag, boost::lexical_cast<std::string>(children.size()), false);
60 }
61 }
62
63
64 void ResourceFinder::InjectComputedTags(DicomMap& requestedTags,
65 const FindResponse::Resource& resource) const
66 {
67 switch (resource.GetLevel())
68 {
69 case ResourceType_Patient:
70 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES, resource, ResourceType_Study);
71 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES, resource, ResourceType_Series);
72 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES, resource, ResourceType_Instance);
73 break;
74
75 case ResourceType_Study:
76 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES, resource, ResourceType_Series);
77 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES, resource, ResourceType_Instance);
78 break;
79
80 case ResourceType_Series:
81 InjectChildrenCountComputedTag(requestedTags, DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES, resource, ResourceType_Instance);
82 break;
83
84 case ResourceType_Instance:
85 if (IsRequestedComputedTag(DICOM_TAG_INSTANCE_AVAILABILITY))
86 {
87 requestedTags.SetValue(DICOM_TAG_INSTANCE_AVAILABILITY, "ONLINE", false);
88 }
89 break;
90
91 default:
92 throw OrthancException(ErrorCode_InternalError);
93 }
94 }
95
96
38 SeriesStatus ResourceFinder::GetSeriesStatus(uint32_t& expectedNumberOfInstances, 97 SeriesStatus ResourceFinder::GetSeriesStatus(uint32_t& expectedNumberOfInstances,
39 const FindResponse::Resource& resource) const 98 const FindResponse::Resource& resource) const
40 { 99 {
41 if (request_.GetLevel() != ResourceType_Series) 100 if (request_.GetLevel() != ResourceType_Series)
42 { 101 {
89 return SeriesStatus_Complete; 148 return SeriesStatus_Complete;
90 } 149 }
91 else 150 else
92 { 151 {
93 return SeriesStatus_Missing; 152 return SeriesStatus_Missing;
94 }
95 }
96
97
98 static void InjectRequestedTags(DicomMap& requestedTags,
99 std::set<DicomTag>& missingTags /* out */,
100 const FindResponse::Resource& resource,
101 ResourceType level,
102 const std::set<DicomTag>& tags)
103 {
104 if (!tags.empty())
105 {
106 DicomMap m;
107 resource.GetMainDicomTags(m, level);
108
109 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
110 {
111 std::string value;
112 if (m.LookupStringValue(value, *it, false /* not binary */))
113 {
114 requestedTags.SetValue(*it, value, false /* not binary */);
115 }
116 else
117 {
118 // This is the case where the Housekeeper should be run
119 missingTags.insert(*it);
120 }
121 }
122 } 153 }
123 } 154 }
124 155
125 156
126 void ResourceFinder::Expand(Json::Value& target, 157 void ResourceFinder::Expand(Json::Value& target,
163 throw OrthancException(ErrorCode_InternalError); 194 throw OrthancException(ErrorCode_InternalError);
164 } 195 }
165 196
166 if (resource.GetLevel() != ResourceType_Instance) 197 if (resource.GetLevel() != ResourceType_Instance)
167 { 198 {
168 const std::set<std::string>& children = resource.GetChildrenIdentifiers(); 199 const std::set<std::string>& children = resource.GetChildrenIdentifiers(GetChildResourceType(resource.GetLevel()));
169 200
170 Json::Value c = Json::arrayValue; 201 Json::Value c = Json::arrayValue;
171 for (std::set<std::string>::const_iterator 202 for (std::set<std::string>::const_iterator
172 it = children.begin(); it != children.end(); ++it) 203 it = children.begin(); it != children.end(); ++it)
173 { 204 {
480 requestedInstanceTags_.insert(tag); 511 requestedInstanceTags_.insert(tag);
481 } 512 }
482 513
483 hasRequestedTags_ = true; 514 hasRequestedTags_ = true;
484 } 515 }
516 else if (tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES)
517 {
518 ConfigureChildrenCountComputedTag(tag, ResourceType_Patient, ResourceType_Study);
519 }
520 else if (tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES)
521 {
522 ConfigureChildrenCountComputedTag(tag, ResourceType_Patient, ResourceType_Series);
523 }
524 else if (tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES)
525 {
526 ConfigureChildrenCountComputedTag(tag, ResourceType_Patient, ResourceType_Instance);
527 }
528 else if (tag == DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES)
529 {
530 ConfigureChildrenCountComputedTag(tag, ResourceType_Study, ResourceType_Series);
531 }
532 else if (tag == DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES)
533 {
534 ConfigureChildrenCountComputedTag(tag, ResourceType_Study, ResourceType_Instance);
535 }
536 else if (tag == DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES)
537 {
538 ConfigureChildrenCountComputedTag(tag, ResourceType_Series, ResourceType_Instance);
539 }
485 else if (tag == DICOM_TAG_INSTANCE_AVAILABILITY) 540 else if (tag == DICOM_TAG_INSTANCE_AVAILABILITY)
486 { 541 {
487 requestedComputedTags_.insert(tag); 542 requestedComputedTags_.insert(tag);
488 hasRequestedTags_ = true; 543 hasRequestedTags_ = true;
489 }
490 else if (tag == DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES)
491 {
492 if (request_.GetLevel() == ResourceType_Series)
493 {
494 requestedComputedTags_.insert(tag);
495 hasRequestedTags_ = true;
496 request_.GetChildrenRetrieveSpecification(ResourceType_Instance).SetRetrieveCount(true);
497 }
498 } 544 }
499 else 545 else
500 { 546 {
501 // This is neither a main DICOM tag, nor a computed DICOM tag: 547 // This is neither a main DICOM tag, nor a computed DICOM tag:
502 // We will be forced to access the DICOM file anyway 548 // We will be forced to access the DICOM file anyway
519 AddRequestedTags(*it); 565 AddRequestedTags(*it);
520 } 566 }
521 } 567 }
522 568
523 569
524 void ResourceFinder::InjectComputedTags(DicomMap& requestedTags, 570 static void InjectRequestedTags(DicomMap& requestedTags,
525 const FindResponse::Resource& resource) const 571 std::set<DicomTag>& missingTags /* out */,
526 { 572 const FindResponse::Resource& resource,
527 switch (resource.GetLevel()) 573 ResourceType level,
528 { 574 const std::set<DicomTag>& tags)
529 case ResourceType_Patient: 575 {
530 break; 576 if (!tags.empty())
531 577 {
532 case ResourceType_Study: 578 DicomMap m;
533 break; 579 resource.GetMainDicomTags(m, level);
534 580
535 case ResourceType_Series: 581 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
536 if (IsRequestedComputedTag(DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES)) 582 {
537 { 583 std::string value;
538 requestedTags.SetValue(DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES, 584 if (m.LookupStringValue(value, *it, false /* not binary */))
539 boost::lexical_cast<std::string>(resource.GetChildrenIdentifiers().size()), false); 585 {
540 } 586 requestedTags.SetValue(*it, value, false /* not binary */);
541 break; 587 }
542 588 else
543 case ResourceType_Instance: 589 {
544 if (IsRequestedComputedTag(DICOM_TAG_INSTANCE_AVAILABILITY)) 590 // This is the case where the Housekeeper should be run
545 { 591 missingTags.insert(*it);
546 requestedTags.SetValue(DICOM_TAG_INSTANCE_AVAILABILITY, "ONLINE", false); 592 }
547 } 593 }
548 break;
549
550 default:
551 throw OrthancException(ErrorCode_InternalError);
552 } 594 }
553 } 595 }
554 596
555 597
556 static void ReadMissingTagsFromStorageArea(DicomMap& requestedTags, 598 static void ReadMissingTagsFromStorageArea(DicomMap& requestedTags,