changeset 2144:9d77c935f2c3 dicom-sr

handling of pending referenced instances when loading DICOM-SR
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 16 Aug 2024 17:24:00 +0200
parents 83efb01991c5
children 743fa9c74443
files Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp OrthancStone/Sources/Toolbox/DicomStructuredReport.h
diffstat 3 files changed, 134 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Fri Aug 16 14:59:31 2024 +0200
+++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Fri Aug 16 17:24:00 2024 +0200
@@ -155,6 +155,12 @@
     };
   
 
+enum FramesCollectionType
+{
+  FramesCollectionType_None,
+  FramesCollectionType_DicomSR
+};
+
 
 static OrthancStone::MouseAction ConvertWebViewerAction(int action)
 {
@@ -641,6 +647,10 @@
 
     virtual void SignalVirtualSeriesThumbnailLoaded(const std::string& virtualSeriesId,
                                                     const std::string& jpeg) = 0;
+
+    virtual void SignalDicomSRLoaded(const std::string& studyInstanceUid,
+                                     const std::string& seriesInstanceUid,
+                                     const std::string& sopInstanceUid) = 0;
   };
   
 private:
@@ -719,9 +729,45 @@
     }
     else if (payload.GetValue() == Orthanc::ResourceType_Instance)
     {
-      // This occurs if loading DICOM-SR
-
-      // TODO - Hide/show DICOM-SR once they have been loaded
+      // This occurs if loading DICOM-SR: Show the DICOM-SR once all its referenced instances are loaded
+
+      for (size_t i = 0; i < dicom.GetSize(); i++)
+      {
+        std::string studyInstanceUid, seriesInstanceUid, sopInstanceUid;
+        if (dicom.GetResource(i).LookupStringValue(studyInstanceUid, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false) &&
+            dicom.GetResource(i).LookupStringValue(seriesInstanceUid, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false) &&
+            dicom.GetResource(i).LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false))
+        {
+          for (StructuredReports::const_iterator it = structuredReports_.begin(); it != structuredReports_.end(); ++it)
+          {
+            if (it->second->IsReferencedInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid))
+            {
+              bool complete = true;
+              for (size_t j = 0; j < it->second->GetReferencedInstancesCount(); j++)
+              {
+                std::string referencedStudyInstanceUid, referencedSeriesInstanceUid, referencedInstanceInstanceUid, sopClassUid;
+                it->second->GetReferencedInstance(referencedStudyInstanceUid, referencedSeriesInstanceUid, referencedInstanceInstanceUid, sopClassUid, j);
+                if (!instances_->HasResource(referencedInstanceInstanceUid))
+                {
+                  complete = false;
+                  break;
+                }
+              }
+
+              if (complete)
+              {
+                LOG(INFO) << "Loaded all the instances referred by DICOM-SR instance: " << sopInstanceUid;
+                if (observer_ != NULL)
+                {
+                  observer_->SignalDicomSRLoaded(it->second->GetStudyInstanceUid(),
+                                                 it->second->GetSeriesInstanceUid(),
+                                                 it->second->GetSopInstanceUid());
+                }
+              }
+            }
+          }
+        }
+      }
     }
 
     if (payload.GetValue() == Orthanc::ResourceType_Study ||
@@ -1166,8 +1212,11 @@
     }
   }
 
-  IFramesCollection* GetSeriesFrames(const std::string& seriesInstanceUid) const
-  {
+  IFramesCollection* GetSeriesFrames(FramesCollectionType& type,
+                                     const std::string& seriesInstanceUid) const
+  {
+    type = FramesCollectionType_None;
+
     OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid);
     
     if (accessor.IsComplete())
@@ -1176,6 +1225,7 @@
       if (sr != structuredReports_.end())
       {
         assert(sr->second != NULL);
+        type = FramesCollectionType_DicomSR;
 
         try
         {
@@ -1183,8 +1233,8 @@
         }
         catch (Orthanc::OrthancException&)
         {
-          // TODO
-          LOG(ERROR) << "Instances of the DICOM-SR are not available yet";
+          LOG(INFO) << "All the instances referenced by the DICOM-SR series \""
+                    << seriesInstanceUid << "\" are not available yet";
           return NULL;
         }
       }
@@ -2475,6 +2525,7 @@
   boost::shared_ptr<OrthancStone::AnnotationsSceneLayer>  stoneAnnotations_;
 
   bool linearInterpolation_;
+  std::string pendingSeriesInstanceUid_;
 
 
   void ScheduleNextPrefetch()
@@ -3979,6 +4030,24 @@
         *this, current.GetOrigin() + synchronizationOffset_, current.GetNormal());
     }
   }
