diff --git a/DetectorDescription/DDCMS/interface/DDFilteredView.h b/DetectorDescription/DDCMS/interface/DDFilteredView.h index bab167f14d8fb..b5b4163be4f81 100644 --- a/DetectorDescription/DDCMS/interface/DDFilteredView.h +++ b/DetectorDescription/DDCMS/interface/DDFilteredView.h @@ -207,6 +207,13 @@ namespace cms { // the current position in the DDFilteredView nav_type navPos() const; + //! get Iterator level + const int level() const; + + //! transversed the DDFilteredView according + // to the given stack of sibling numbers + bool goTo(const nav_type&); + //! print Filter paths and selections void printFilter() const; diff --git a/DetectorDescription/DDCMS/src/DDFilteredView.cc b/DetectorDescription/DDCMS/src/DDFilteredView.cc index b4f3897fc2b96..d04f533e4af29 100644 --- a/DetectorDescription/DDCMS/src/DDFilteredView.cc +++ b/DetectorDescription/DDCMS/src/DDFilteredView.cc @@ -560,6 +560,40 @@ DDFilteredView::nav_type DDFilteredView::navPos() const { return pos; } +const int DDFilteredView::level() const { + int level(0); + if (not it_.empty()) { + level = it_.back().GetLevel(); + } + return level; +} + +bool DDFilteredView::goTo(const nav_type& newpos) { + bool result(false); + + // save the current position + it_.emplace_back(Iterator(it_.back().GetTopVolume())); + Node* node = nullptr; + + // try to navigate down to the newpos + for (auto const& i : newpos) { + it_.back().SetType(0); + node = it_.back().Next(); + for (int j = 1; j <= i; j++) { + it_.back().SetType(1); + node = it_.back().Next(); + } + } + if (node != nullptr) { + node_ = node; + result = true; + } else { + it_.pop_back(); + } + + return result; +} + const std::vector DDFilteredView::geoHistory() const { std::vector result; if (not it_.empty()) { diff --git a/DetectorDescription/DDCMS/test/BuildFile.xml b/DetectorDescription/DDCMS/test/BuildFile.xml index 7a557940646e4..a42d8b3517ec6 100644 --- a/DetectorDescription/DDCMS/test/BuildFile.xml +++ b/DetectorDescription/DDCMS/test/BuildFile.xml @@ -4,6 +4,16 @@ + + + + + + + + + + diff --git a/DetectorDescription/DDCMS/test/DDFilteredView.goto.cppunit.cc b/DetectorDescription/DDCMS/test/DDFilteredView.goto.cppunit.cc new file mode 100644 index 0000000000000..bf656bd514728 --- /dev/null +++ b/DetectorDescription/DDCMS/test/DDFilteredView.goto.cppunit.cc @@ -0,0 +1,144 @@ +#include + +#include "DetectorDescription/DDCMS/interface/DDFilteredView.h" +#include "DetectorDescription/DDCMS/interface/DDDetector.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "DD4hep/Detector.h" + +#include +#include +#include + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" + +using namespace cms; + +class testDDFilteredViewGoTo : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(testDDFilteredViewGoTo); + CPPUNIT_TEST(checkFilteredView); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() override; + void tearDown() override {} + void checkFilteredView(); + +private: + void printMe(const cms::DDFilteredView&); + std::string fileName_; + std::vector refPos_{0, 0, 4, 2, 2, 1}; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(testDDFilteredViewGoTo); + +void testDDFilteredViewGoTo::setUp() { + fileName_ = edm::FileInPath("Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2021.xml").fullPath(); +} + +void testDDFilteredViewGoTo::checkFilteredView() { + std::unique_ptr det = std::make_unique("DUMMY", fileName_); + DDFilteredView fview(det.get(), det->description()->worldVolume()); + + int count = 1; + auto testPos = fview.navPos(); + while (fview.next(0)) { + std::cout << "#" << count << ": "; + printMe(fview); + + if (count == 45) { + testPos = fview.navPos(); + } + if (count == 100) { + break; + } + count++; + } + + std::cout << "\n==== Let's go to #45\n"; + fview.goTo(testPos); + printMe(fview); + + int i = 0; + for (auto it : fview.navPos()) { + CPPUNIT_ASSERT(it == testPos[i++]); + } + i = 0; + for (auto it : testPos) { + CPPUNIT_ASSERT(it == refPos_[i++]); + } + + // Start with Tracker + std::cout << "\n==== Let's go to Tracker\n"; + fview.goTo({0, 0, 4}); + CPPUNIT_ASSERT(fview.name() == "Tracker"); + printMe(fview); + + // Go to the first daughter + fview.next(0); + printMe(fview); + + // Use it as an escape level + int startLevel = fview.level(); + + count = 1; + + do { + std::cout << "#" << count++ << ": "; + std::cout << "started at level " << startLevel << "\n"; + printMe(fview); + + } while (fview.next(0) && fview.level() < startLevel); + + std::cout << "\n==== Continue iteration\n"; + + count = 1; + fview.next(0); + startLevel = fview.level(); + printMe(fview); + + do { + std::cout << "#" << count++; + std::cout << " started at level " << startLevel << ":\n"; + printMe(fview); + } while (fview.next(0) && fview.level() < startLevel); + + fview.next(0); + printMe(fview); + + std::cout << "\n==== Let's do it again, go to Tracker\n"; + fview.goTo({0, 0, 4}); + CPPUNIT_ASSERT(fview.name() == "Tracker"); + printMe(fview); + + // Go to the first daughter + fview.next(0); + printMe(fview); + + // Use it as an escape level + startLevel = fview.level(); + + count = 1; + + do { + std::cout << "#" << count++ << ": "; + std::cout << "started at level " << startLevel << "\n"; + printMe(fview); + + } while (fview.next(0) && fview.level() < startLevel); +} + +void testDDFilteredViewGoTo::printMe(const cms::DDFilteredView& fview) { + std::cout << ">>> " << fview.level() << " level: " << fview.name() << " is a " + << cms::dd::name(cms::DDSolidShapeMap, fview.shape()) << "\n"; + std::cout << "Full path to it is " << fview.path() << "\n"; + + auto copies = fview.copyNos(); + std::cout << " copy Nos: "; + std::for_each(copies.rbegin(), copies.rend(), [](const auto& it) { std::cout << it << ", "; }); + std::cout << "\n levels : "; + for (auto it : fview.navPos()) { + std::cout << it << ", "; + } + std::cout << "\n"; +} diff --git a/DetectorDescription/DDCMS/test/DDFilteredView.level.cppunit.cc b/DetectorDescription/DDCMS/test/DDFilteredView.level.cppunit.cc new file mode 100644 index 0000000000000..0ef27c33fbf54 --- /dev/null +++ b/DetectorDescription/DDCMS/test/DDFilteredView.level.cppunit.cc @@ -0,0 +1,96 @@ +#include + +#include "DetectorDescription/DDCMS/interface/DDFilteredView.h" +#include "DetectorDescription/DDCMS/interface/DDDetector.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "DD4hep/Detector.h" + +#include +#include +#include + +#include "cppunit/TestAssert.h" +#include "cppunit/TestFixture.h" + +using namespace cms; + +class testDDFilteredViewLevel : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(testDDFilteredViewLevel); + CPPUNIT_TEST(checkFilteredView); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() override; + void tearDown() override {} + void checkFilteredView(); + +private: + std::string fileName_; + std::vector refPos_{0, 0, 4, 2, 2, 1}; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(testDDFilteredViewLevel); + +void testDDFilteredViewLevel::setUp() { + fileName_ = edm::FileInPath("Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2021.xml").fullPath(); +} + +void testDDFilteredViewLevel::checkFilteredView() { + std::unique_ptr det = std::make_unique("DUMMY", fileName_); + DDFilteredView fview(det.get(), det->description()->worldVolume()); + bool doContinue(true); + int count = 1; + auto testPos = fview.navPos(); + while (fview.next(0) && doContinue) { + std::cout << "#" << count << ": "; + std::cout << fview.level() << " level: " << fview.name() << " is a " + << cms::dd::name(cms::DDSolidShapeMap, fview.shape()) << "\n"; + std::cout << "Full path to it is " << fview.path() << "\n"; + auto copyNos = fview.copyNos(); + for (auto it : copyNos) { + std::cout << it << ", "; + } + std::cout << "\n"; + auto pos = fview.navPos(); + for (auto it : pos) { + std::cout << it << ", "; + } + + fview.parent(); + std::cout << "\n" + << fview.level() << " level: " << fview.name() << " is a " + << cms::dd::name(cms::DDSolidShapeMap, fview.shape()) << "\n"; + + if (count == 45) { + testPos = fview.navPos(); + } + if (count == 50) { + doContinue = false; + } + count++; + std::cout << "\n"; + } + fview.goTo(testPos); + std::cout << "Go to #45\n"; + std::cout << fview.level() << " level: " << fview.name() << " is a " + << cms::dd::name(cms::DDSolidShapeMap, fview.shape()) << "\n"; + std::cout << "Full path to it is " << fview.path() << "\n"; + auto copyNos = fview.copyNos(); + for (auto it : copyNos) { + std::cout << it << ", "; + } + std::cout << "\n"; + count = 0; + auto pos = fview.navPos(); + for (auto it : pos) { + std::cout << it << ", "; + CPPUNIT_ASSERT(it == testPos[count++]); + } + std::cout << "\n"; + count = 0; + for (auto it : testPos) { + std::cout << it << ", "; + CPPUNIT_ASSERT(it == refPos_[count++]); + } + std::cout << "\n"; +}