# HG changeset patch # User Sebastien Jodogne # Date 1603899345 -3600 # Node ID b2941196cabf8cd80a228816dec54e1c70733e0c # Parent 1704341bb96e86b2e8109679099f5cfbe8ca4602 SortedFrames::LookupFrame() diff -r 1704341bb96e -r b2941196cabf OrthancStone/Sources/Toolbox/SortedFrames.cpp --- a/OrthancStone/Sources/Toolbox/SortedFrames.cpp Wed Oct 28 15:46:25 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/SortedFrames.cpp Wed Oct 28 16:35:45 2020 +0100 @@ -144,10 +144,13 @@ delete instances_[i]; } - instancesIndex_.clear(); studyInstanceUid_.clear(); seriesInstanceUid_.clear(); frames_.clear(); + + instancesIndex_.clear(); + framesIndex_.clear(); + sorted_ = true; } @@ -218,6 +221,7 @@ for (unsigned int i = 0; i < instance.GetNumberOfFrames(); i++) { + framesIndex_[std::make_pair(instance.GetSopInstanceUid(), i)] = frames_.size(); frames_.push_back(Frame(instance, i)); } @@ -390,6 +394,33 @@ } + bool SortedFrames::LookupFrame(size_t& frameIndex, + const std::string& sopInstanceUid, + unsigned int frameNumber) const + { + if (sorted_) + { + FramesIndex::const_iterator found = framesIndex_.find( + std::make_pair(sopInstanceUid, frameNumber)); + + if (found == framesIndex_.end()) + { + return false; + } + else + { + frameIndex = found->second; + return true; + } + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls, + "Sort() has not been called"); + } + } + + void SortedFrames::Sort() { if (!sorted_) @@ -407,6 +438,7 @@ frames_.clear(); frames_.reserve(totalFrames); + framesIndex_.clear(); SortUsingIntegerTag(remainingInstances, Orthanc::DICOM_TAG_INSTANCE_NUMBER); // VR is "IS" SortUsingIntegerTag(remainingInstances, Orthanc::DICOM_TAG_IMAGE_INDEX); // VR is "US" diff -r 1704341bb96e -r b2941196cabf OrthancStone/Sources/Toolbox/SortedFrames.h --- a/OrthancStone/Sources/Toolbox/SortedFrames.h Wed Oct 28 15:46:25 2020 +0100 +++ b/OrthancStone/Sources/Toolbox/SortedFrames.h Wed Oct 28 16:35:45 2020 +0100 @@ -98,12 +98,17 @@ // Maps "SOPInstanceUID" to an index in "instances_" typedef std::map InstancesIndex; + // Maps pair "(SOPInstanceUID, FrameNumber)" to an index in + // "frames_" (only once "Sort()" is called) + typedef std::map, size_t> FramesIndex; + std::string studyInstanceUid_; std::string seriesInstanceUid_; std::vector instances_; std::vector frames_; bool sorted_; InstancesIndex instancesIndex_; + FramesIndex framesIndex_; const Instance& GetInstance(size_t instanceIndex) const; @@ -194,6 +199,10 @@ return GetFrame(frameIndex).GetInstance().IsMonochrome1(); } + bool LookupFrame(size_t& frameIndex, + const std::string& sopInstanceUid, + unsigned int frameNumber) const; + void Sort(); }; } diff -r 1704341bb96e -r b2941196cabf UnitTestsSources/SortedFramesTests.cpp --- a/UnitTestsSources/SortedFramesTests.cpp Wed Oct 28 15:46:25 2020 +0100 +++ b/UnitTestsSources/SortedFramesTests.cpp Wed Oct 28 16:35:45 2020 +0100 @@ -94,11 +94,13 @@ f.AddInstance(tags); size_t i; + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop3")); ASSERT_EQ(0u, i); ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop1")); ASSERT_EQ(1u, i); ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2")); ASSERT_EQ(2u, i); - ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop3")); ASSERT_EQ(0u, i); ASSERT_FALSE(f.LookupSopInstanceUid(i, "nope")); - + + ASSERT_THROW(f.LookupFrame(i, "sop3", 0), Orthanc::OrthancException); // Not sorted yet + f.Sort(); ASSERT_EQ(3u, f.GetInstancesCount()); ASSERT_EQ("sop3", f.GetSopInstanceUid(0)); @@ -117,6 +119,18 @@ ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2")); ASSERT_EQ(2u, i); ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop3")); ASSERT_EQ(0u, i); ASSERT_FALSE(f.LookupSopInstanceUid(i, "nope")); + + ASSERT_TRUE(f.LookupFrame(i, "sop1", 0)); ASSERT_EQ(0u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop1", 1)); ASSERT_EQ(1u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop1", 2)); ASSERT_EQ(2u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop2", 0)); ASSERT_EQ(3u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop2", 1)); ASSERT_EQ(4u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop3", 0)); ASSERT_EQ(5u, i); + + ASSERT_FALSE(f.LookupFrame(i, "nope", 0)); + ASSERT_FALSE(f.LookupFrame(i, "sop1", 3)); + ASSERT_FALSE(f.LookupFrame(i, "sop2", 2)); + ASSERT_FALSE(f.LookupFrame(i, "sop3", 1)); } @@ -146,6 +160,17 @@ tags.SetValue(Orthanc::DICOM_TAG_INSTANCE_NUMBER, "10", false); f.AddInstance(tags); + size_t i; + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop1")); ASSERT_EQ(0u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2")); ASSERT_EQ(1u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2a")); ASSERT_EQ(2u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop4")); ASSERT_EQ(3u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop3")); ASSERT_EQ(4u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop5")); ASSERT_EQ(5u, i); + ASSERT_FALSE(f.LookupSopInstanceUid(i, "nope")); + + ASSERT_THROW(f.LookupFrame(i, "sop1", 0), Orthanc::OrthancException); // Not sorted yet + f.Sort(); ASSERT_EQ(6u, f.GetInstancesCount()); ASSERT_EQ("sop1", f.GetSopInstanceUid(0)); @@ -160,7 +185,26 @@ ASSERT_EQ("sop4", f.GetFrameSopInstanceUid(2)); ASSERT_EQ(0u, f.GetFrameNumberInInstance(2)); ASSERT_EQ("sop5", f.GetFrameSopInstanceUid(3)); ASSERT_EQ(0u, f.GetFrameNumberInInstance(3)); ASSERT_EQ("sop1", f.GetFrameSopInstanceUid(4)); ASSERT_EQ(0u, f.GetFrameNumberInInstance(4)); - ASSERT_EQ("sop2a", f.GetFrameSopInstanceUid(5)); ASSERT_EQ(0u, f.GetFrameNumberInInstance(5)); + ASSERT_EQ("sop2a", f.GetFrameSopInstanceUid(5)); ASSERT_EQ(0u, f.GetFrameNumberInInstance(5)); + + // The instances must not have been reordered, only the frames + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop1")); ASSERT_EQ(0u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2")); ASSERT_EQ(1u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop2a")); ASSERT_EQ(2u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop4")); ASSERT_EQ(3u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop3")); ASSERT_EQ(4u, i); + ASSERT_TRUE(f.LookupSopInstanceUid(i, "sop5")); ASSERT_EQ(5u, i); + ASSERT_FALSE(f.LookupSopInstanceUid(i, "nope")); + + ASSERT_TRUE(f.LookupFrame(i, "sop2", 0)); ASSERT_EQ(0u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop3", 0)); ASSERT_EQ(1u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop4", 0)); ASSERT_EQ(2u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop5", 0)); ASSERT_EQ(3u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop1", 0)); ASSERT_EQ(4u, i); + ASSERT_TRUE(f.LookupFrame(i, "sop2a", 0)); ASSERT_EQ(5u, i); + + ASSERT_FALSE(f.LookupFrame(i, "nope", 0)); + ASSERT_FALSE(f.LookupFrame(i, "sop1", 1)); }