# HG changeset patch # User Sebastien Jodogne # Date 1723821840 -7200 # Node ID 9d77c935f2c38d93c1a5df4e9617439a11f0367b # Parent 83efb01991c578446d3dab4a43510a204cd7d8f8 handling of pending referenced instances when loading DICOM-SR diff -r 83efb01991c5 -r 9d77c935f2c3 Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- 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 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 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 frames(GetResourcesLoader().GetSeriesFrames(seriesInstanceUid)); + FramesCollectionType type; + std::unique_ptr 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; } } diff -r 83efb01991c5 -r 9d77c935f2c3 OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp --- 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::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); + } + } } diff -r 83efb01991c5 -r 9d77c935f2c3 OrthancStone/Sources/Toolbox/DicomStructuredReport.h --- 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; }; }