File indexing completed on 2025-01-30 09:17:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Objects.h>
0016 #include <DDG4/Defs.h>
0017 #include <DDG4/Geant4SteppingAction.h>
0018
0019
0020 class G4LogicalVolume;
0021
0022
0023 namespace dd4hep {
0024
0025
0026 namespace sim {
0027
0028
0029
0030
0031
0032
0033
0034
0035 class Geant4GeometryScanner : public Geant4SteppingAction {
0036 protected:
0037
0038 class StepInfo {
0039 public:
0040
0041 Position pre, post;
0042
0043 std::string path;
0044
0045 const G4LogicalVolume* volume;
0046
0047
0048 StepInfo(const Position& pre,
0049 const Position& post,
0050 const G4LogicalVolume* volume,
0051 const std::string& path);
0052
0053 StepInfo(const StepInfo& c);
0054
0055 ~StepInfo() {}
0056
0057 StepInfo& operator=(const StepInfo& c);
0058 };
0059 typedef std::vector<StepInfo*> Steps;
0060 Steps m_steps;
0061 double m_sumPath = 0;
0062 public:
0063
0064 Geant4GeometryScanner(Geant4Context* context, const std::string& name);
0065
0066 virtual ~Geant4GeometryScanner();
0067
0068 virtual void operator()(const G4Step* step, G4SteppingManager* mgr);
0069
0070 virtual void begin(const G4Track* track);
0071
0072 virtual void end(const G4Track* track);
0073
0074 void beginEvent(const G4Event* event);
0075 };
0076 }
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 #include <DD4hep/InstanceCount.h>
0089 #include <DD4hep/Printout.h>
0090 #include <DDG4/Geant4TouchableHandler.h>
0091 #include <DDG4/Geant4StepHandler.h>
0092 #include <DDG4/Geant4EventAction.h>
0093 #include <DDG4/Geant4TrackingAction.h>
0094 #include <CLHEP/Units/SystemOfUnits.h>
0095 #include <G4LogicalVolume.hh>
0096 #include <G4Material.hh>
0097 #include <G4VSolid.hh>
0098
0099 using namespace dd4hep::sim;
0100
0101 #include <DDG4/Factories.h>
0102 DECLARE_GEANT4ACTION(Geant4GeometryScanner)
0103
0104
0105 Geant4GeometryScanner::StepInfo::StepInfo(const Position& prePos,
0106 const Position& postPos,
0107 const G4LogicalVolume* vol,
0108 const std::string& p)
0109 : pre(prePos), post(postPos), path(p), volume(vol)
0110 {
0111 }
0112
0113
0114 Geant4GeometryScanner::StepInfo::StepInfo(const StepInfo& c)
0115 : pre(c.pre), post(c.post), path(c.path), volume(c.volume)
0116 {
0117 }
0118
0119
0120 Geant4GeometryScanner::StepInfo& Geant4GeometryScanner::StepInfo::operator=(const StepInfo& c) {
0121 pre = c.pre;
0122 post = c.post;
0123 volume = c.volume;
0124 return *this;
0125 }
0126
0127
0128 Geant4GeometryScanner::Geant4GeometryScanner(Geant4Context* ctxt, const std::string& nam)
0129 : Geant4SteppingAction(ctxt,nam)
0130 {
0131 m_needsControl = true;
0132 eventAction().callAtBegin(this,&Geant4GeometryScanner::beginEvent);
0133 trackingAction().callAtEnd(this,&Geant4GeometryScanner::end);
0134 trackingAction().callAtBegin(this,&Geant4GeometryScanner::begin);
0135 InstanceCount::increment(this);
0136 }
0137
0138
0139 Geant4GeometryScanner::~Geant4GeometryScanner() {
0140 InstanceCount::decrement(this);
0141 }
0142
0143
0144 void Geant4GeometryScanner::operator()(const G4Step* step, G4SteppingManager*) {
0145 Geant4StepHandler h(step);
0146 Geant4TouchableHandler handler(step);
0147 m_steps.emplace_back(new StepInfo(h.prePos(), h.postPos(), h.logvol(h.pre), handler.path()));
0148 }
0149
0150
0151 void Geant4GeometryScanner::beginEvent(const G4Event* ) {
0152 for_each(m_steps.begin(),m_steps.end(),detail::DestroyObject<StepInfo*>());
0153 m_steps.clear();
0154 m_sumPath = 0;
0155 }
0156
0157
0158 void Geant4GeometryScanner::begin(const G4Track* track) {
0159 printP2("Starting tracking action for track ID=%d",track->GetTrackID());
0160 for_each(m_steps.begin(),m_steps.end(),detail::DestroyObject<StepInfo*>());
0161 m_steps.clear();
0162 m_sumPath = 0;
0163 }
0164
0165
0166 void Geant4GeometryScanner::end(const G4Track* track) {
0167 if ( !m_steps.empty() ) {
0168 constexpr const char* line = " +--------------------------------------------------------------------------------------------------------------------------------------------------\n";
0169 constexpr const char* fmt = " | %5d %11.4f %9.3f (%7.2f,%7.2f,%7.2f) Path:\"/world%s\" Shape:%s Mat:%s\n";
0170 const Position& start = m_steps[0]->pre;
0171 const Position& stop = m_steps[m_steps.size()-1]->post;
0172
0173 ::printf("%s + Geometry scan between: x_0 = (%7.2f,%7.2f,%7.2f) [cm] and x_1 = (%7.2f,%7.2f,%7.2f) [cm] TrackID:%d: \n%s",
0174 line,start.X()/CLHEP::cm,start.Y()/CLHEP::cm,start.Z()/CLHEP::cm,
0175 stop.X()/CLHEP::cm,stop.Y()/CLHEP::cm,stop.Z()/CLHEP::cm,
0176 track->GetTrackID(),line);
0177 ::printf(" | \\ Path \n");
0178 ::printf(" | Num. \\ Thickness Length Endpoint Volume , Shape , Material\n");
0179 ::printf(" | Layer \\ [cm] [cm] ( cm, cm, cm) \n");
0180 ::printf("%s",line);
0181 int count = 1;
0182 for(Steps::const_iterator i=m_steps.begin(); i!=m_steps.end(); ++i, ++count) {
0183 const G4LogicalVolume* logVol = (*i)->volume;
0184 G4Material* material = logVol->GetMaterial();
0185 G4VSolid* solid = logVol->GetSolid();
0186 const Position& prePos = (*i)->pre;
0187 const Position& postPos = (*i)->post;
0188 Position direction = postPos - prePos;
0189 double length = direction.R()/CLHEP::cm;
0190 m_sumPath += length;
0191 ::printf(fmt,count,
0192 length, m_sumPath,
0193 postPos.X()/CLHEP::cm,postPos.Y()/CLHEP::cm,postPos.Z()/CLHEP::cm,
0194 (*i)->path.c_str(), typeName(typeid(*solid)).c_str(), material->GetName().c_str());
0195 }
0196 for_each(m_steps.begin(),m_steps.end(),detail::DestroyObject<StepInfo*>());
0197 m_steps.clear();
0198 }
0199 }