comparison OrthancServer/Sources/ResourceFinder.cpp @ 5686:11575590e493 find-refactoring

integrating DatabaseLookup into ResourceFinder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 09 Jul 2024 12:51:46 +0200
parents fd4c5e064cbe
children d0a264b803f1
comparison
equal deleted inserted replaced
5685:f0f7d15d195e 5686:11575590e493
34 #include "ServerIndex.h" 34 #include "ServerIndex.h"
35 35
36 36
37 namespace Orthanc 37 namespace Orthanc
38 { 38 {
39 static bool IsComputedTag(const DicomTag& tag)
40 {
41 return (tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES ||
42 tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES ||
43 tag == DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES ||
44 tag == DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES ||
45 tag == DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES ||
46 tag == DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES ||
47 tag == DICOM_TAG_SOP_CLASSES_IN_STUDY ||
48 tag == DICOM_TAG_MODALITIES_IN_STUDY ||
49 tag == DICOM_TAG_INSTANCE_AVAILABILITY);
50 }
51
39 void ResourceFinder::ConfigureChildrenCountComputedTag(DicomTag tag, 52 void ResourceFinder::ConfigureChildrenCountComputedTag(DicomTag tag,
40 ResourceType parentLevel, 53 ResourceType parentLevel,
41 ResourceType childLevel) 54 ResourceType childLevel)
42 { 55 {
43 if (request_.GetLevel() == parentLevel) 56 if (request_.GetLevel() == parentLevel)
453 } 466 }
454 467
455 468
456 void ResourceFinder::SetDatabaseLookup(const DatabaseLookup& lookup) 469 void ResourceFinder::SetDatabaseLookup(const DatabaseLookup& lookup)
457 { 470 {
471 lookup_.reset(lookup.Clone());
472
473 for (size_t i = 0; i < lookup.GetConstraintsCount(); i++)
474 {
475 DicomTag tag = lookup.GetConstraint(i).GetTag();
476 if (IsComputedTag(tag))
477 {
478 AddRequestedTag(tag);
479 }
480 }
481
458 MainDicomTagsRegistry registry; 482 MainDicomTagsRegistry registry;
459 registry.NormalizeLookup(request_.GetDicomTagConstraints(), lookup, request_.GetLevel()); 483 registry.NormalizeLookup(request_.GetDicomTagConstraints(), lookup, request_.GetLevel());
460 } 484
461 485 // Sanity check
462 486 for (size_t i = 0; i < request_.GetDicomTagConstraints().GetSize(); i++)
463 void ResourceFinder::AddRequestedTags(const DicomTag& tag) 487 {
488 if (IsComputedTag(request_.GetDicomTagConstraints().GetConstraint(i).GetTag()))
489 {
490 throw OrthancException(ErrorCode_InternalError);
491 }
492 }
493 }
494
495
496 void ResourceFinder::AddRequestedTag(const DicomTag& tag)
464 { 497 {
465 if (DicomMap::IsMainDicomTag(tag, ResourceType_Patient)) 498 if (DicomMap::IsMainDicomTag(tag, ResourceType_Patient))
466 { 499 {
467 if (request_.GetLevel() == ResourceType_Patient) 500 if (request_.GetLevel() == ResourceType_Patient)
468 { 501 {
600 633
601 void ResourceFinder::AddRequestedTags(const std::set<DicomTag>& tags) 634 void ResourceFinder::AddRequestedTags(const std::set<DicomTag>& tags)
602 { 635 {
603 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it) 636 for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
604 { 637 {
605 AddRequestedTags(*it); 638 AddRequestedTag(*it);
606 } 639 }
607 } 640 }
608 641
609 642
610 static void InjectRequestedTags(DicomMap& requestedTags, 643 static void InjectRequestedTags(DicomMap& requestedTags,
709 742
710 743
711 void ResourceFinder::Execute(FindResponse& response, 744 void ResourceFinder::Execute(FindResponse& response,
712 ServerIndex& index) const 745 ServerIndex& index) const
713 { 746 {
714 if (hasRequestedTags_) 747 index.ExecuteFind(response, request_);
715 {
716 throw OrthancException(ErrorCode_BadSequenceOfCalls);
717 }
718 else
719 {
720 index.ExecuteFind(response, request_);
721 }
722 } 748 }
723 749
724 750
725 void ResourceFinder::Execute(Json::Value& target, 751 void ResourceFinder::Execute(Json::Value& target,
726 ServerContext& context) const 752 ServerContext& context) const
732 758
733 for (size_t i = 0; i < response.GetSize(); i++) 759 for (size_t i = 0; i < response.GetSize(); i++)
734 { 760 {
735 const FindResponse::Resource& resource = response.GetResourceByIndex(i); 761 const FindResponse::Resource& resource = response.GetResourceByIndex(i);
736 762
737 if (expand_) 763 DicomMap requestedTags;
738 { 764
739 Json::Value item; 765 if (hasRequestedTags_)
740 Expand(item, resource, context.GetIndex()); 766 {
741 767 InjectComputedTags(requestedTags, resource);
742 if (hasRequestedTags_) 768
743 { 769 std::set<DicomTag> missingTags = requestedTagsFromFileStorage_;
744 DicomMap requestedTags; 770 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Patient, requestedPatientTags_);
745 InjectComputedTags(requestedTags, resource); 771 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Study, requestedStudyTags_);
746 772 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Series, requestedSeriesTags_);
747 std::set<DicomTag> missingTags = requestedTagsFromFileStorage_; 773 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Instance, requestedInstanceTags_);
748 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Patient, requestedPatientTags_); 774
749 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Study, requestedStudyTags_); 775 if (!missingTags.empty())
750 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Series, requestedSeriesTags_); 776 {
751 InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Instance, requestedInstanceTags_); 777 if (!allowStorageAccess_)
752
753 if (!missingTags.empty())
754 { 778 {
755 if (!allowStorageAccess_) 779 throw OrthancException(ErrorCode_BadSequenceOfCalls,
756 { 780 "Cannot add missing requested tags, as access to file storage is disallowed");
757 throw OrthancException(ErrorCode_BadSequenceOfCalls,
758 "Cannot add missing requested tags, as access to file storage is disallowed");
759 }
760 else
761 {
762 ReadMissingTagsFromStorageArea(requestedTags, context, request_, resource, missingTags);
763 }
764 } 781 }
765 782 else
766 static const char* const REQUESTED_TAGS = "RequestedTags"; 783 {
767 item[REQUESTED_TAGS] = Json::objectValue; 784 ReadMissingTagsFromStorageArea(requestedTags, context, request_, resource, missingTags);
768 FromDcmtkBridge::ToJson(item[REQUESTED_TAGS], requestedTags, format_); 785 }
769 } 786 }
770 787 }
771 target.append(item); 788
772 } 789 bool match = true;
773 else 790
774 { 791 if (lookup_.get() != NULL)
775 target.append(resource.GetIdentifier()); 792 {
793 DicomMap tags;
794 resource.GetMainDicomTags(tags, request_.GetLevel());
795 tags.Merge(requestedTags);
796 match = lookup_->IsMatch(tags);
797 }
798
799 if (match)
800 {
801 if (expand_)
802 {
803 Json::Value item;
804 Expand(item, resource, context.GetIndex());
805
806 if (hasRequestedTags_)
807 {
808 static const char* const REQUESTED_TAGS = "RequestedTags";
809 item[REQUESTED_TAGS] = Json::objectValue;
810 FromDcmtkBridge::ToJson(item[REQUESTED_TAGS], requestedTags, format_);
811 }
812
813 target.append(item);
814 }
815 else
816 {
817 target.append(resource.GetIdentifier());
818 }
776 } 819 }
777 } 820 }
778 } 821 }
779 822
780 823