Mercurial > hg > orthanc
diff OrthancServer/Sources/ServerContext.cpp @ 4977:dad71e6da406 more-tags
pre-filtering studies without ModalitiesInStudies first
author | Alain Mazy <am@osimis.io> |
---|---|
date | Wed, 20 Apr 2022 11:32:31 +0200 |
parents | f377d5643538 |
children | 2cfa50d8eb60 |
line wrap: on
line diff
--- a/OrthancServer/Sources/ServerContext.cpp Wed Apr 13 14:58:58 2022 +0200 +++ b/OrthancServer/Sources/ServerContext.cpp Wed Apr 20 11:32:31 2022 +0200 @@ -1670,9 +1670,104 @@ } } }; + +# if 1 + class StudyInstanceUidVisitor : public ServerContext::ILookupVisitor + { + private: + std::set<std::string> studyInstanceUids; + + public: + explicit StudyInstanceUidVisitor() + { + } + + virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE + { + return false; + } + + virtual void MarkAsComplete() ORTHANC_OVERRIDE + { + } + + virtual void Visit(const std::string& publicId, + const std::string& instanceId, + const DicomMap& mainDicomTags, + const Json::Value* dicomAsJson) ORTHANC_OVERRIDE + { + std::string studyInstanceUid; + if (!mainDicomTags.LookupStringValue(studyInstanceUid, DICOM_TAG_STUDY_INSTANCE_UID, false)) + { + throw OrthancException(ErrorCode_InternalError); + } + studyInstanceUids.insert(studyInstanceUid); + } + + const std::set<std::string>& GetFilteredStudyInstanceUids() const + { + return studyInstanceUids; + } + }; + } + + void ServerContext::Apply(ILookupVisitor& visitor, + const DatabaseLookup& lookup, + ResourceType queryLevel, + size_t since, + size_t limit) + { + const DicomTagConstraint* constraint = NULL; + + if (queryLevel == ResourceType_Study && + lookup.GetConstraint(constraint, DICOM_TAG_MODALITIES_IN_STUDY) && + ((constraint->GetConstraintType() == ConstraintType_Equal && !constraint->GetValue().empty()) || + (constraint->GetConstraintType() == ConstraintType_List && !constraint->GetValues().empty())) + ) + { + std::unique_ptr<DatabaseLookup> studiesPreFilterLookup(lookup.Clone()); + studiesPreFilterLookup->RemoveConstraint(DICOM_TAG_MODALITIES_IN_STUDY); + + DatabaseLookup seriesLookup; + + std::set<std::string> filteredStudyInstanceUids; + if (studiesPreFilterLookup->GetConstraintsCount() >= 1) + { + LOG(INFO) << "Performing First filtering without ModalitiesInStudy"; + + StudyInstanceUidVisitor studyVisitor; + + ApplyInternal(studyVisitor, *studiesPreFilterLookup, queryLevel, since, limit); + + DicomTagConstraint studyInstanceUidsConstraint(DICOM_TAG_STUDY_INSTANCE_UID, ConstraintType_List, true, true); + for (std::set<std::string>::const_iterator it = studyVisitor.GetFilteredStudyInstanceUids().begin(); + it != studyVisitor.GetFilteredStudyInstanceUids().end(); it++) + { + studyInstanceUidsConstraint.AddValue(*it); + } + + seriesLookup.AddConstraint(studyInstanceUidsConstraint); + } + + // Convert the study-level query, into a series-level query, + // where "ModalitiesInStudy" is replaced by "Modality" + // and where all other constraints are replaced by "StudyInstanceUID IN (...)" + + DicomTagConstraint modality(*constraint); + modality.SetTag(DICOM_TAG_MODALITY); + seriesLookup.AddConstraint(modality); + + ModalitiesInStudyVisitor seriesVisitor(visitor.IsDicomAsJsonNeeded()); + ApplyInternal(seriesVisitor, seriesLookup, ResourceType_Series, 0, 0); + seriesVisitor.Forward(visitor, since, limit); + } + else // filtering without ModalitiesInStudy + { + ApplyInternal(visitor, lookup, queryLevel, since, limit); + } } - +#else void ServerContext::Apply(ILookupVisitor& visitor, const DatabaseLookup& lookup, ResourceType queryLevel, @@ -1720,8 +1815,8 @@ { ApplyInternal(visitor, lookup, queryLevel, since, limit); } - } - + } +#endif bool ServerContext::LookupOrReconstructMetadata(std::string& target, const std::string& publicId,