changeset 3538:23219b9da4d1

fix ordered-slices route to be closer to 1.5.7 behaviour
author Alain Mazy <alain@mazy.be>
date Tue, 15 Oct 2019 09:53:33 +0200
parents 9cc09f4c0fa9
children f25e84cc5f87
files NEWS OrthancServer/SliceOrdering.cpp OrthancServer/SliceOrdering.h Resources/CMake/OrthancFrameworkParameters.cmake
diffstat 4 files changed, 65 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Oct 10 13:16:15 2019 +0200
+++ b/NEWS	Tue Oct 15 09:53:33 2019 +0200
@@ -1,6 +1,14 @@
 Pending changes in the mainline
 ===============================
 
+REST API
+--------
+
+* API version has been upgraded to 4
+* in /ordered-slices route, ignore instances without position/normal/seriesIndex
+  unless there are only such instances in the series.
+
+
 Maintenance
 -----------
 
@@ -17,7 +25,6 @@
   the REST API to ease usage of the Authorization plugin. Note that
   only the 'token', 'auth-token' & 'authorization' search params are
   transmitted into HTTP headers.
-* in /ordered-slices route, ignore instances without position/normal/seriesIndex
 * Fix lost relationships between CT and RT-STRUCT during anonymization
 
 Version 1.5.7 (2019-06-25)
--- a/OrthancServer/SliceOrdering.cpp	Thu Oct 10 13:16:15 2019 +0200
+++ b/OrthancServer/SliceOrdering.cpp	Tue Oct 15 09:53:33 2019 +0200
@@ -310,11 +310,7 @@
     for (std::list<std::string>::const_iterator
            it = instancesId.begin(); it != instancesId.end(); ++it)
     {
-      std::auto_ptr<Instance> instance(new Instance(index_, *it));
-      if (instance->HasPosition() || instance->HasNormal() || instance->HasIndexInSeries())
-      {
-        instances_.push_back(instance.release());
-      }
+      instances_.push_back(new Instance(index_, *it));
     }
   }
   
@@ -324,6 +320,7 @@
     if (instances_.size() <= 1)
     {
       // One single instance: It is sorted by default
+      sortedInstances_ = instances_;
       return true;
     }
 
@@ -332,25 +329,31 @@
       return false;
     }
 
+    sortedInstances_.clear();
+
+    // consider only the instances with a position
     for (size_t i = 0; i < instances_.size(); i++)
     {
       assert(instances_[i] != NULL);
 
-      if (!instances_[i]->HasPosition() ||
-          (instances_[i]->HasNormal() &&
-           !IsParallelOrOpposite(instances_[i]->GetNormal(), normal_)))
+      if (instances_[i]->HasPosition())
       {
-        return false;
+        sortedInstances_.push_back(instances_[i]);
       }
     }
 
-    PositionComparator comparator(normal_);
-    std::sort(instances_.begin(), instances_.end(), comparator);
+    if (sortedInstances_.size() == 0)
+    {
+      return false;
+    }
 
-    float a = instances_[0]->ComputeRelativePosition(normal_);
-    for (size_t i = 1; i < instances_.size(); i++)
+    PositionComparator comparator(normal_);
+    std::sort(sortedInstances_.begin(), sortedInstances_.end(), comparator);
+
+    float a = sortedInstances_[0]->ComputeRelativePosition(normal_);
+    for (size_t i = 1; i < sortedInstances_.size(); i++)
     {
-      float b = instances_[i]->ComputeRelativePosition(normal_);
+      float b = sortedInstances_[i]->ComputeRelativePosition(normal_);
 
       if (std::fabs(b - a) <= 10.0f * std::numeric_limits<float>::epsilon())
       {
@@ -372,27 +375,38 @@
     if (instances_.size() <= 1)
     {
       // One single instance: It is sorted by default
+      sortedInstances_ = instances_;
       return true;
     }
 
+    sortedInstances_.clear();
+
+    // consider only the instances with an index
     for (size_t i = 0; i < instances_.size(); i++)
     {
       assert(instances_[i] != NULL);
-      if (!instances_[i]->HasIndexInSeries())
+      if (instances_[i]->HasIndexInSeries())
       {
-        return false;
+        sortedInstances_.push_back(instances_[i]);
       }
     }
 
-    std::sort(instances_.begin(), instances_.end(), IndexInSeriesComparator);
-    
-    for (size_t i = 1; i < instances_.size(); i++)
+    if (sortedInstances_.size() == 0) // if we were not able to sort instances because none of them had an index, return all instances in a "random" order
+    {
+      sortedInstances_ = instances_;
+    }
+    else
     {
-      if (instances_[i - 1]->GetIndexInSeries() == instances_[i]->GetIndexInSeries())
+      std::sort(sortedInstances_.begin(), sortedInstances_.end(), IndexInSeriesComparator);
+
+      for (size_t i = 1; i < sortedInstances_.size(); i++)
       {
-        // The current "IndexInSeries" occurs 2 times: Not a proper ordering
-        LOG(WARNING) << "This series contains 2 slices with the same index, trying to display it anyway";
-        break;
+        if (sortedInstances_[i - 1]->GetIndexInSeries() == sortedInstances_[i]->GetIndexInSeries())
+        {
+          // The current "IndexInSeries" occurs 2 times: Not a proper ordering
+          LOG(WARNING) << "This series contains 2 slices with the same index, trying to display it anyway";
+          break;
+        }
       }
     }
 
@@ -431,28 +445,28 @@
   }
 
 
-  const std::string& SliceOrdering::GetInstanceId(size_t index) const
+  const std::string& SliceOrdering::GetSortedInstanceId(size_t index) const
   {
-    if (index >= instances_.size())
+    if (index >= sortedInstances_.size())
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
     else
     {
-      return instances_[index]->GetIdentifier();
+      return sortedInstances_[index]->GetIdentifier();
     }
   }
 
 
-  unsigned int SliceOrdering::GetFramesCount(size_t index) const
+  unsigned int SliceOrdering::GetSortedInstanceFramesCount(size_t index) const
   {
-    if (index >= instances_.size())
+    if (index >= sortedInstances_.size())
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
     else
     {
-      return instances_[index]->GetFramesCount();
+      return sortedInstances_[index]->GetFramesCount();
     }
   }
 
@@ -463,9 +477,9 @@
     result["Type"] = (isVolume_ ? "Volume" : "Sequence");
     
     Json::Value tmp = Json::arrayValue;
-    for (size_t i = 0; i < GetInstancesCount(); i++)
+    for (size_t i = 0; i < GetSortedInstancesCount(); i++)
     {
-      tmp.append(GetBasePath(ResourceType_Instance, GetInstanceId(i)) + "/file");
+      tmp.append(GetBasePath(ResourceType_Instance, GetSortedInstanceId(i)) + "/file");
     }
 
     result["Dicom"] = tmp;
@@ -473,18 +487,18 @@
     Json::Value slicesShort = Json::arrayValue;
 
     tmp.clear();
-    for (size_t i = 0; i < GetInstancesCount(); i++)
+    for (size_t i = 0; i < GetSortedInstancesCount(); i++)
     {
-      std::string base = GetBasePath(ResourceType_Instance, GetInstanceId(i));
-      for (size_t j = 0; j < GetFramesCount(i); j++)
+      std::string base = GetBasePath(ResourceType_Instance, GetSortedInstanceId(i));
+      for (size_t j = 0; j < GetSortedInstanceFramesCount(i); j++)
       {
         tmp.append(base + "/frames/" + boost::lexical_cast<std::string>(j));
       }
 
       Json::Value tmp2 = Json::arrayValue;
-      tmp2.append(GetInstanceId(i));
+      tmp2.append(GetSortedInstanceId(i));
       tmp2.append(0);
-      tmp2.append(GetFramesCount(i));
+      tmp2.append(GetSortedInstanceFramesCount(i));
       
       slicesShort.append(tmp2);
     }
--- a/OrthancServer/SliceOrdering.h	Thu Oct 10 13:16:15 2019 +0200
+++ b/OrthancServer/SliceOrdering.h	Tue Oct 15 09:53:33 2019 +0200
@@ -51,7 +51,8 @@
     std::string              seriesId_;
     bool                     hasNormal_;
     Vector                   normal_;
-    std::vector<Instance*>   instances_;
+    std::vector<Instance*>   instances_;        // this vector owns the instances
+    std::vector<Instance*>   sortedInstances_;  // this vectore references the instances of instances_
     bool                     isVolume_;
 
     static bool ComputeNormal(Vector& normal,
@@ -77,14 +78,14 @@
 
     ~SliceOrdering();
 
-    size_t  GetInstancesCount() const
+    size_t  GetSortedInstancesCount() const
     {
-      return instances_.size();
+      return sortedInstances_.size();
     }
 
-    const std::string& GetInstanceId(size_t index) const;
+    const std::string& GetSortedInstanceId(size_t index) const;
 
-    unsigned int GetFramesCount(size_t index) const;
+    unsigned int GetSortedInstanceFramesCount(size_t index) const;
 
     void Format(Json::Value& result) const;
   };
--- a/Resources/CMake/OrthancFrameworkParameters.cmake	Thu Oct 10 13:16:15 2019 +0200
+++ b/Resources/CMake/OrthancFrameworkParameters.cmake	Tue Oct 15 09:53:33 2019 +0200
@@ -17,7 +17,7 @@
 # Version of the Orthanc API, can be retrieved from "/system" URI in
 # order to check whether new URI endpoints are available even if using
 # the mainline version of Orthanc
-set(ORTHANC_API_VERSION "3")
+set(ORTHANC_API_VERSION "4")
 
 
 #####################################################################