+
+
+  void SetPendingSeriesInstanceUid(const std::string& seriesInstanceUid)
+  {
+    pendingSeriesInstanceUid_ = seriesInstanceUid;
+  }
+
+
+  void ClearPendingSeriesInstanceUid()
+  {
+    pendingSeriesInstanceUid_.clear();
+  }
+
+
+  const std::string& GetPendingSeriesInstanceUid() const
+  {
+    return pendingSeriesInstanceUid_;
+  }
 };
 
 
@@ -4260,6 +4329,10 @@
       labelPosition.GetX(),
       labelPosition.GetY() );
   }
+
+  virtual void SignalDicomSRLoaded(const std::string& studyInstanceUid,
+                                   const std::string& seriesInstanceUid,
+                                   const std::string& sopInstanceUid) ORTHANC_OVERRIDE;
 };
 
 
@@ -4330,6 +4403,28 @@
 }
 
 
+void WebAssemblyObserver::SignalDicomSRLoaded(const std::string& studyInstanceUid,
+                                              const std::string& seriesInstanceUid,
+                                              const std::string& sopInstanceUid)
+{
+  for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it)
+  {
+    if (it->second->GetPendingSeriesInstanceUid() == seriesInstanceUid)
+    {
+      it->second->ClearPendingSeriesInstanceUid();
+
+      FramesCollectionType type;
+      std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(type, seriesInstanceUid));
+
+      if (frames.get() != NULL)
+      {
+        it->second->SetFrames(frames.release());
+      }
+    }
+  }
+}
+
+
 extern "C"
 {
   int main(int argc, char const *argv[]) 
@@ -4624,15 +4719,23 @@
   {
     try
     {
-      std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(seriesInstanceUid));
+      FramesCollectionType type;
+      std::unique_ptr<IFramesCollection> frames(GetResourcesLoader().GetSeriesFrames(type, seriesInstanceUid));
 
       if (frames.get() != NULL)
       {
+        GetViewport(canvas)->ClearPendingSeriesInstanceUid();
         GetViewport(canvas)->SetFrames(frames.release());
         return 1;
       }
+      else if (type == FramesCollectionType_DicomSR)
+      {
+        GetViewport(canvas)->SetPendingSeriesInstanceUid(seriesInstanceUid);
+        return 0;
+      }
       else
       {
+        GetViewport(canvas)->ClearPendingSeriesInstanceUid();
         return 0;
       }
     }
--- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp	Fri Aug 16 14:59:31 2024 +0200
+++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp	Fri Aug 16 17:24:00 2024 +0200
@@ -607,4 +607,23 @@
       return *structures_[index];
     }
   }
+
+
+  bool DicomStructuredReport::IsReferencedInstance(const std::string& studyInstanceUid,
+                                                   const std::string& seriesInstanceUid,
+                                                   const std::string& sopInstanceUid) const
+  {
+    std::map<std::string, ReferencedInstance*>::const_iterator found = instancesInformation_.find(sopInstanceUid);
+
+    if (found == instancesInformation_.end())
+    {
+      return false;
+    }
+    else
+    {
+      assert(found->second != NULL);
+      return (found->second->GetStudyInstanceUid() == studyInstanceUid &&
+              found->second->GetSeriesInstanceUid() == seriesInstanceUid);
+    }
+  }
 }
--- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.h	Fri Aug 16 14:59:31 2024 +0200
+++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.h	Fri Aug 16 17:24:00 2024 +0200
@@ -302,5 +302,9 @@
     }
 
     const Structure& GetStructure(size_t index) const;
+
+    bool IsReferencedInstance(const std::string& studyInstanceUid,
+                              const std::string& seriesInstanceUid,
+                              const std::string& sopInstanceUid) const;
   };
 }