changeset 1487:75ac66d5f4b2 bgo-timing-tests

Added timing test for dose loading and histogram computation
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 09 Jun 2020 09:50:03 +0200
parents faaff0a1711e
children
files Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Framework/Loaders/OrthancMultiframeVolumeLoader.h UnitTestsSources/UnitTestsMain.cpp
diffstat 3 files changed, 113 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp	Sat Jun 06 11:04:04 2020 +0200
+++ b/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp	Tue Jun 09 09:50:03 2020 +0200
@@ -24,6 +24,9 @@
 #include <Core/Endianness.h>
 #include <Core/Toolbox.h>
 
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+
 namespace OrthancStone
 {
   class OrthancMultiframeVolumeLoader::LoadRTDoseGeometry : public LoaderStateMachine::State
@@ -262,10 +265,23 @@
     CopyPixel(*targetUp, source);
   }
 
+
+  #define TIME_CHECKPOINT(name)                            \
+    {                                                      \
+      pt::ptime nowTime = pt::second_clock::local_time();  \
+      pt::time_duration diff = nowTime - initialTime;      \
+      uint64_t us = diff.total_microseconds();             \
+      timingUSecMap_[name] = us;                         \
+    }
+
   template <typename T>
   void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution(
     const std::string& pixelData, std::map<T,uint64_t>& distribution)
   {
+    namespace pt = boost::posix_time;
+
+    pt::ptime initialTime = pt::second_clock::local_time();
+
     OrthancStone::ImageBuffer3D& target = volume_->GetPixelData();
       
     const unsigned int bpp = target.GetBytesPerPixel();
@@ -284,6 +300,7 @@
       return;
     }
 
+    TIME_CHECKPOINT("start")
     // first pass to initialize map
     {
       const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str());
@@ -302,7 +319,7 @@
         }
       }
     }
-
+    TIME_CHECKPOINT("map_initialized")
     {
       const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str());
 
@@ -353,6 +370,7 @@
 #endif
       }
     }
+    TIME_CHECKPOINT("pixels_and_distribution_ok")
   }
 
   template <typename T>
--- a/Framework/Loaders/OrthancMultiframeVolumeLoader.h	Sat Jun 06 11:04:04 2020 +0200
+++ b/Framework/Loaders/OrthancMultiframeVolumeLoader.h	Tue Jun 09 09:50:03 2020 +0200
@@ -50,6 +50,9 @@
     float                                computedDistributionMin_;
     float                                computedDistributionMax_;
 
+    /** Informational only */
+    std::map<std::string,uint64_t>       timingUSecMap_;
+
     const std::string& GetInstanceId() const;
 
     void ScheduleFrameDownloads();
@@ -119,5 +122,7 @@
       (float& minValue, float& maxValue) const;
 
     void LoadInstance(const std::string& instanceId);
+
+    const std::map<std::string,uint64_t>& GetTimingInfo() const { return timingUSecMap_; }
   };
 }
--- a/UnitTestsSources/UnitTestsMain.cpp	Sat Jun 06 11:04:04 2020 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Tue Jun 09 09:50:03 2020 +0200
@@ -26,6 +26,7 @@
 #include "../Framework/Toolbox/GeometryToolbox.h"
 #include "../Framework/Volumes/ImageBuffer3D.h"
 #include "../Framework/Loaders/LoaderCache.h"
+#include "../Framework/Loaders/OrthancMultiframeVolumeLoader.h"
 
 #include <Core/HttpClient.h>
 #include <Core/Images/ImageProcessing.h>
@@ -37,6 +38,7 @@
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/thread/thread.hpp> 
 #include <boost/math/special_functions/round.hpp>
+#include "Framework/Loaders/GenericLoadersContext.h"
 
 
 TEST(GeometryToolbox, Interpolation)
@@ -879,6 +881,93 @@
   }
 }
 
+void LoadRtDoseBlocking(boost::shared_ptr<OrthancStone::OrthancMultiframeVolumeLoader> doseLoader, std::string instanceId)
+{
+  namespace pt = boost::posix_time;
+
+  // Load RTSTRUCT
+  doseLoader->LoadInstance(instanceId);
+
+  pt::ptime initialTime = pt::second_clock::local_time();
+
+  // Wait for the loading process to complete
+  {
+    bool bContinue(true);
+    while (bContinue)
+    {
+      bContinue = !doseLoader->IsPixelDataLoaded();
+      boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
+
+      {
+        pt::ptime nowTime = pt::second_clock::local_time();
+        pt::time_duration diff = nowTime - initialTime;
+        double seconds = static_cast<double>(diff.total_milliseconds()) * 0.001;
+        std::cout << seconds << " seconds elapsed...\n";
+        if (seconds > 30)
+        {
+          const char* msg = "More than 30 seconds elapsed when waiting for RTSTRUCT... Aborting test :(\n";
+          GTEST_FATAL_FAILURE_(msg);
+          bContinue = false;
+        }
+      }
+    }
+  }
+}
+
+static void InitializeLoadersContext(const char* orthancApiUrl, OrthancStone::ILoadersContext& loadersContext)
+{
+  Orthanc::WebServiceParameters p;
+
+  OrthancStone::GenericLoadersContext& typedLoadersContext =
+    dynamic_cast<OrthancStone::GenericLoadersContext&>(loadersContext);
+  // Default is http://localhost:8042
+  // Here's how you may change it
+  p.SetUrl(orthancApiUrl);
+  p.SetCredentials("orthanc", "orthanc");
+  typedLoadersContext.SetOrthancParameters(p);
+
+  typedLoadersContext.StartOracle();
+}
+
+void ExitializeLoadersContext(OrthancStone::ILoadersContext& loadersContext)
+{
+  OrthancStone::GenericLoadersContext& typedLoadersContext =
+    dynamic_cast<OrthancStone::GenericLoadersContext&>(loadersContext);
+
+  typedLoadersContext.StopOracle();
+}
+
+TEST(DoseLoader, DISABLED_DoseLoadingTiming)
+{
+  using namespace OrthancStone;
+
+  // create loaders context
+  std::unique_ptr<OrthancStone::ILoadersContext> loadersContext(new GenericLoadersContext(1,4,1));
+  InitializeLoadersContext("http://localhost:8042/", *loadersContext);
+
+  auto doseVolume = boost::make_shared<DicomVolumeImage>();
+  auto doseLoader = OrthancMultiframeVolumeLoader::Create(*loadersContext, doseVolume);
+
+  LoadRtDoseBlocking(doseLoader, "830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");
+
+
+  std::map<std::string,uint64_t> timing = doseLoader->GetTimingInfo();
+
+  for (std::map<std::string, uint64_t>::iterator it = timing.begin(); it != timing.end(); ++it)
+  {
+    const std::string& checkPtName = it->first;
+    uint64_t value = it->second;
+    double valueSec = static_cast<double>(value)/1000000.0;
+    std::cout << checkPtName << " : " << value << " usec (" << valueSec << " secs)" << std::endl;
+  }
+
+  //auto ti = doseLoader->GetTimingInfo();
+
+  //Register<DicomVolumeImage::ContentUpdatedMessage>(*doseLoader_, &RtViewerApp::HandleDoseLoaded);
+  ExitializeLoadersContext(*loadersContext);
+}
+
+
 int main(int argc, char **argv)
 {
   Orthanc::Logging::Initialize();