changeset 1180:9c8f557ea799 broker

ParsedDicomDataset to speed up loading RT-STRUCT from parsed DICOM files
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 Nov 2019 17:34:17 +0100
parents 177e7d431cd1
children 2e52d1f4c9e3
files Framework/Toolbox/DicomStructureSet.cpp Framework/Toolbox/DicomStructureSet.h Framework/Toolbox/ParsedDicomDataset.cpp Framework/Toolbox/ParsedDicomDataset.h Resources/CMake/OrthancStoneConfiguration.cmake
diffstat 5 files changed, 185 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Toolbox/DicomStructureSet.cpp	Wed Nov 20 15:24:20 2019 +0100
+++ b/Framework/Toolbox/DicomStructureSet.cpp	Wed Nov 20 17:34:17 2019 +0100
@@ -27,7 +27,6 @@
 #include <Core/Logging.h>
 #include <Core/OrthancException.h>
 #include <Core/Toolbox.h>
-#include <Plugins/Samples/Common/FullOrthancDataset.h>
 #include <Plugins/Samples/Common/DicomDatasetReader.h>
 
 #if defined(_MSC_VER)
@@ -46,6 +45,11 @@
 #  pragma warning(pop)
 #endif
 
+#if ORTHANC_ENABLE_DCMTK == 1
+#  include "ParsedDicomDataset.h"
+#endif
+
+
 typedef boost::geometry::model::d2::point_xy<double> BoostPoint;
 typedef boost::geometry::model::polygon<BoostPoint> BoostPolygon;
 typedef boost::geometry::model::multi_polygon<BoostPolygon>  BoostMultiPolygon;
@@ -461,7 +465,7 @@
     return structures_[index];
   }
 
-  DicomStructureSet::DicomStructureSet(const OrthancPlugins::FullOrthancDataset& tags)
+  void DicomStructureSet::Setup(const OrthancPlugins::IDicomDataset& tags)
   {
     OrthancPlugins::DicomDatasetReader reader(tags);
     
@@ -607,6 +611,15 @@
   }
 
 
+#if ORTHANC_ENABLE_DCMTK == 1
+  DicomStructureSet::DicomStructureSet(Orthanc::ParsedDicomFile& instance)
+  {
+    ParsedDicomDataset dataset(instance);
+    Setup(dataset);
+  }
+#endif
+  
+
   Vector DicomStructureSet::GetStructureCenter(size_t index) const
   {
     const Structure& structure = GetStructure(index);
--- a/Framework/Toolbox/DicomStructureSet.h	Wed Nov 20 15:24:20 2019 +0100
+++ b/Framework/Toolbox/DicomStructureSet.h	Wed Nov 20 17:34:17 2019 +0100
@@ -21,12 +21,20 @@
 
 #pragma once
 
+#if !defined(ORTHANC_ENABLE_DCMTK)
+#  error The macro ORTHANC_ENABLE_DCMTK must be defined
+#endif
+
 #include "DicomStructureSetUtils.h"
 #include "CoordinateSystem3D.h"
 #include "Extent2D.h"
 #include "../Scene2D/Color.h"
 #include "../Scene2D/PolylineSceneLayer.h"
 
+#if ORTHANC_ENABLE_DCMTK == 1
+#  include <Core/DicomParsing/ParsedDicomFile.h>
+#endif
+
 //#define USE_BOOST_UNION_FOR_POLYGONS 1
 
 #include <Plugins/Samples/Common/FullOrthancDataset.h>
@@ -138,6 +146,8 @@
     Structures        structures_;
     ReferencedSlices  referencedSlices_;
 
+    void Setup(const OrthancPlugins::IDicomDataset& dataset);
+    
     const Structure& GetStructure(size_t index) const;
 
     Structure& GetStructure(size_t index);
@@ -152,7 +162,14 @@
       const CoordinateSystem3D& slice) const;
 
   public:
