Instance(ServerIndex& index, const std::string& instanceId) : instanceId_(instanceId), framesCount_(1) { DicomMap instance; if (!index.GetMainDicomTags(instance, instanceId, ResourceType_Instance, ResourceType_Instance)) { throw OrthancException(ErrorCode_UnknownResource); } const DicomValue* frames = instance.TestAndGetValue(DICOM_TAG_NUMBER_OF_FRAMES); if (frames != NULL && !frames->IsNull() && !frames->IsBinary()) { try { framesCount_ = boost::lexical_cast<unsigned int>(frames->GetContent()); } catch (boost::bad_lexical_cast&) { } } std::vector<float> tmp; hasPosition_ = TokenizeVector(tmp, instance, DICOM_TAG_IMAGE_POSITION_PATIENT, 3); if (hasPosition_) { position_[0] = tmp[0]; position_[1] = tmp[1]; position_[2] = tmp[2]; } std::string s; hasIndexInSeries_ = false; try { if (index.LookupMetadata(s, instanceId, MetadataType_Instance_IndexInSeries)) { indexInSeries_ = boost::lexical_cast<size_t>(s); hasIndexInSeries_ = true; } } catch (boost::bad_lexical_cast&) { } }
void LookupResource::ApplyLevel(SetOfResources& candidates, ResourceType level, IDatabaseWrapper& database) const { Levels::const_iterator it = levels_.find(level); if (it != levels_.end()) { it->second->Apply(candidates, database); } if (level == ResourceType_Study && modalitiesInStudy_.get() != NULL) { // There is a constraint on the "ModalitiesInStudy" DICOM // extension. Check out whether one child series has one of the // allowed modalities std::list<int64_t> allStudies, matchingStudies; candidates.Flatten(allStudies); for (std::list<int64_t>::const_iterator study = allStudies.begin(); study != allStudies.end(); ++study) { std::list<int64_t> childrenSeries; database.GetChildrenInternalId(childrenSeries, *study); for (std::list<int64_t>::const_iterator series = childrenSeries.begin(); series != childrenSeries.end(); ++series) { DicomMap tags; database.GetMainDicomTags(tags, *series); const DicomValue* value = tags.TestAndGetValue(DICOM_TAG_MODALITY); if (value != NULL && !value->IsNull() && !value->IsBinary()) { if (modalitiesInStudy_->Match(value->GetContent())) { matchingStudies.push_back(*study); break; } } } } candidates.Intersect(matchingStudies); } }
static bool Match(const DicomMap& tags, const DicomTag& tag, const IFindConstraint& constraint) { const DicomValue* value = tags.TestAndGetValue(tag); if (value == NULL || value->IsNull() || value->IsBinary()) { return false; } else { return constraint.Match(value->GetContent()); } }
static bool TokenizeVector(std::vector<float>& result, const DicomMap& map, const DicomTag& tag, unsigned int expectedSize) { const DicomValue* value = map.TestAndGetValue(tag); if (value == NULL || value->IsNull() || value->IsBinary()) { return false; } else { return TokenizeVector(result, value->GetContent(), expectedSize); } }
static void StoreIdentifiers(IDatabaseWrapper& database, int64_t resource, ResourceType level, const DicomMap& map) { const DicomTag* tags; size_t size; LoadIdentifiers(tags, size, level); for (size_t i = 0; i < size; i++) { const DicomValue* value = map.TestAndGetValue(tags[i]); if (value != NULL && !value->IsNull() && !value->IsBinary()) { std::string s = NormalizeIdentifier(value->GetContent()); database.SetIdentifierTag(resource, tags[i], s); } } }
bool OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, const DicomMap& input, const std::string& callingAETitle) { /** * Ensure that the calling modality is known to Orthanc. **/ RemoteModalityParameters modality; if (!Configuration::LookupDicomModalityUsingAETitle(modality, callingAETitle)) { throw OrthancException("Unknown modality"); } // ModalityManufacturer manufacturer = modality.GetManufacturer(); bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false); /** * Retrieve the query level. **/ const DicomValue* levelTmp = input.TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); if (levelTmp == NULL) { throw OrthancException(ErrorCode_BadRequest); } ResourceType level = StringToResourceType(levelTmp->AsString().c_str()); if (level != ResourceType_Patient && level != ResourceType_Study && level != ResourceType_Series && level != ResourceType_Instance) { throw OrthancException(ErrorCode_NotImplemented); } DicomArray query(input); LOG(INFO) << "DICOM C-Find request at level: " << EnumerationToString(level); for (size_t i = 0; i < query.GetSize(); i++) { if (!query.GetElement(i).GetValue().IsNull()) { LOG(INFO) << " " << query.GetElement(i).GetTag() << " " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag()) << " = " << query.GetElement(i).GetValue().AsString(); } } /** * Build up the query object. **/ CFindQuery findQuery(answers, context_.GetIndex(), query); findQuery.SetLevel(level); for (size_t i = 0; i < query.GetSize(); i++) { const DicomTag tag = query.GetElement(i).GetTag(); if (query.GetElement(i).GetValue().IsNull() || tag == DICOM_TAG_QUERY_RETRIEVE_LEVEL || tag == DICOM_TAG_SPECIFIC_CHARACTER_SET) { continue; } std::string value = query.GetElement(i).GetValue().AsString(); if (value.size() == 0) { // An empty string corresponds to a "*" wildcard constraint, so we ignore it continue; } if (tag == DICOM_TAG_MODALITIES_IN_STUDY) { findQuery.SetModalitiesInStudy(value); } else { findQuery.SetConstraint(tag, value, caseSensitivePN); } } /** * Run the query. **/ ResourceFinder finder(context_); switch (level) { case ResourceType_Patient: case ResourceType_Study: case ResourceType_Series: finder.SetMaxResults(maxResults_); break; case ResourceType_Instance: finder.SetMaxResults(maxInstances_); break; default: throw OrthancException(ErrorCode_InternalError); } std::list<std::string> tmp; bool finished = finder.Apply(tmp, findQuery); LOG(INFO) << "Number of matching resources: " << tmp.size(); return finished; }