Mercurial > hg > orthanc
changeset 1366:a3559b66fba7 query-retrieve
move primitives
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 22 May 2015 16:17:28 +0200 |
parents | 38ce915cb455 |
children | fe6e5a9f1ea2 |
files | OrthancServer/DicomProtocol/DicomUserConnection.cpp OrthancServer/DicomProtocol/DicomUserConnection.h OrthancServer/OrthancInitialization.cpp OrthancServer/main.cpp |
diffstat | 4 files changed, 192 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp Thu May 21 17:03:15 2015 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp Fri May 22 16:17:28 2015 +0200 @@ -337,6 +337,16 @@ } + namespace + { + struct FindPayload + { + DicomFindAnswers* answers; + std::string level; + }; + } + + static void FindCallback( /* in */ void *callbackData, @@ -346,13 +356,19 @@ DcmDataset *responseIdentifiers /* pending response identifiers */ ) { - DicomFindAnswers& answers = *reinterpret_cast<DicomFindAnswers*>(callbackData); + FindPayload& payload = *reinterpret_cast<FindPayload*>(callbackData); if (responseIdentifiers != NULL) { DicomMap m; FromDcmtkBridge::Convert(m, *responseIdentifiers); - answers.Add(m); + + if (!m.HasTag(DICOM_TAG_QUERY_RETRIEVE_LEVEL)) + { + m.SetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL, payload.level); + } + + payload.answers->Add(m); } } @@ -362,11 +378,15 @@ { CheckIsOpen(); + FindPayload payload; + payload.answers = &result; + const char* sopClass; std::auto_ptr<DcmDataset> dataset(ToDcmtkBridge::Convert(fields)); switch (model) { case FindRootModel_Patient: + payload.level = "PATIENT"; DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "PATIENT"); sopClass = UID_FINDPatientRootQueryRetrieveInformationModel; @@ -381,6 +401,7 @@ break; case FindRootModel_Study: + payload.level = "STUDY"; DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "STUDY"); sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; @@ -395,6 +416,7 @@ break; case FindRootModel_Series: + payload.level = "SERIES"; DU_putStringDOElement(dataset.get(), DcmTagKey(0x0008, 0x0052), "SERIES"); sopClass = UID_FINDStudyRootQueryRetrieveInformationModel; @@ -413,6 +435,7 @@ break; case FindRootModel_Instance: + payload.level = "INSTANCE"; if (manufacturer_ == ModalityManufacturer_ClearCanvas || manufacturer_ == ModalityManufacturer_Dcm4Chee) { @@ -467,7 +490,7 @@ T_DIMSE_C_FindRSP response; DcmDataset* statusDetail = NULL; OFCondition cond = DIMSE_findUser(pimpl_->assoc_, presID, &request, dataset.get(), - FindCallback, &result, + FindCallback, &payload, /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ pimpl_->dimseTimeout_, &response, &statusDetail); @@ -534,8 +557,8 @@ } - void DicomUserConnection::Move(const std::string& targetAet, - const DicomMap& fields) + void DicomUserConnection::MoveInternal(const std::string& targetAet, + const DicomMap& fields) { CheckIsOpen(); @@ -830,33 +853,86 @@ } - void DicomUserConnection::MoveSeries(const std::string& targetAet, - const DicomMap& findResult) + static void TestAndCopyTag(DicomMap& result, + const DicomMap& source, + const DicomTag& tag) + { + if (!source.HasTag(tag)) + { + throw OrthancException(ErrorCode_BadRequest); + } + else + { + result.SetValue(tag, source.GetValue(tag)); + } + } + + + void DicomUserConnection::Move(const std::string& targetAet, + const DicomMap& findResult) { - DicomMap simplified; - simplified.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, findResult.GetValue(DICOM_TAG_STUDY_INSTANCE_UID)); - simplified.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SERIES_INSTANCE_UID)); - Move(targetAet, simplified); + if (!findResult.HasTag(DICOM_TAG_QUERY_RETRIEVE_LEVEL)) + { + throw OrthancException(ErrorCode_InternalError); + } + + const std::string tmp = findResult.GetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL).AsString(); + ResourceType level = StringToResourceType(tmp.c_str()); + + DicomMap move; + switch (level) + { + case ResourceType_Patient: + TestAndCopyTag(move, findResult, DICOM_TAG_PATIENT_ID); + break; + + case ResourceType_Study: + TestAndCopyTag(move, findResult, DICOM_TAG_STUDY_INSTANCE_UID); + break; + + case ResourceType_Series: + TestAndCopyTag(move, findResult, DICOM_TAG_STUDY_INSTANCE_UID); + TestAndCopyTag(move, findResult, DICOM_TAG_SERIES_INSTANCE_UID); + break; + + case ResourceType_Instance: + TestAndCopyTag(move, findResult, DICOM_TAG_STUDY_INSTANCE_UID); + TestAndCopyTag(move, findResult, DICOM_TAG_SERIES_INSTANCE_UID); + TestAndCopyTag(move, findResult, DICOM_TAG_SOP_INSTANCE_UID); + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + MoveInternal(targetAet, move); + } + + + void DicomUserConnection::MovePatient(const std::string& targetAet, + const std::string& patientId) + { + DicomMap query; + query.SetValue(DICOM_TAG_PATIENT_ID, patientId); + MoveInternal(targetAet, query); + } + + void DicomUserConnection::MoveStudy(const std::string& targetAet, + const std::string& studyUid) + { + DicomMap query; + query.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); + MoveInternal(targetAet, query); } void DicomUserConnection::MoveSeries(const std::string& targetAet, const std::string& studyUid, const std::string& seriesUid) { - DicomMap map; - map.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); - map.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); - Move(targetAet, map); - } - - void DicomUserConnection::MoveInstance(const std::string& targetAet, - const DicomMap& findResult) - { - DicomMap simplified; - simplified.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, findResult.GetValue(DICOM_TAG_STUDY_INSTANCE_UID)); - simplified.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SERIES_INSTANCE_UID)); - simplified.SetValue(DICOM_TAG_SOP_INSTANCE_UID, findResult.GetValue(DICOM_TAG_SOP_INSTANCE_UID)); - Move(targetAet, simplified); + DicomMap query; + query.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); + query.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); + MoveInternal(targetAet, query); } void DicomUserConnection::MoveInstance(const std::string& targetAet, @@ -864,11 +940,11 @@ const std::string& seriesUid, const std::string& instanceUid) { - DicomMap map; - map.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); - map.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); - map.SetValue(DICOM_TAG_SOP_INSTANCE_UID, instanceUid); - Move(targetAet, map); + DicomMap query; + query.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, studyUid); + query.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, seriesUid); + query.SetValue(DICOM_TAG_SOP_INSTANCE_UID, instanceUid); + MoveInternal(targetAet, query); }
--- a/OrthancServer/DicomProtocol/DicomUserConnection.h Thu May 21 17:03:15 2015 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.h Fri May 22 16:17:28 2015 +0200 @@ -76,8 +76,8 @@ FindRootModel model, const DicomMap& fields); - void Move(const std::string& targetAet, - const DicomMap& fields); + void MoveInternal(const std::string& targetAet, + const DicomMap& fields); void ResetStorageSOPClasses(); @@ -162,17 +162,20 @@ void FindInstance(DicomFindAnswers& result, const DicomMap& fields); - void MoveSeries(const std::string& targetAet, - const DicomMap& findResult); + void Move(const std::string& targetAet, + const DicomMap& findResult); + + void MovePatient(const std::string& targetAet, + const std::string& patientId); + + void MoveStudy(const std::string& targetAet, + const std::string& studyUid); void MoveSeries(const std::string& targetAet, const std::string& studyUid, const std::string& seriesUid); void MoveInstance(const std::string& targetAet, - const DicomMap& findResult); - - void MoveInstance(const std::string& targetAet, const std::string& studyUid, const std::string& seriesUid, const std::string& instanceUid);
--- a/OrthancServer/OrthancInitialization.cpp Thu May 21 17:03:15 2015 +0200 +++ b/OrthancServer/OrthancInitialization.cpp Fri May 22 16:17:28 2015 +0200 @@ -238,7 +238,8 @@ { boost::mutex::scoped_lock lock(globalMutex_); - if (configuration_->isMember(parameter)) + if (configuration_.get() != NULL && + configuration_->isMember(parameter)) { return (*configuration_) [parameter].asString(); } @@ -254,7 +255,8 @@ { boost::mutex::scoped_lock lock(globalMutex_); - if (configuration_->isMember(parameter)) + if (configuration_.get() != NULL && + configuration_->isMember(parameter)) { return (*configuration_) [parameter].asInt(); } @@ -270,7 +272,8 @@ { boost::mutex::scoped_lock lock(globalMutex_); - if (configuration_->isMember(parameter)) + if (configuration_.get() != NULL && + configuration_->isMember(parameter)) { return (*configuration_) [parameter].asBool(); } @@ -286,6 +289,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InexistentItem); + } + if (!configuration_->isMember("DicomModalities")) { throw OrthancException(ErrorCode_BadFileFormat); @@ -318,6 +326,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InexistentItem); + } + if (!configuration_->isMember("OrthancPeers")) { throw OrthancException(ErrorCode_BadFileFormat); @@ -352,7 +365,8 @@ target.clear(); - if (!configuration_->isMember(parameter)) + if (configuration_.get() == NULL || + !configuration_->isMember(parameter)) { return true; } @@ -409,7 +423,8 @@ httpServer.ClearUsers(); - if (!configuration_->isMember("RegisteredUsers")) + if (configuration_.get() == NULL || + !configuration_->isMember("RegisteredUsers")) { return; } @@ -470,7 +485,8 @@ target.clear(); - if (!configuration_->isMember(key)) + if (configuration_.get() == NULL || + !configuration_->isMember(key)) { return; } @@ -571,6 +587,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + if (!configuration_->isMember("DicomModalities")) { (*configuration_) ["DicomModalities"] = Json::objectValue; @@ -594,6 +615,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + if (!configuration_->isMember("DicomModalities")) { throw OrthancException(ErrorCode_BadFileFormat); @@ -614,6 +640,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + if (!configuration_->isMember("OrthancPeers")) { (*configuration_) ["OrthancPeers"] = Json::objectValue; @@ -637,6 +668,11 @@ { boost::mutex::scoped_lock lock(globalMutex_); + if (configuration_.get() == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + if (!configuration_->isMember("OrthancPeers")) { throw OrthancException(ErrorCode_BadFileFormat);
--- a/OrthancServer/main.cpp Thu May 21 17:03:15 2015 +0200 +++ b/OrthancServer/main.cpp Fri May 22 16:17:28 2015 +0200 @@ -51,6 +51,7 @@ #include "ServerToolbox.h" #include "../Plugins/Engine/PluginsManager.h" #include "../Plugins/Engine/OrthancPlugins.h" +#include "FromDcmtkBridge.h" using namespace Orthanc; @@ -531,6 +532,39 @@ } LOG(WARNING) << "Orthanc has started"; + + + if (1) + { + DicomUserConnection c; + c.SetLocalApplicationEntityTitle("ORTHANC"); + c.SetRemoteApplicationEntityTitle("ORTHANC"); + c.SetRemoteHost("localhost"); + c.SetRemotePort(4343); + c.Open(); + + DicomMap m; // Cardiac + m.SetValue(DICOM_TAG_PATIENT_ID, "3390592L"); + //m.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "1.3.51.0.1.1.192.168.29.133.1681753.1681732"); + //m.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "1.3.12.2.1107.5.2.33.37097.2012041612474981424569674.0.0.0"); + //m.SetValue(DICOM_TAG_SOP_INSTANCE_UID, "1.3.12.2.1107.5.2.33.37097.2012041612485535037669708"); + + DicomFindAnswers fnd; + c.FindPatient(fnd, m); + //c.FindInstance(fnd, m); + //c.FindSeries(fnd, m); + //c.FindStudy(fnd, m); + + for (size_t i = 0; i < fnd.GetSize(); i++) + { + FromDcmtkBridge::Print(stdout, fnd.GetAnswer(i)); + c.Move("ORTHANC", fnd.GetAnswer(i)); + } + + printf("ok %d\n", fnd.GetSize()); + } + + Toolbox::ServerBarrier(restApi.ResetRequestReceivedFlag()); isReset = restApi.ResetRequestReceivedFlag(); @@ -638,29 +672,6 @@ int status = 0; try { - if (1) - { - DicomUserConnection c; - c.SetLocalApplicationEntityTitle("ORTHANC"); - c.SetRemoteApplicationEntityTitle("ORTHANC"); - c.SetRemoteHost("localhost"); - c.SetRemotePort(4343); - c.Open(); - - DicomMap m; // Delphine - m.SetValue(DICOM_TAG_PATIENT_ID, "5423962"); - m.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "1.2.840.113845.11.1000000001951524609.20121203131451.1457891"); - m.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "1.2.840.113619.2.278.3.262930758.589.1354512768.115"); - m.SetValue(DICOM_TAG_SOP_INSTANCE_UID, "1.3.12.2.1107.5.2.33.37097.2012041613043195815872177"); - - DicomFindAnswers fnd; - c.FindInstance(fnd, m); - //c.FindSeries(fnd, m); - - printf("ok %d\n", fnd.GetSize()); - } - - for (;;) { OrthancInitialize(configurationFile);