Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /DD4hep/examples/DDG4/src/HitTupleAction.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DD4HEP_DDG4_HITTUPLEACTION_H
0014 #define DD4HEP_DDG4_HITTUPLEACTION_H
0015 
0016 // Framework include files
0017 #include "DDG4/Geant4EventAction.h"
0018 
0019 // Forward declarations
0020 class G4VHitsCollection;
0021 class TFile;
0022 class TTree;
0023 class TBranch;
0024 
0025 /// Namespace example name of the user
0026 namespace myanalysis {
0027 
0028   // Forward declarations
0029   class Geant4ParticleMap;
0030     
0031   /// Class to measure the energy of escaping tracks
0032   /** Class to measure the energy of escaping tracks of a detector using Geant 4
0033    * Measure escaping energy....
0034    *
0035    *  \author  M.Frank
0036    *  \version 1.0
0037    *  \ingroup DD4HEP_SIMULATION
0038    */
0039   class HitTupleAction : public dd4hep::sim::Geant4EventAction {
0040   public:
0041     typedef std::vector<std::string> CollectionNames;
0042     /// Property: collection names to be dumped 
0043     CollectionNames m_containers;
0044     /// Property: Output file name
0045     std::string     m_outFileName;
0046     /// ROOT TFile instance
0047     TFile*          m_outFile = 0;
0048     /// Tree object within the file
0049     TTree*          m_outTree = 0;
0050     /// We want to write a separate branch for all deposits of one container(sub-detector)
0051     typedef std::pair<double, std::vector<double> > Data;
0052     /// The intermediate storage of the hit deposits to be written to ROOT
0053     std::map<std::string, std::pair<TBranch*, Data> > m_deposits;
0054     
0055   public:
0056     /// Standard constructor
0057     HitTupleAction(dd4hep::sim::Geant4Context* context, const std::string& nam);
0058     /// Default destructor
0059     virtual ~HitTupleAction();
0060     /// Begin-of-run callback: Open output file
0061     void beginRun(const G4Run* run);
0062     /// End-of-run callback: Close output file
0063     void endRun(const G4Run* run);
0064     /// Geant4EventAction interface: Begin-of-event callback
0065     virtual void begin(const G4Event* event)  override;
0066     /// Geant4EventAction interface: End-of-event callback
0067     virtual void end(const G4Event* event)  override;
0068   };
0069 }      // End namespace dd4hep
0070 #endif /* DD4HEP_DDG4_HITTUPLEACTION_H */
0071 
0072 //====================================================================
0073 //  AIDA Detector description implementation 
0074 //--------------------------------------------------------------------
0075 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0076 // All rights reserved.
0077 //
0078 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0079 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0080 //
0081 // Author     : M.Frank
0082 //
0083 //====================================================================
0084 
0085 // Framework include files
0086 #include "DDG4/Geant4DataDump.h"
0087 #include "DDG4/Geant4RunAction.h"
0088 #include "DDG4/Geant4HitCollection.h"
0089 
0090 // Geant 4 includes
0091 #include "G4HCofThisEvent.hh"
0092 #include "G4Event.hh"
0093 
0094 // ROOT include files
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 /// Standard constructor
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 /// Default destructor
0118 myanalysis::HitTupleAction::~HitTupleAction() {
0119 }
0120 
0121 /// Begin-of-run callback: Open output file
0122 void myanalysis::HitTupleAction::beginRun(const G4Run* /* run */)   {
0123 }
0124 
0125 /// End-of-run callback: Close output file
0126 void myanalysis::HitTupleAction::endRun(const G4Run* /* run */)    {
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 /// Geant4EventAction interface: Begin-of-event callback
0139 void myanalysis::HitTupleAction::begin(const G4Event* /* event */)   {
0140 }
0141 
0142 /// Geant4EventAction interface: End-of-event callback
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       //                      Name                   Option      Title
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         // Seperate loop. We need fixed addresses when creating the branches
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           e.first = m_outTree->Branch(c.c_str(), &e.second);
0171           e.first->SetAutoDelete(false);
0172           printout(ALWAYS,"HitTupleAction","+++ Prepare hit branch %s in root file.",c.c_str());
0173         }
0174       }
0175       else   {
0176         except("HitTupleAction","Failed to open ROOT N-tuple file: %s",m_outFileName.c_str());
0177       }
0178     }
0179     for ( auto& e : m_deposits )  {
0180       e.second.first->SetAddress(0);
0181     }
0182     for (int i = 0; i < nCol; ++i) {
0183       G4VHitsCollection* hc = hce->GetHC(i);
0184       const string& nam = hc->GetName();
0185       if ( find(m_containers.begin(),m_containers.end(),nam) != m_containers.end() )   {
0186         Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(hc);
0187         if ( coll )    {
0188           std::pair<TBranch*, Data>& e = m_deposits[nam];
0189           size_t nhits = coll->GetSize();
0190           Data& d = e.second;
0191           d.first = 0e0;
0192           d.second.clear();
0193 
0194           for ( size_t j=0; j<nhits; ++j )   {
0195             double dep = 0e0;
0196             Geant4HitData* h = coll->hit(j);
0197             Geant4Tracker::Hit* trk_hit = dynamic_cast<Geant4Tracker::Hit*>(h);
0198             if ( 0 != trk_hit )   {
0199               dep = trk_hit->truth.deposit;
0200             }
0201             else  {
0202               Geant4Calorimeter::Hit* cal_hit = dynamic_cast<Geant4Calorimeter::Hit*>(h);
0203               if ( 0 != cal_hit )
0204                 dep = cal_hit->energyDeposit;
0205               else
0206                 continue;
0207             }
0208             if ( dep > 0 )  {
0209               d.first += dep;
0210               d.second.push_back(dep);
0211             }
0212           }
0213         }
0214       }
0215     }
0216     m_outTree->Fill();
0217     return;
0218   }
0219   warning("+++ [Event:%d] The value of G4HCofThisEvent is NULL.",event->GetEventID());
0220 }
0221 
0222 #include "DDG4/Factories.h"
0223 DECLARE_GEANT4ACTION_NS(myanalysis,HitTupleAction)