From 819352d0f00062cc2e7efeb67cb18cf3fa8c582f Mon Sep 17 00:00:00 2001 From: Johannes Josef Junggeburth <johannes.josef.junggeburth@cern.ch> Date: Fri, 17 Jan 2025 10:58:53 +0100 Subject: [PATCH 1/3] Add GeoId caching --- .../GeoModelHelpers/GeoDeDuplicator.h | 12 +++++++++--- .../GeoModelHelpers/src/GeoDeDuplicator.cxx | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h index 60a4cfd17..1e0dbd8c1 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h @@ -9,6 +9,7 @@ #include "GeoModelKernel/GeoTransform.h" #include "GeoModelKernel/GeoSerialIdentifier.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoIdentifierTag.h" #include "GeoModelHelpers/GeoLogVolSorter.h" #include "GeoModelHelpers/GeoPhysVolSorter.h" @@ -16,7 +17,7 @@ #include "GeoModelHelpers/TransformSorter.h" #include <set> -#include <map> +#include <unordered_map> #include <mutex> #include <thread> /*** @@ -75,6 +76,7 @@ class GeoDeDuplicator { using GeoTrfPtr = GeoIntrusivePtr<GeoTransform>; using GeoPhysVolPtr = GeoIntrusivePtr<GeoPhysVol>; using GeoSerialIdPtr = GeoIntrusivePtr<GeoSerialIdentifier>; + using GeoIdPtr = GeoIntrusivePtr<GeoIdentifierTag>; using GeoNamePtr = GeoIntrusivePtr<GeoNameTag>; /** @brief Standard constructor */ @@ -104,6 +106,8 @@ class GeoDeDuplicator { GeoNamePtr nameTag(const std::string& tagName) const; /** @brief Returns a new GeoSerial Id */ GeoSerialIdPtr serialId(const int id) const; + /** @brief Returns a new GeoIdentifier tag */ + GeoIdPtr geoId(const int id) const; /** @brief Toggles whether shape deduplication shall be enabled */ void setShapeDeDuplication(bool enable); @@ -125,8 +129,9 @@ class GeoDeDuplicator { using LogVolSet = std::set<GeoLogVolPtr, GeoLogVolSorter>; using TrfSet = std::set<GeoTrfPtr, GeoTrf::TransformSorter>; using ShapeSet = std::set<GeoShapePtr, GeoShapeSorter>; - using SerialIdMap = std::map<int, GeoSerialIdPtr>; - using NameTagMap = std::map<std::string, GeoNamePtr>; + using SerialIdMap = std::unordered_map<int, GeoSerialIdPtr>; + using GeoIdMap = std::unordered_map<int, GeoIdPtr>; + using NameTagMap = std::unordered_map<std::string, GeoNamePtr>; mutable PhysVolSet m_physVolStore{}; mutable LogVolSet m_logVolStore{}; @@ -136,6 +141,7 @@ class GeoDeDuplicator { static ShapeSet s_shapeStore; static SerialIdMap s_serialIds; static NameTagMap s_nameTags; + static GeoIdMap s_geoIds; mutable std::mutex m_mutex{}; }; diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx index 19432f217..f8ecad113 100644 --- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx +++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx @@ -8,6 +8,7 @@ GeoDeDuplicator::TrfSet GeoDeDuplicator::s_trfStore{}; GeoDeDuplicator::ShapeSet GeoDeDuplicator::s_shapeStore{}; GeoDeDuplicator::SerialIdMap GeoDeDuplicator::s_serialIds{}; GeoDeDuplicator::NameTagMap GeoDeDuplicator::s_nameTags{}; +GeoDeDuplicator::GeoIdMap GeoDeDuplicator::s_geoIds{}; namespace { std::mutex s_mutex{}; @@ -31,6 +32,7 @@ void GeoDeDuplicator::clearSharedCaches() { s_shapeStore.clear(); s_serialIds.clear(); s_nameTags.clear(); + s_geoIds.clear(); } GeoDeDuplicator::GeoTrfPtr @@ -86,7 +88,8 @@ GeoDeDuplicator::GeoNamePtr GeoDeDuplicator::nameTag(const std::string& tagName) s_nameTags.insert(std::make_pair(tagName, newTag)); return newTag; } -GeoDeDuplicator::GeoSerialIdPtr GeoDeDuplicator::serialId(const int id) const { +GeoDeDuplicator::GeoSerialIdPtr + GeoDeDuplicator::serialId(const int id) const { std::lock_guard guard{s_mutex}; SerialIdMap::const_iterator itr = s_serialIds.find(id); if (itr != s_serialIds.end()){ @@ -95,4 +98,15 @@ GeoDeDuplicator::GeoSerialIdPtr GeoDeDuplicator::serialId(const int id) const { GeoSerialIdPtr newId = make_intrusive<GeoSerialIdentifier>(id); s_serialIds.insert(std::make_pair(id, newId)); return newId; +} +GeoDeDuplicator::GeoIdPtr + GeoDeDuplicator::geoId(const int id) const { + std::lock_guard guard{s_mutex}; + GeoIdMap::const_iterator itr = s_geoIds.find(id); + if (itr != s_geoIds.end()){ + return itr->second; + } + GeoIdPtr newId = make_intrusive<GeoIdentifierTag>(id); + s_geoIds.insert(std::make_pair(id, newId)); + return newId; } \ No newline at end of file -- GitLab From 79bf759419587470cd18c46677b29ea28bd6c57d Mon Sep 17 00:00:00 2001 From: Johannes Josef Junggeburth <johannes.josef.junggeburth@cern.ch> Date: Fri, 17 Jan 2025 12:00:16 +0100 Subject: [PATCH 2/3] Add clone volume function --- .../GeoModelHelpers/GeoDeDuplicator.h | 8 +++- .../GeoModelHelpers/src/GeoDeDuplicator.cxx | 44 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h index 1e0dbd8c1..547252a61 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h @@ -7,6 +7,9 @@ #include "GeoModelKernel/GeoPhysVol.h" #include "GeoModelKernel/GeoShape.h" #include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" #include "GeoModelKernel/GeoSerialIdentifier.h" #include "GeoModelKernel/GeoNameTag.h" #include "GeoModelKernel/GeoIdentifierTag.h" @@ -109,6 +112,10 @@ class GeoDeDuplicator { /** @brief Returns a new GeoIdentifier tag */ GeoIdPtr geoId(const int id) const; + /** @brief Clones a physical volume. All components in the tree are + * parsed through the deduplication chain */ + PVLink clone(PVConstLink vol) const; + /** @brief Toggles whether shape deduplication shall be enabled */ void setShapeDeDuplication(bool enable); /** @brief Toggles whether logVol deduplication shall be enabled */ @@ -117,7 +124,6 @@ class GeoDeDuplicator { void setTransformDeDuplication(bool enable); /** @brief Toggles whether physVol node deduplication shall be enabled */ void setPhysVolDeDuplication(bool enable); - /** @brief Clears the shared Shape / Transform / SerialId & NameTag cache */ static void clearSharedCaches(); private: diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx index f8ecad113..e4b885009 100644 --- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx +++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx @@ -109,4 +109,48 @@ GeoDeDuplicator::GeoIdPtr GeoIdPtr newId = make_intrusive<GeoIdentifierTag>(id); s_geoIds.insert(std::make_pair(id, newId)); return newId; +} + +PVLink GeoDeDuplicator::clone(PVConstLink vol) const { + PVLink newVol{}; + bool tryPhysVolDeDup{m_deDuplicatePhysVol}; + GeoLogVolPtr logVol{const_cast<GeoLogVol*>(vol->getLogVol())}; + if (dynamic_cast<const GeoPhysVol*>(vol.get())) { + newVol = make_intrusive<GeoPhysVol>(cacheVolume(logVol)); + } else { + newVol = make_intrusive<GeoFullPhysVol>(cacheVolume(logVol)); + tryPhysVolDeDup = false; + } + for(unsigned int chNode =0; chNode < newVol->getNChildNodes(); ++chNode) { + GeoIntrusivePtr<const GeoGraphNode>node{*newVol->getChildNode(chNode)}; + /** transform nodes */ + if (typeid(*node) == typeid(GeoAlignableTransform)) { + const auto geoTrf = dynamic_pointer_cast<const GeoAlignableTransform>(node); + newVol->add(make_intrusive<GeoAlignableTransform>(geoTrf->getDefTransform())); + } else if (typeid(*node) == typeid(GeoTransform)) { + const auto geoTrf = dynamic_pointer_cast<const GeoTransform>(node); + auto geoTrfNonConst = const_pointer_cast(geoTrf); + newVol->add(cacheTransform(geoTrfNonConst)); + } + /** physical volumes */ + else if (auto physVol = dynamic_pointer_cast<const GeoVPhysVol>(node); physVol) { + newVol->add(clone(physVol)); + } else if (auto geoId = dynamic_pointer_cast<const GeoIdentifierTag>(node); geoId) { + std::lock_guard guard{s_mutex}; + newVol->add(s_geoIds.insert(std::make_pair(geoId->getIdentifier(), const_pointer_cast(geoId))).first->second); + } else if (auto serialId = dynamic_pointer_cast<const GeoSerialIdentifier>(node); serialId) { + std::lock_guard guard{s_mutex}; + newVol->add(s_serialIds.insert(std::make_pair(serialId->getBaseId(), const_pointer_cast(serialId))).first->second); + } else if (auto nameTag = dynamic_pointer_cast<const GeoNameTag>(node); nameTag) { + std::lock_guard guard{s_mutex}; + newVol->add(s_nameTags.insert(std::make_pair(nameTag->getName(), const_pointer_cast(nameTag))).first->second); + } else { + /// Just copy what's left + newVol->add(const_pointer_cast(node)); + } + } + if (tryPhysVolDeDup){ + newVol = cacheVolume(dynamic_pointer_cast<GeoPhysVol>(newVol)); + } + return newVol; } \ No newline at end of file -- GitLab From 01c836e55ddf0f6a7df813f795d469a6a8cc375c Mon Sep 17 00:00:00 2001 From: Johannes Josef Junggeburth <johannes.josef.junggeburth@cern.ch> Date: Sat, 18 Jan 2025 08:48:19 +0100 Subject: [PATCH 3/3] Use GeoIdentifier & nametag from deduplicator --- .../GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx | 4 ++-- .../GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx index 8c1b225d0..e893f7b06 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx @@ -50,7 +50,7 @@ void AssemblyProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, Geo // // Name AssemblyStore& store {m_map[name]}; - physVolName = make_intrusive<GeoNameTag>(name); + physVolName = nameTag(name); store.name = physVolName; } else { // Already in the registry; use it. physVolName = entry->second.name; @@ -58,7 +58,7 @@ void AssemblyProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, Geo lv = gmxUtil.getAssemblyLV(); toAdd.push_back(physVolName); gmxUtil.positionIndex.setCopyNo(m_map[name].id); - toAdd.push_back(make_intrusive<GeoIdentifierTag>(m_map[name].id++)); + toAdd.push_back(geoId(m_map[name].id++)); // // Process the assembly's children // diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx index 8638d8794..11251f58f 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx @@ -115,7 +115,7 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo // LogVolStore* store{&m_map[name]}; if(isNamed) { - nameTag_physVolName = make_intrusive<GeoNameTag>(name); + nameTag_physVolName = nameTag(name); store->name = nameTag_physVolName; } // @@ -228,15 +228,15 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo newName.append("_"); newName.append(std::to_string(index_i.second)); } - nameTag_physChildVolName = make_intrusive<GeoNameTag>(newName);//Make sensitive always have a name, to extra Id information from + nameTag_physChildVolName = nameTag(newName);//Make sensitive always have a name, to extra Id information from toAdd.push_back(nameTag_physChildVolName); if(hasIdentifier) { //TODO: check if all "sensitive" volumes must have an identifier. If that's the case, then we can remove this "if" here - toAdd.push_back(make_intrusive<GeoIdentifierTag>(sensId)); + toAdd.push_back(geoId(sensId)); } } else { if(hasIdentifier) { - toAdd.push_back(make_intrusive<GeoIdentifierTag>(m_map[name].id)); // Normal copy number + toAdd.push_back(geoId(m_map[name].id)); // Normal copy number gmxUtil.positionIndex.setCopyNo(m_map[name].id++); } } -- GitLab