From 295696795b4581bb6453b98ace35a9bab5c6b002 Mon Sep 17 00:00:00 2001 From: Leonhard Reichenbach Date: Tue, 30 Jul 2024 15:01:13 +0200 Subject: [PATCH 1/3] kill white space --- DDRec/include/DDRec/SurfaceManager.h | 18 +++++++------- DDRec/src/SurfaceManager.cpp | 36 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/DDRec/include/DDRec/SurfaceManager.h b/DDRec/include/DDRec/SurfaceManager.h index eb6d5b210..dd75f0c8c 100644 --- a/DDRec/include/DDRec/SurfaceManager.h +++ b/DDRec/include/DDRec/SurfaceManager.h @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -21,13 +21,13 @@ namespace dd4hep { namespace rec { - /// typedef for surface maps, keyed by the cellID + /// typedef for surface maps, keyed by the cellID typedef std::multimap< unsigned long, ISurface*> SurfaceMap ; - /** Surface manager class that holds maps of surfaces for all known - * sensitive detector types and individual sub detectors. + /** Surface manager class that holds maps of surfaces for all known + * sensitive detector types and individual sub detectors. * Maps can be retrieved via detector name. - * + * * @author F.Gaede, DESY * @date May, 11 2015 * @version $Id$ @@ -48,23 +48,23 @@ namespace dd4hep { #endif /// No copy constructor SurfaceManager(const SurfaceManager& copy) = delete; - + /// Default destructor ~SurfaceManager(); /// No assignment operator SurfaceManager& operator=(const SurfaceManager& copy) = delete; - + /** Get the maps of all surfaces associated to the given detector or * type of detectors, e.g. map("tracker") returns a map with all surfaces * assigned to tracking detectors. Returns 0 if no map exists. */ const SurfaceMap* map( const std::string name ) const ; - + ///create a string with all available maps and their size (number of surfaces) std::string toString() const ; - + protected : diff --git a/DDRec/src/SurfaceManager.cpp b/DDRec/src/SurfaceManager.cpp index 2576ebb41..3170769de 100644 --- a/DDRec/src/SurfaceManager.cpp +++ b/DDRec/src/SurfaceManager.cpp @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -19,11 +19,11 @@ #include namespace dd4hep { - + using namespace detail ; namespace rec { - + SurfaceManager::SurfaceManager(const Detector& theDetector){ @@ -34,12 +34,12 @@ namespace dd4hep { initialize(theDetector) ; } - + SurfaceManager::~SurfaceManager(){ // nothing to do } - - + + const SurfaceMap* SurfaceManager::map( const std::string name ) const { SurfaceMapsMap::const_iterator it = _map.find( name ) ; @@ -53,34 +53,34 @@ namespace dd4hep { } void SurfaceManager::initialize(const Detector& description) { - + const std::vector& types = description.detectorTypes() ; for(unsigned i=0,N=types.size();i& dets = description.detectors( types[i] ) ; + const std::vector& dets = description.detectors( types[i] ) ; for(unsigned j=0,M=dets.size();jid(), surf ); // enter surface into map for detector type _map[ types[i] ].emplace(surf->id(), surf ); - // enter surface into world map + // enter surface into world map _map[ "world" ].emplace(surf->id(), surf ); } @@ -90,14 +90,14 @@ namespace dd4hep { } std::string SurfaceManager::toString() const { - + std::stringstream sstr ; - + sstr << "-------- SurfaceManager contains the following maps : --------- " << std::endl ; - + for( SurfaceMapsMap::const_iterator mi = _map.begin() ; mi != _map.end() ; ++mi ) { - - sstr << " key: " << mi->first << " \t number of surfaces : " << mi->second.size() << std::endl ; + + sstr << " key: " << mi->first << " \t number of surfaces : " << mi->second.size() << std::endl ; } sstr << "---------------------------------------------------------------- " << std::endl ; From 25d13d1741d1f7f18ee6f2fb4679f66322fcc095 Mon Sep 17 00:00:00 2001 From: Leonhard Reichenbach Date: Fri, 2 Aug 2024 14:27:17 +0200 Subject: [PATCH 2/3] enable lazy surface map construction --- DDRec/include/DDRec/SurfaceManager.h | 12 ++- DDRec/src/SurfaceManager.cpp | 112 ++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 11 deletions(-) diff --git a/DDRec/include/DDRec/SurfaceManager.h b/DDRec/include/DDRec/SurfaceManager.h index dd75f0c8c..5435a7513 100644 --- a/DDRec/include/DDRec/SurfaceManager.h +++ b/DDRec/include/DDRec/SurfaceManager.h @@ -17,6 +17,7 @@ #include "DD4hep/Detector.h" #include #include +#include namespace dd4hep { namespace rec { @@ -34,7 +35,7 @@ namespace dd4hep { */ class SurfaceManager { - typedef std::map< std::string, SurfaceMap > SurfaceMapsMap ; + typedef std::map< std::string, std::pair> SurfaceMapsMap; public: /// The constructor @@ -59,7 +60,7 @@ namespace dd4hep { * type of detectors, e.g. map("tracker") returns a map with all surfaces * assigned to tracking detectors. Returns 0 if no map exists. */ - const SurfaceMap* map( const std::string name ) const ; + const SurfaceMap* map( const std::string name ); ///create a string with all available maps and their size (number of surfaces) @@ -71,7 +72,14 @@ namespace dd4hep { /// initialize all known surface maps void initialize(const Detector& theDetector) ; + /// name has to be the name of a single detector! not e.g. tracker or world. + const SurfaceMap& getOrConstruct(const std::string name); + SurfaceMapsMap _map ; + const Detector& m_detector; + std::set m_detectorNames; + std::set m_detectorTypes; + std::map> m_missingDetectors; }; } /* namespace rec */ diff --git a/DDRec/src/SurfaceManager.cpp b/DDRec/src/SurfaceManager.cpp index 3170769de..6aea7aecb 100644 --- a/DDRec/src/SurfaceManager.cpp +++ b/DDRec/src/SurfaceManager.cpp @@ -25,14 +25,28 @@ namespace dd4hep { namespace rec { - SurfaceManager::SurfaceManager(const Detector& theDetector){ + SurfaceManager::SurfaceManager(const Detector& theDetector) : + m_detector(theDetector) + { // have to make sure the volume manager is populated once in order to have // the volumeIDs attached to the DetElements VolumeManager::getVolumeManager(theDetector); - initialize(theDetector) ; + std::set worldSet{}; + // collect all detector names that belong to a type e.g.: tracker, calorimeter, passive + for (const std::string& typeName : theDetector.detectorTypes()) { + m_detectorTypes.insert(typeName); + std::set nameSet{}; + for (const DetElement& det : theDetector.detectors(typeName)) { + m_detectorNames.insert(det.name()); + nameSet.insert(det.name()); + } + worldSet.insert(nameSet.begin(), nameSet.end()); + m_missingDetectors.emplace(typeName, std::move(nameSet)); + } + m_missingDetectors.emplace("world", std::move(worldSet)); } SurfaceManager::~SurfaceManager(){ @@ -40,16 +54,96 @@ namespace dd4hep { } - const SurfaceMap* SurfaceManager::map( const std::string name ) const { + const SurfaceMap* SurfaceManager::map( const std::string name ) { + // return map if it already exists and is complete SurfaceMapsMap::const_iterator it = _map.find( name ) ; + if(it != _map.end() && it->second.first) { + return &it->second.second ; + } + + // surface map does not exist or is not completed yet, build it + + bool isDetector = m_detectorNames.find(name) != m_detectorNames.end(); + bool isDetectorType = m_detectorTypes.find(name) != m_detectorTypes.end(); + bool isWorld = name == "world"; - if( it != _map.end() ){ + if (isDetector) { + // name is a detector: easiest case + return &getOrConstruct(name); + } else if (!isDetectorType && !isWorld) { + // neither a type name nor world -> invalid + // TODO: maybe do an additional debug printout (not done in original implementation!) + return 0; + } + + // if we arrived here we were asked for a type map like tracker or world + // get missing detectors, construct them, look up map again and return it + auto& missingDets = m_missingDetectors[name]; + for (const auto& detName : missingDets) { + getOrConstruct(detName); + } + + return &_map[name].second; + } - return & it->second ; + const SurfaceMap& SurfaceManager::getOrConstruct(const std::string name) { + // check if we already have this map + { + auto it = _map.find(name); + // second condition is always true because we only call this method with name in m_detectorNames + // i.e. no compounds like tracker or world! + if(it != _map.end() /* && it->second.first */){ + return it->second.second ; + } + } // scope to get rid of it variable that is useless after this + + // map does not exist yet, we need to construct it ourselves + // if our detector is also in detectorTypes we construct that + // part of the corresponding surface map also + + std::vector> types; + // we also want to construct a map for the detector itself + // so we just add it first and set it to be valid as we + // will construct it completely + types.push_back(std::make_pair(name, true)); + + // first, check if it is part of any compounds to also add our surfaces to them + // remove the name at the same time as we will construct the map for it now + for (auto& [typeName, nameSet] : m_missingDetectors) { + bool found = nameSet.erase(name); + if (found) { + // we store the typename and if it was the last missing detector of this type + types.push_back(std::make_pair(typeName, nameSet.empty())); + } + } + + // make a vector of references to all the maps that we need to add surfaces to + std::vector>> maps{}; + for (const auto& [typeName, valid] : types) { + auto it = _map.find(typeName); + if (it == _map.end()) { + // need to create a new empty map in the global _map + const auto& res = _map.emplace(typeName, std::make_pair(valid, SurfaceMap())); + maps.push_back(res.first->second); + } else { + maps.push_back(it->second); + } + } + + // now get the surfaces and put them into the maps + const DetElement& det = m_detector.detector(name); + SurfaceHelper surfHelper(det); + const SurfaceList& surfList = surfHelper.surfaceList(); + + for (ISurface* surf : surfList) { + for (auto& map : maps) { + map.get().second.emplace(surf->id(), surf); + } } - return 0 ; + // return the map of the detector + return maps[0].get().second; } void SurfaceManager::initialize(const Detector& description) { @@ -97,7 +191,7 @@ namespace dd4hep { for( SurfaceMapsMap::const_iterator mi = _map.begin() ; mi != _map.end() ; ++mi ) { - sstr << " key: " << mi->first << " \t number of surfaces : " << mi->second.size() << std::endl ; + sstr << " key: " << mi->first << " \t number of surfaces : " << mi->second.second.size() << std::endl ; } sstr << "---------------------------------------------------------------- " << std::endl ; @@ -105,5 +199,5 @@ namespace dd4hep { } - } // namespace -}// namespace + } // namespace rec +} // namespace dd4hep From 3f99f2acf2cfa776b8a164c2710ad921ec1dc04e Mon Sep 17 00:00:00 2001 From: Leonhard Reichenbach Date: Fri, 2 Aug 2024 14:35:21 +0200 Subject: [PATCH 3/3] remove now unused initialize function --- DDRec/include/DDRec/SurfaceManager.h | 4 --- DDRec/src/SurfaceManager.cpp | 37 ---------------------------- 2 files changed, 41 deletions(-) diff --git a/DDRec/include/DDRec/SurfaceManager.h b/DDRec/include/DDRec/SurfaceManager.h index 5435a7513..f12e7d508 100644 --- a/DDRec/include/DDRec/SurfaceManager.h +++ b/DDRec/include/DDRec/SurfaceManager.h @@ -68,10 +68,6 @@ namespace dd4hep { protected : - - /// initialize all known surface maps - void initialize(const Detector& theDetector) ; - /// name has to be the name of a single detector! not e.g. tracker or world. const SurfaceMap& getOrConstruct(const std::string name); diff --git a/DDRec/src/SurfaceManager.cpp b/DDRec/src/SurfaceManager.cpp index 6aea7aecb..563ad2ead 100644 --- a/DDRec/src/SurfaceManager.cpp +++ b/DDRec/src/SurfaceManager.cpp @@ -146,43 +146,6 @@ namespace dd4hep { return maps[0].get().second; } - void SurfaceManager::initialize(const Detector& description) { - - const std::vector& types = description.detectorTypes() ; - - for(unsigned i=0,N=types.size();i& dets = description.detectors( types[i] ) ; - - for(unsigned j=0,M=dets.size();jid(), surf ); - - // enter surface into map for detector type - _map[ types[i] ].emplace(surf->id(), surf ); - - // enter surface into world map - _map[ "world" ].emplace(surf->id(), surf ); - - } - } - } - - } - std::string SurfaceManager::toString() const { std::stringstream sstr ;