Skip to content

Commit

Permalink
enable lazy surface map construction
Browse files Browse the repository at this point in the history
  • Loading branch information
Zehvogel committed Aug 2, 2024
1 parent 2956967 commit 25d13d1
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
12 changes: 10 additions & 2 deletions DDRec/include/DDRec/SurfaceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "DD4hep/Detector.h"
#include <string>
#include <map>
#include <set>

namespace dd4hep {
namespace rec {
Expand All @@ -34,7 +35,7 @@ namespace dd4hep {
*/
class SurfaceManager {

typedef std::map< std::string, SurfaceMap > SurfaceMapsMap ;
typedef std::map< std::string, std::pair<bool, SurfaceMap>> SurfaceMapsMap;

public:
/// The constructor
Expand All @@ -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)
Expand All @@ -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<std::string> m_detectorNames;
std::set<std::string> m_detectorTypes;
std::map<std::string, std::set<std::string>> m_missingDetectors;
};

} /* namespace rec */
Expand Down
112 changes: 103 additions & 9 deletions DDRec/src/SurfaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,125 @@ 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<std::string> 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<std::string> 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(){
// nothing to do
}


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<std::pair<std::string, bool>> 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<std::reference_wrapper<std::pair<bool, SurfaceMap>>> 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) {
Expand Down Expand Up @@ -97,13 +191,13 @@ 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 ;

return sstr.str() ;
}


} // namespace
}// namespace
} // namespace rec
} // namespace dd4hep

0 comments on commit 25d13d1

Please sign in to comment.