Skip to content

Commit

Permalink
Optimize GeantVolumeManager
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusFrankATcernch committed Jan 21, 2025
1 parent 23df6a7 commit f5058ed
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 165 deletions.
90 changes: 48 additions & 42 deletions DDG4/include/DDG4/Geant4GeometryInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
#include <DD4hep/GeoHandler.h>
#include <DD4hep/PropertyTable.h>
#include <DDG4/Geant4Primitives.h>
#include <DDG4/Geant4TouchableHandler.h>


// C/C++ include files
#include <map>
#include <vector>
#include <cstdint>

// Forward declarations (TGeo)
class TGeoElement;
Expand Down Expand Up @@ -64,24 +67,19 @@ namespace dd4hep {
* \ingroup DD4HEP_SIMULATION
*/
namespace Geant4GeometryMaps {
//typedef std::vector<const G4VPhysicalVolume*> Geant4PlacementPath;
typedef std::map<Atom, G4Element*> ElementMap;
typedef std::map<const TGeoIsotope*, G4Isotope*> IsotopeMap;
typedef std::map<Material, G4Material*> MaterialMap;
//typedef std::map<LimitSet, G4UserLimits*> LimitMap;
typedef std::map<PlacedVolume, G4VPhysicalVolume*> PlacementMap;
//typedef std::map<Region, G4Region*> RegionMap;
typedef std::map<Volume, G4LogicalVolume*> VolumeMap;
typedef std::map<PlacedVolume, Geant4AssemblyVolume*> AssemblyMap;
typedef std::map<Atom, G4Element*> ElementMap;
typedef std::map<const TGeoIsotope*, G4Isotope*> IsotopeMap;
typedef std::map<Material, G4Material*> MaterialMap;
typedef std::map<PlacedVolume, G4VPhysicalVolume*> PlacementMap;
typedef std::map<Volume, G4LogicalVolume*> VolumeMap;
typedef std::map<PlacedVolume, Geant4AssemblyVolume*> AssemblyMap;

typedef std::vector<const TGeoNode*> VolumeChain;
typedef std::pair<VolumeChain,const G4VPhysicalVolume*> ImprintEntry;
typedef std::vector<ImprintEntry> Imprints;
typedef std::map<Volume,Imprints> VolumeImprintMap;
typedef std::map<const TGeoShape*, G4VSolid*> SolidMap;
//typedef std::map<VisAttr, G4VisAttributes*> VisMap;
//typedef std::map<Geant4PlacementPath, VolumeID> Geant4PathMap;
typedef std::map<const G4VPhysicalVolume*, PlacedVolume> G4PlacementMap;
typedef std::vector<const TGeoNode*> PlacedVolumeChain;
typedef std::pair<PlacedVolumeChain,const G4VPhysicalVolume*> ImprintEntry;
typedef std::vector<ImprintEntry> Imprints;
typedef std::map<Volume,Imprints> VolumeImprintMap;
typedef std::map<const TGeoShape*, G4VSolid*> SolidMap;
typedef std::map<const G4VPhysicalVolume*, PlacedVolume> G4PlacementMap;
}

/// Concreate class holding the relation information between geant4 objects and dd4hep objects.
Expand All @@ -92,22 +90,20 @@ namespace dd4hep {
*/
class Geant4GeometryInfo : public TNamed, public detail::GeoHandlerTypes::GeometryInfo {
public:
struct Placement {
VolumeID volumeID;
int flags;
};
union PlacementFlags {
int value;
struct _flags {
unsigned parametrised:1;
unsigned replicated:1;
unsigned path_has_parametrised:1;
unsigned path_has_replicated:1;
} flags;
PlacementFlags() { this->value = 0; }
PlacementFlags(int v) { this->value = v; }
int value;
struct _flags {
unsigned parametrised:1;
unsigned replicated:1;
} flags;
PlacementFlags() { this->value = 0; }
PlacementFlags(int v) { this->value = v; }
};
typedef std::vector<const G4VPhysicalVolume*> Geant4PlacementPath;
struct Placement {
VolumeID volumeID;
int flags;
};

TGeoManager* manager = 0;
Geant4GeometryMaps::IsotopeMap g4Isotopes;
Geant4GeometryMaps::ElementMap g4Elements;
Expand All @@ -126,35 +122,45 @@ namespace dd4hep {
PropertyVector() = default;
~PropertyVector() = default;
};
std::map<PropertyTable, PropertyVector*> g4OpticalProperties;
std::map<OpticalSurface, G4OpticalSurface*> g4OpticalSurfaces;
std::map<SkinSurface, G4LogicalSkinSurface*> g4SkinSurfaces;
std::map<BorderSurface, G4LogicalBorderSurface*> g4BorderSurfaces;
std::map<Region, G4Region*> g4Regions;
std::map<VisAttr, G4VisAttributes*> g4Vis;
std::map<LimitSet, G4UserLimits*> g4Limits;
std::map<Geant4PlacementPath, Placement> g4Paths;
std::map<PropertyTable, PropertyVector*> g4OpticalProperties;
std::map<OpticalSurface, G4OpticalSurface*> g4OpticalSurfaces;
std::map<SkinSurface, G4LogicalSkinSurface*> g4SkinSurfaces;
std::map<BorderSurface, G4LogicalBorderSurface*> g4BorderSurfaces;
std::map<Region, G4Region*> g4Regions;
std::map<VisAttr, G4VisAttributes*> g4Vis;
std::map<LimitSet, G4UserLimits*> g4Limits;
#ifdef OLD_VOLMGR_TYPE
typedef std::vector<const G4VPhysicalVolume*> Geant4PlacementPath;
std::map<Geant4PlacementPath, Placement> g4Paths;
#else
std::map<uint64_t, Placement> g4Paths;
#endif
std::map<SensitiveDetector,std::set<const TGeoVolume*> > sensitives;
std::map<Region, std::set<const TGeoVolume*> > regions;
std::map<LimitSet, std::set<const TGeoVolume*> > limits;
G4VPhysicalVolume* m_world;
PrintLevel printLevel;
bool has_volmgr;
bool valid;

/// Assemble Geant4 volume path
static std::string placementPath(const Geant4TouchableHandler::Geant4PlacementPath& path, bool reverse=true) {
return Geant4TouchableHandler::placementPath(path, reverse);
}

private:
friend class Geant4Mapping;
/// Default constructor
Geant4GeometryInfo();
/// Default destructor
virtual ~Geant4GeometryInfo();

public:
/// The world placement
G4VPhysicalVolume* world() const;
/// Set the world volume
void setWorld(const TGeoNode* node);
/// Assemble Geant4 volume path
static std::string placementPath(const Geant4PlacementPath& path, bool reverse=true);
};

} // End namespace sim
} // End namespace dd4hep
#endif // DDG4_GEANT4GEOMETRYINFO_H
3 changes: 3 additions & 0 deletions DDG4/include/DDG4/Geant4TouchableHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ namespace dd4hep {
/// Default constructor. Takes the step's pre-touchable
Geant4TouchableHandler(const G4Step* step, bool use_post_step_point);

/// Assemble Geant4 volume path
static std::string placementPath(const Geant4PlacementPath& path, bool reverse=true);

/// Helper: Generate placement path from touchable object
Geant4PlacementPath placementPath(bool exception=false) const;

Expand Down
5 changes: 2 additions & 3 deletions DDG4/include/DDG4/Geant4VolumeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include <DD4hep/IDDescriptor.h>
#include <DDG4/Geant4Primitives.h>

// Geant4 include files
#include <G4VTouchable.hh>

// Geant4 forward declarations
class G4VPhysicalVolume;

Expand Down Expand Up @@ -68,8 +70,6 @@ namespace dd4hep {
/// Helper: Generate placement path from touchable object
std::vector<const G4VPhysicalVolume*>
placementPath(const G4VTouchable* touchable, bool exception = true) const;
/// Access CELLID by placement path
//VolumeID volumeID(const std::vector<const G4VPhysicalVolume*>& path) const;
/// Access CELLID by Geant4 touchable object
VolumeID volumeID(const G4VTouchable* touchable) const;
/// Accessfully decoded volume fields by placement path
Expand All @@ -79,7 +79,6 @@ namespace dd4hep {
void volumeDescriptor(const G4VTouchable* touchable,
std::pair<VolumeID,std::vector<std::pair<const BitFieldElement*, VolumeID> > >& volume_desc) const;
};

} // End namespace sim
} // End namespace dd4hep
#endif // DDG4_GEANT4VOLUMEMANAGER_H
32 changes: 16 additions & 16 deletions DDG4/src/Geant4AssemblyVolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,

