File indexing completed on 2025-01-18 09:14:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_DDG4_HITTUPLEACTION_H
0014 #define DD4HEP_DDG4_HITTUPLEACTION_H
0015
0016
0017 #include "DDG4/Geant4EventAction.h"
0018
0019
0020 class G4VHitsCollection;
0021 class TFile;
0022 class TTree;
0023 class TBranch;
0024
0025
0026 namespace myanalysis {
0027
0028
0029 class Geant4ParticleMap;
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 class HitTupleAction : public dd4hep::sim::Geant4EventAction {
0040 public:
0041 typedef std::vector<std::string> CollectionNames;
0042
0043 CollectionNames m_containers;
0044
0045 std::string m_outFileName;
0046
0047 TFile* m_outFile = 0;
0048
0049 TTree* m_outTree = 0;
0050
0051 typedef std::pair<double, std::vector<double> > Data;
0052
0053 std::map<std::string, std::pair<TBranch*, Data> > m_deposits;
0054
0055 public:
0056
0057 HitTupleAction(dd4hep::sim::Geant4Context* context, const std::string& nam);
0058
0059 virtual ~HitTupleAction();
0060
0061 void beginRun(const G4Run* run);
0062
0063 void endRun(const G4Run* run);
0064
0065 virtual void begin(const G4Event* event) override;
0066
0067 virtual void end(const G4Event* event) override;
0068 };
0069 }
0070 #endif
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 #include "DDG4/Geant4DataDump.h"
0087 #include "DDG4/Geant4RunAction.h"
0088 #include "DDG4/Geant4HitCollection.h"
0089
0090
0091 #include "G4HCofThisEvent.hh"
0092 #include "G4Event.hh"
0093
0094
0095 #include "TFile.h"
0096 #include "TTree.h"
0097 #include "TROOT.h"
0098 #include "TClass.h"
0099 #include "TBranch.h"
0100
0101 using namespace std;
0102 using namespace dd4hep;
0103 using namespace dd4hep::sim;
0104
0105
0106 myanalysis::HitTupleAction::HitTupleAction(Geant4Context* ctxt, const string& nam)
0107 : Geant4EventAction(ctxt, nam), m_containers{"*"}
0108 {
0109 m_needsControl = true;
0110 m_containers.push_back("*");
0111 declareProperty("OutputFile", m_outFileName);
0112 declareProperty("Collections", m_containers);
0113 runAction().callAtBegin(this, &HitTupleAction::beginRun);
0114 runAction().callAtEnd(this, &HitTupleAction::endRun);
0115 }
0116
0117
0118 myanalysis::HitTupleAction::~HitTupleAction() {
0119 }
0120
0121
0122 void myanalysis::HitTupleAction::beginRun(const G4Run* ) {
0123 }
0124
0125
0126 void myanalysis::HitTupleAction::endRun(const G4Run* ) {
0127 if ( m_outFile ) {
0128 if ( m_outTree ) {
0129 m_outTree->Print();
0130 }
0131 m_outFile->Write();
0132 m_outFile->Close();
0133 delete m_outFile;
0134 m_outFile = 0;
0135 }
0136 }
0137
0138
0139 void myanalysis::HitTupleAction::begin(const G4Event* ) {
0140 }
0141
0142
0143 void myanalysis::HitTupleAction::end(const G4Event* event) {
0144 G4HCofThisEvent* hce = event->GetHCofThisEvent();
0145 if ( hce ) {
0146 int nCol = hce->GetNumberOfCollections();
0147 if ( nCol <= 0 ) {
0148 return;
0149 }
0150 else if ( !m_outFile ) {
0151
0152 m_outFile = TFile::Open(m_outFileName.c_str(), "RECREATE", "DDG4 User file");
0153 if ( m_outFile && !m_outFile->IsZombie() ) {
0154 m_outTree = new TTree("DDG4 User Test","DDG4 data");
0155 printout(ALWAYS,"HitTupleAction","+++ Successfully opened ROOT file %s and created TTree:%s",
0156 m_outFile->GetName(), "DDG4 User Test");
0157 if ( m_containers.size() == 1 && (m_containers[0] == "*" || m_containers[0] == "ALL") ) {
0158 m_containers.clear();
0159 for (int i = 0; i < nCol; ++i)
0160 m_containers.push_back(hce->GetHC(i)->GetName());
0161 }
0162
0163 for(const auto& c : m_containers) {
0164 m_deposits[c].first = 0;
0165 m_deposits[c].second.first = 0e0;
0166 m_deposits[c].second.second.clear();
0167 }
0168 for(const auto& c : m_containers) {
0169 std::pair<TBranch*, Data>& e = m_deposits[c];
0170 TClass* cl = gROOT->GetClass(typeid(Data));
0171 e.first = m_outTree->Branch(c.c_str(), cl->GetName(), (void*)0);
0172 e.first->SetAutoDelete(false);
0173 printout(ALWAYS,"HitTupleAction","+++ Prepare hit branch %s in root file.",c.c_str());
0174 }
0175 }
0176 else {
0177 except("HitTupleAction","Failed to open ROOT N-tuple file: %s",m_outFileName.c_str());
0178 }
0179 }
0180 for ( auto& e : m_deposits ) {
0181 e.second.first->SetAddress(0);
0182 }
0183 for (int i = 0; i < nCol; ++i) {
0184 G4VHitsCollection* hc = hce->GetHC(i);
0185 const string& nam = hc->GetName();
0186 if ( find(m_containers.begin(),m_containers.end(),nam) != m_containers.end() ) {
0187 Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(hc);
0188 if ( coll ) {
0189 std::pair<TBranch*, Data>& e = m_deposits[nam];
0190 size_t nhits = coll->GetSize();
0191 Data* d = &e.second;
0192
0193 e.second.first = 0e0;
0194 e.second.second.clear();
0195 e.first->SetAddress(&d);
0196 for ( size_t j=0; j<nhits; ++j ) {
0197 double dep = 0e0;
0198 Geant4HitData* h = coll->hit(j);
0199 Geant4Tracker::Hit* trk_hit = dynamic_cast<Geant4Tracker::Hit*>(h);
0200 if ( 0 != trk_hit ) {
0201 dep = trk_hit->truth.deposit;
0202 }
0203 else {
0204 Geant4Calorimeter::Hit* cal_hit = dynamic_cast<Geant4Calorimeter::Hit*>(h);
0205 if ( 0 != cal_hit )
0206 dep = cal_hit->energyDeposit;
0207 else
0208 continue;
0209 }
0210 if ( dep > 0 ) {
0211 e.second.first += dep;
0212 e.second.second.push_back(dep);
0213 }
0214 }
0215 }
0216 }
0217 }
0218 m_outTree->Fill();
0219 return;
0220 }
0221 warning("+++ [Event:%d] The value of G4HCofThisEvent is NULL.",event->GetEventID());
0222 }
0223
0224 #include "DDG4/Factories.h"
0225 DECLARE_GEANT4ACTION_NS(myanalysis,HitTupleAction)