-    DicomStructureSet(const OrthancPlugins::FullOrthancDataset& instance);
+    DicomStructureSet(const OrthancPlugins::FullOrthancDataset& instance)
+    {
+      Setup(instance);
+    }
+
+#if ORTHANC_ENABLE_DCMTK == 1
+    DicomStructureSet(Orthanc::ParsedDicomFile& instance);
+#endif
 
     size_t GetStructuresCount() const
     {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Toolbox/ParsedDicomDataset.cpp	Wed Nov 20 17:34:17 2019 +0100
@@ -0,0 +1,104 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "ParsedDicomDataset.h"
+
+#include <dcmtk/dcmdata/dcfilefo.h>
+
+namespace OrthancStone
+{
+  static DcmItem* LookupPath(Orthanc::ParsedDicomFile& dicom,
+                             const OrthancPlugins::DicomPath& path)
+  {
+    DcmItem* node = dicom.GetDcmtkObject().getDataset();
+      
+    for (size_t i = 0; i < path.GetPrefixLength(); i++)
+    {
+      const OrthancPlugins::DicomTag& tmp = path.GetPrefixTag(i);
+      DcmTagKey tag(tmp.GetGroup(), tmp.GetElement());
+
+      DcmSequenceOfItems* sequence = NULL;
+      if (!node->findAndGetSequence(tag, sequence).good() ||
+          sequence == NULL)
+      {
+        return NULL;
+      }
+
+      unsigned long pos = path.GetPrefixIndex(i);
+      if (pos >= sequence->card())
+      {
+        return NULL;
+      }
+
+      node = sequence->getItem(pos);
+      if (node == NULL)
+      {
+        return NULL;
+      }
+    }
+
+    return node;
+  }
+
+    
+  bool ParsedDicomDataset::GetStringValue(std::string& result,
+                                          const OrthancPlugins::DicomPath& path) const
+  {
+    DcmItem* node = LookupPath(dicom_, path);
+      
+    if (node != NULL)
+    {
+      DcmTagKey tag(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement());
+
+      const char* s = NULL;
+      if (node->findAndGetString(tag, s).good() &&
+          s != NULL)
+      {
+        result.assign(s);
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+
+  bool ParsedDicomDataset::GetSequenceSize(size_t& size,
+                                           const OrthancPlugins::DicomPath& path) const
+  {
+    DcmItem* node = LookupPath(dicom_, path);
+      
+    if (node != NULL)
+    {
+      DcmTagKey tag(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement());
+
+      DcmSequenceOfItems* s = NULL;
+      if (node->findAndGetSequence(tag, s).good() &&
+          s != NULL)
+      {
+        size = s->card();
+        return true;
+      }
+    }
+
+    return false;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Toolbox/ParsedDicomDataset.h	Wed Nov 20 17:34:17 2019 +0100
@@ -0,0 +1,46 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2019 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <Core/DicomParsing/ParsedDicomFile.h>
+#include <Plugins/Samples/Common/IDicomDataset.h>
+
+namespace OrthancStone
+{
+  class ParsedDicomDataset : public OrthancPlugins::IDicomDataset
+  {
+  private:
+    Orthanc::ParsedDicomFile&  dicom_;
+
+  public:
+    ParsedDicomDataset(Orthanc::ParsedDicomFile& dicom) :
+      dicom_(dicom)
+    {
+    }
+
+    virtual bool GetStringValue(std::string& result,
+                                const OrthancPlugins::DicomPath& path) const ORTHANC_OVERRIDE;
+
+    virtual bool GetSequenceSize(size_t& size,
+                                 const OrthancPlugins::DicomPath& path) const ORTHANC_OVERRIDE;
+  };
+}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Nov 20 15:24:20 2019 +0100
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Nov 20 17:34:17 2019 +0100
@@ -409,6 +409,7 @@
   list(APPEND ORTHANC_STONE_SOURCES
     ${ORTHANC_STONE_ROOT}/Framework/Oracle/ParseDicomSuccessMessage.cpp
     ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParsedDicomCache.cpp
+    ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParsedDicomDataset.cpp
     )
 endif()
 
@@ -435,6 +436,7 @@
 
   ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomTag.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp