Mercurial > hg > orthanc
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, |