# HG changeset patch # User Sebastien Jodogne # Date 1382094738 -7200 # Node ID 9924aec1d694af0fe59ff93c1a03bded9c941260 # Parent 5ba825b87b21ad33997c53b1a350873a10e538e6 filtering on modalities diff -r 5ba825b87b21 -r 9924aec1d694 Core/DicomFormat/DicomTag.h --- a/Core/DicomFormat/DicomTag.h Fri Oct 18 10:32:12 2013 +0200 +++ b/Core/DicomFormat/DicomTag.h Fri Oct 18 13:12:18 2013 +0200 @@ -114,4 +114,5 @@ // Tags for C-FIND and C-MOVE static const DicomTag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005); static const DicomTag DICOM_TAG_QUERY_RETRIEVE_LEVEL(0x0008, 0x0052); + static const DicomTag DICOM_TAG_MODALITIES_IN_STUDY(0x0008, 0x0061); } diff -r 5ba825b87b21 -r 9924aec1d694 OrthancServer/OrthancFindRequestHandler.cpp --- a/OrthancServer/OrthancFindRequestHandler.cpp Fri Oct 18 10:32:12 2013 +0200 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Fri Oct 18 13:12:18 2013 +0200 @@ -76,8 +76,6 @@ static bool ApplyListConstraint(const std::string& value, const std::string& constraint) { - std::cout << value << std::endl; - std::string v1 = ToLowerCase(value); std::vector items; @@ -163,7 +161,8 @@ { if (query.GetElement(i).GetValue().IsNull() || query.GetElement(i).GetTag() == DICOM_TAG_QUERY_RETRIEVE_LEVEL || - query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET) + query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET || + query.GetElement(i).GetTag() == DICOM_TAG_MODALITIES_IN_STUDY) { continue; } @@ -175,8 +174,6 @@ value = resource.get(tag, Json::arrayValue).get("Value", "").asString(); } - std::cout << tag << " " << value << std::endl; - if (!Matches(value, query.GetElement(i).GetValue().AsString())) { return false; @@ -245,11 +242,73 @@ context_.GetIndex().GetAllUuids(resources, level); assert(resources.type() == Json::arrayValue); - // TODO : Speed up using MainDicomTags (to avoid looping over ALL // the resources and reading the JSON file for each of them) + + /** + * Apply filtering on modalities for studies, if asked (this is an + * extension to standard DICOM) + * http://www.medicalconnections.co.uk/kb/Filtering_on_and_Retrieving_the_Modality_in_a_C_FIND + **/ + + if (level == ResourceType_Study && + input.HasTag(DICOM_TAG_MODALITIES_IN_STUDY)) + { + const DicomValue& v = input.GetValue(DICOM_TAG_MODALITIES_IN_STUDY); + if (!v.IsNull()) + { + // Move the allowed modalities into a "std::set" + std::vector tmp; + Toolbox::TokenizeString(tmp, v.AsString(), '\\'); + + std::set modalities; + for (size_t i = 0; i < tmp.size(); i++) + { + modalities.insert(tmp[i]); + } + + // Loop over the studies + Json::Value studies = resources; + resources = Json::arrayValue; + + for (Json::Value::ArrayIndex i = 0; i < studies.size(); i++) + { + // We are considering a single study. Check whether one of + // its child series matches one of the modalities. + Json::Value study; + if (context_.GetIndex().LookupResource(study, studies[i].asString(), ResourceType_Study)) + { + // Loop over the series of the considered study. + for (Json::Value::ArrayIndex j = 0; j < study["Series"].size(); j++) // (*) + { + Json::Value series; + if (context_.GetIndex().LookupResource(series, study["Series"][j].asString(), ResourceType_Series)) + { + // Get the modality of this series + if (series["MainDicomTags"].isMember("Modality")) + { + std::string modality = series["MainDicomTags"]["Modality"].asString(); + if (modalities.find(modality) != modalities.end()) + { + // This series of the considered study matches one + // of the required modalities. Take the study into + // consideration for future filtering. + resources.append(studies[i]); + + // We have finished considering this study. Break the study loop at (*). + break; + } + } + } + } + } + } + } + } + + /** * Loop over all the resources for this query level. **/ @@ -273,7 +332,7 @@ } catch (OrthancException&) { - // This resource has been deleted during the find request + // This resource has probably been deleted during the find request } } }