diff OrthancServer/DicomProtocol/DicomUserConnection.cpp @ 1366:a3559b66fba7 query-retrieve

move primitives
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 22 May 2015 16:17:28 +0200
parents 111e23bb4904
children b22ba8c5edbe
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);
   }