path = detail::tools::placementPath(chain);
printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
"++ Assembly: %s", path.c_str());
"++ Assembly: %s", path.c_str());
std::vector<G4AssemblyTriplet>::iterator iter = par_ass->GetTripletsIterator();
for( unsigned int i = 0, n = par_ass->TotalTriplets(); i < n; i++, iter++ ) {
Chain new_chain = chain;
Expand All @@ -97,14 +97,14 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
new_chain.emplace_back(node);
path = detail::tools::placementPath(new_chain);
printout(cnv.debugPlacements ? ALWAYS : DEBUG, "Geant4Converter",
" Assembly: Entry: %s", path.c_str());
" Assembly: Entry: %s", path.c_str());

G4Transform3D Ta( *(triplet.GetRotation()), triplet.GetTranslation() );
if ( triplet.IsReflection() ) {
if( triplet.IsReflection() ) {
Ta = Ta * G4ReflectZ3D();
}
G4Transform3D Tfinal = transformation * Ta;
if ( triplet.GetVolume() ) {
if( triplet.GetVolume() ) {
// Generate the unique name for the next PV instance
// The name has format:
//
Expand All @@ -119,9 +119,9 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
pvName << "AV_"
<< m_assembly->GetAssemblyID()
<< '!'
<< parent->GetName()
<< '#'
<< parent->GetNumber()
<< parent->GetName()
<< '#'
<< parent->GetNumber()
<< '!'
<< node->GetName()
<< '#'
Expand All @@ -140,24 +140,24 @@ void Geant4AssemblyVolume::imprint(const Geant4Converter& cnv,
node->GetNumber(),
surfCheck );

info.g4VolumeImprints[vol].emplace_back(new_chain,pvPlaced.first);
info.g4VolumeImprints[vol].emplace_back(new_chain, pvPlaced.first);
printout(cnv.debugPlacements ? ALWAYS : DEBUG,
"Geant4Converter", "++ Place %svolume %s in assembly.",
triplet.IsReflection() ? "REFLECTED " : "", path.c_str());
"Geant4Converter", "++ Place %svolume %s in assembly.",
triplet.IsReflection() ? "REFLECTED " : "", path.c_str());
printout(cnv.debugPlacements ? ALWAYS : DEBUG,
"Geant4Converter", " Assembly:Parent: %s %s %p G4:%s",
parent->GetName(), node->GetName(),
(void*)node, pvName.str().c_str());
if ( pvPlaced.second ) {
"Geant4Converter", " Assembly:Parent: %s %s %p G4:%s",
parent->GetName(), node->GetName(),
(void*)node, pvName.str().c_str());
if( pvPlaced.second ) {
G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
"Fancy construct popping new mother from the stack!");
}
}
else if ( triplet.GetAssembly() ) {
else if( triplet.GetAssembly() ) {
// Place volumes in this assembly with composed transformation
imprint(cnv, parent, std::move(new_chain), avol, pMotherLV, Tfinal, surfCheck );
}
else {
else {
G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException,
"Triplet has no volume and no assembly");
}
Expand Down
16 changes: 10 additions & 6 deletions DDG4/src/Geant4Converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,9 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
PrintLevel lvl = debugVolumes ? ALWAYS : outputLevel;
Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(volume);
if ( _v.testFlagBit(Volume::VETO_SIMU) ) {
printout(lvl, "Geant4Converter", "++ Volume %s not converted [Veto'ed for simulation]",volume->GetName());
printout(lvl, "Geant4Converter",
"++ Volume %s not converted [Veto'ed for simulation]",
volume->GetName());
return nullptr;
}
else if (volIt == info.g4Volumes.end() ) {
Expand Down Expand Up @@ -786,7 +788,7 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v

G4LogicalVolume* g4vol = nullptr;
if( _v.hasProperties() && !_v.getProperty(GEANT4_TAG_PLUGIN,"").empty() ) {
Detector* det = const_cast<Detector*>(&m_detDesc);
Detector* det = const_cast<Detector*>(&m_detDesc);
std::string plugin = _v.getProperty(GEANT4_TAG_PLUGIN,"");
g4vol = PluginService::Create<G4LogicalVolume*>(plugin, det, _v, g4solid, g4medium);
if ( !g4vol ) {
Expand All @@ -800,17 +802,19 @@ void* Geant4Converter::handleVolume(const std::string& name, const TGeoVolume* v
/// Set smartless optimization
unsigned char smart_less_value = _v.smartlessValue();
if( smart_less_value != Volume::NO_SMARTLESS_OPTIMIZATION ) {
printout(ALWAYS, "Geant4Converter", "++ Volume %s Set Smartless value to %d",
vnam, int(smart_less_value));
printout(ALWAYS, "Geant4Converter",
"++ Volume %s Set Smartless value to %d",
vnam, int(smart_less_value));
g4vol->SetSmartless( smart_less_value );
}
/// Assign limits if necessary
if( g4limits ) {
g4vol->SetUserLimits(g4limits);
}
if( g4region ) {
printout(plevel, "Geant4Converter", "++ Volume + Apply REGION settings: %-24s to volume %s.",
reg.name(), vnam);
printout(plevel, "Geant4Converter",
"++ Volume + Apply REGION settings: %-24s to volume %s.",
reg.name(), vnam);
// Handle the region settings for the world volume seperately.
// Geant4 does NOT WANT any regions assigned to the workd volume.
// The world's region is created in the G4RunManagerKernel!
Expand Down
15 changes: 0 additions & 15 deletions DDG4/src/Geant4GeometryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,6 @@

using namespace dd4hep::sim;

std::string Geant4GeometryInfo::placementPath(const Geant4PlacementPath& path, bool reverse) {
std::string path_name;
if ( reverse ) {
for (Geant4PlacementPath::const_reverse_iterator pIt = path.rbegin(); pIt != path.rend(); ++pIt) {
path_name += "/"; path_name += (*pIt)->GetName();
}
}
else {
for (Geant4PlacementPath::const_iterator pIt = path.begin(); pIt != path.end(); ++pIt) {
path_name += "/"; path_name += (*pIt)->GetName();
}
}
return path_name;
}

/// Default constructor
Geant4GeometryInfo::Geant4GeometryInfo()
: TNamed("Geant4GeometryInfo", "Geant4GeometryInfo"), m_world(0), printLevel(DEBUG), valid(false) {
Expand Down
2 changes: 1 addition & 1 deletion DDG4/src/Geant4Mapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void Geant4Mapping::attach(Geant4GeometryInfo* data_ptr) {
/// Access the volume manager
Geant4VolumeManager Geant4Mapping::volumeManager() const {
if ( m_dataPtr ) {
if ( m_dataPtr->g4Paths.empty() ) {
if ( m_dataPtr->has_volmgr ) {
return Geant4VolumeManager(m_detDesc, m_dataPtr);
}
return Geant4VolumeManager(Handle < Geant4GeometryInfo > (m_dataPtr));
Expand Down
18 changes: 17 additions & 1 deletion DDG4/src/Geant4TouchableHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,24 @@ Geant4TouchableHandler::Geant4PlacementPath Geant4TouchableHandler::placementPat
return path_val;
}

/// Assemble Geant4 volume path
std::string Geant4TouchableHandler::placementPath(const Geant4PlacementPath& path, bool reverse) {
std::string path_name;
if ( reverse ) {
for (Geant4PlacementPath::const_reverse_iterator pIt = path.rbegin(); pIt != path.rend(); ++pIt) {
path_name += "/"; path_name += (*pIt)->GetName();
}
}
else {
for (Geant4PlacementPath::const_iterator pIt = path.begin(); pIt != path.end(); ++pIt) {
path_name += "/"; path_name += (*pIt)->GetName();
}
}
return path_name;
}

/// Helper: Access the placement path of a Geant4 touchable object as a string
std::string Geant4TouchableHandler::path() const {
return Geant4GeometryInfo::placementPath(this->placementPath());
return Geant4TouchableHandler::placementPath(this->placementPath());
}

Loading

0 comments on commit f5058ed

Please sign in to comment.