ATLAS Offline Software
SG_StepNtuple.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "SG_StepNtuple.h"
6 
7 #include "GaudiKernel/Bootstrap.h"
8 #include "GaudiKernel/ISvcLocator.h"
9 #include "GaudiKernel/IMessageSvc.h"
10 #include "GaudiKernel/IDataProviderSvc.h"
11 #include "GaudiKernel/INTupleSvc.h"
12 #include "GaudiKernel/NTuple.h"
13 #include "GaudiKernel/SmartDataPtr.h"
14 
16 
18 
19 #include "G4Step.hh"
20 #include "G4Event.hh"
21 
22 #include <iostream>
23 
24 
25 namespace G4UA
26 {
27 
28  SG_StepNtuple::SG_StepNtuple(const std::vector<int>& pdgids)
29  : AthMessaging(Gaudi::svcLocator()->service< IMessageSvc >( "MessageSvc" ),
30  "SG_StepNtuple")
31  {
32  // Load up the PDG IDs
33  for (int i : pdgids ){
34  m_rhs.insert(i);
35  }
36  }
37 
39  {
40  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
41 
42  SmartDataPtr<NTuple::Directory>
43  ntdir(ntupleSvc(),"/NTUPLES/FILE1/StepNtuple");
44 
45  if ( !ntdir ) ntdir = ntupleSvc()->createDirectory(file1,"StepNtuple");
46  //if ( !ntdir ) log << MSG::ERROR << " failed to get ntuple directory" << endmsg;
47  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/StepNtuple/10");
48  if ( !nt ) { // Check if already booked
49  nt = ntupleSvc()->book (ntdir.ptr(), 10,CLID_ColumnWiseTuple, "GEANT4 Step NTuple");
50  if ( nt ) {
51 
52  ATH_MSG_INFO("booked step ntuple ");
53 
54  if( nt->addItem ("nstep", m_nsteps,0 ,50000)!=StatusCode::SUCCESS // WARNING!! Force limit to 50k tracks
55  || nt->addItem ("pdg", m_nsteps, m_pdg)!=StatusCode::SUCCESS
56  || nt->addItem ("charge", m_nsteps, m_charge)!=StatusCode::SUCCESS
57  || nt->addItem ("mass", m_nsteps, m_mass)!=StatusCode::SUCCESS
58  || nt->addItem ("baryon", m_nsteps, m_baryon)!=StatusCode::SUCCESS
59  || nt->addItem ("x1", m_nsteps, m_x1)!=StatusCode::SUCCESS
60  || nt->addItem ("y1", m_nsteps, m_y1)!=StatusCode::SUCCESS
61  || nt->addItem ("z1", m_nsteps, m_z1)!=StatusCode::SUCCESS
62  || nt->addItem ("t1", m_nsteps, m_t1)!=StatusCode::SUCCESS
63  || nt->addItem ("x2", m_nsteps, m_x2)!=StatusCode::SUCCESS
64  || nt->addItem ("y2", m_nsteps, m_y2)!=StatusCode::SUCCESS
65  || nt->addItem ("z2", m_nsteps, m_z2)!=StatusCode::SUCCESS
66  || nt->addItem ("t2", m_nsteps, m_t2)!=StatusCode::SUCCESS
67  || nt->addItem ("dep", m_nsteps, m_dep)!=StatusCode::SUCCESS
68  || nt->addItem ("ke1", m_nsteps, m_ke1)!=StatusCode::SUCCESS
69  || nt->addItem ("ke2", m_nsteps, m_ke2)!=StatusCode::SUCCESS
70  || nt->addItem ("rh", m_nsteps, m_rh)!=StatusCode::SUCCESS
71  || nt->addItem ("rhid", m_nsteps, m_rhid)!=StatusCode::SUCCESS
72  || nt->addItem ("step", m_nsteps, m_step)!=StatusCode::SUCCESS
73  || nt->addItem ("pt1", m_nsteps, m_pt1)!=StatusCode::SUCCESS
74  || nt->addItem ("pt2", m_nsteps, m_pt2)!=StatusCode::SUCCESS
75  || nt->addItem ("minA",m_nsteps, m_minA)!=StatusCode::SUCCESS
76  || nt->addItem ("v2",m_nsteps, m_v2)!=StatusCode::SUCCESS
77  || nt->addItem ("vthresh",m_nsteps, m_vthresh)!=StatusCode::SUCCESS
78  || nt->addItem ("vbelowthresh",m_nsteps, m_vbelowthresh)!=StatusCode::SUCCESS
79  || nt->addItem ("evtid", m_evtid)!=StatusCode::SUCCESS)
80 
81  ATH_MSG_ERROR("Could not configure branches ");
82 
83  }
84 
85  else ATH_MSG_ERROR("Could not book step ntuple!! ");
86  }
87 
88  //set initial values
89  m_nevents=0;
90 
91  }
92 
93  void SG_StepNtuple::BeginOfEventAction(const G4Event*)
94  {
95  m_nsteps=0;
96  m_rhadronIndex=0;//the rhadron index (either the first or second rhadon, usually)
97  m_nevents++;
98  m_evtid=m_nevents;//since it gets cleared out after every fill...
99  }
100 
101  void SG_StepNtuple::EndOfEventAction(const G4Event*)
102  {
103  if(! ntupleSvc()->writeRecord("/NTUPLES/FILE1/StepNtuple/10").isSuccess()) {
104  ATH_MSG_ERROR( " failed to write record for this event" );
105  }
106 
107  //this also seems to zero out all the arrays... so beware!
108  }
109 
110  void SG_StepNtuple::UserSteppingAction(const G4Step* aStep)
111  {
112  if(m_nsteps<50000){
113  const int pdg_id = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
114  bool rhad=false;
115  if (std::find(m_rhs.begin(),m_rhs.end(),std::abs(pdg_id))!=m_rhs.end()) {
116  rhad=true;
117  }
118 
119  //
120  if (!rhad && (MC::isSquarkLH(pdg_id) ||
121  pdg_id == 1000021 || // gluino
122  MC::isRHadron(pdg_id))) {
123  ATH_MSG_DEBUG (" TruthUtils classifies "<<pdg_id<<" as an R-Hadron, gluino or LH Squark!");
124  rhad=true;
125  }
126  //
127 
128  if (rhad){
129 
130  //
131  G4Material * mat = aStep->GetTrack()->GetMaterial();
132  double minA=1500000.;
133  for (unsigned int i=0;i<mat->GetNumberOfElements();++i){
134  if (mat->GetElement(i) && minA>mat->GetElement(i)->GetN()){
135  minA=mat->GetElement(i)->GetN();
136  }
137  }
138  //
139 
140  bool firstslow = aStep->GetPostStepPoint()->GetVelocity()<0.15*std::pow(minA,-2./3.)*CLHEP::c_light;
141  //just save the first slow step for the rhadron
142  for (int i=0; i<m_nsteps; ++i){
143  if (m_rhid[i]==m_rhadronIndex && m_vbelowthresh[i]>0) firstslow=false;
144  }
145  if (firstslow || aStep->GetTrack()->GetCurrentStepNumber()<=1 || aStep->GetPostStepPoint()->GetKineticEnergy()==0.){
146 
147  //
148  if (MC::isSquarkLH(pdg_id) ||
149  pdg_id == 1000021 || // gluino
150  MC::isRHadron(pdg_id)) {
151  m_rh[m_nsteps] = 1;// TruthUtils classifies this particle as an R-Hadron, gluino or LH squark
152  }
153  else{
154  m_rh[m_nsteps] = 0;// particle only passes the RHadronPDGIDList property check
155  }
156  //
157 
158  if (aStep->GetPreStepPoint()->GetGlobalTime()==0) m_rhadronIndex++;
160 
161  m_pdg[m_nsteps]=pdg_id;
162  m_charge[m_nsteps]=aStep->GetTrack()->GetDefinition()->GetPDGCharge();
163  m_dep[m_nsteps]=aStep->GetTotalEnergyDeposit();
164  m_mass[m_nsteps]=aStep->GetTrack()->GetDefinition()->GetPDGMass();
165  m_baryon[m_nsteps]=aStep->GetTrack()->GetDefinition()->GetBaryonNumber();
166  m_t1[m_nsteps]=aStep->GetPreStepPoint()->GetGlobalTime();
167  m_t2[m_nsteps]=aStep->GetPostStepPoint()->GetGlobalTime();
168  G4ThreeVector pos1=aStep->GetPreStepPoint()->GetPosition();
169  m_x1[m_nsteps]=pos1.x();
170  m_y1[m_nsteps]=pos1.y();
171  m_z1[m_nsteps]=pos1.z();
172  G4ThreeVector pos2=aStep->GetPostStepPoint()->GetPosition();
173  m_x2[m_nsteps]=pos2.x();
174  m_y2[m_nsteps]=pos2.y();
175  m_z2[m_nsteps]=pos2.z();
176  m_ke1[m_nsteps]=aStep->GetPreStepPoint()->GetKineticEnergy();
177  m_ke2[m_nsteps]=aStep->GetPostStepPoint()->GetKineticEnergy();
178  m_pt1[m_nsteps]=aStep->GetPreStepPoint()->GetMomentum().perp();
179  m_pt2[m_nsteps]=aStep->GetPostStepPoint()->GetMomentum().perp();
180 
181  //
182  m_minA[m_nsteps]=minA;
183  m_v2[m_nsteps]=aStep->GetPostStepPoint()->GetVelocity();
184  m_vthresh[m_nsteps]=0.15*std::pow(minA,-2./3.)*CLHEP::c_light;
185  m_vbelowthresh[m_nsteps]=(firstslow?1:0);
186  //
187 
189  ++m_nsteps;
190  //std::cout<<"stepping, size is "<<m_nsteps<<std::endl;
191  } // writing the step because it stopped or is the start of the "track"
192  } //rhad true
193  else {
194 
195  //KILL the particles here, so we don't waste time in GEANT4 tracking what happens to it!
196  if (MC::isBSM(pdg_id)) { // flag SUSY/BSM particles which are skipped
197  ATH_MSG_DEBUG ("UserSteppingAction(): Killing uninteresting track with pdg_id "<<pdg_id);
198  }
199  aStep->GetTrack()->SetTrackStatus(fKillTrackAndSecondaries);
200  const G4TrackVector *tv = aStep->GetSecondary();
201  //if ((*tv).size()>0) std::cout<<" ... and its "<<(*tv).size()<<" secondaries"<<std::endl;
202  for (unsigned int i=0;i<tv->size();i++){
203  G4Track *t = (*tv)[i];
204  t->SetTrackStatus(fKillTrackAndSecondaries);
205  }
206 
207  } // not an rhad
208 
209  } //m_nsteps<50000
210  }
211 
212 } // namespace G4UA
G4UA::SG_StepNtuple::m_y1
NTuple::Array< float > m_y1
Definition: SG_StepNtuple.h:37
G4UA::SG_StepNtuple::m_evtid
NTuple::Item< long > m_evtid
Definition: SG_StepNtuple.h:35
G4UA::SG_StepNtuple::UserSteppingAction
virtual void UserSteppingAction(const G4Step *) override
Definition: SG_StepNtuple.cxx:110
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
G4UA::SG_StepNtuple::m_mass
NTuple::Array< float > m_mass
Definition: SG_StepNtuple.h:40
G4UA::SG_StepNtuple::m_x1
NTuple::Array< float > m_x1
Definition: SG_StepNtuple.h:37
G4UA
for nSW
Definition: CalibrationDefaultProcessing.h:19
isBSM
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
Definition: AtlasPID.h:591
G4UA::SG_StepNtuple::m_nevents
long m_nevents
Definition: SG_StepNtuple.h:44
G4UA::SG_StepNtuple::m_y2
NTuple::Array< float > m_y2
Definition: SG_StepNtuple.h:38
mat
GeoMaterial * mat
Definition: LArDetectorConstructionTBEC.cxx:55
G4UA::SG_StepNtuple::m_v2
NTuple::Array< float > m_v2
Definition: SG_StepNtuple.h:39
ServiceAccessor.h
G4UA::SG_StepNtuple::SG_StepNtuple
SG_StepNtuple(const std::vector< int > &)
Definition: SG_StepNtuple.cxx:28
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
G4UA::SG_StepNtuple::m_t2
NTuple::Array< float > m_t2
Definition: SG_StepNtuple.h:38
G4UA::SG_StepNtuple::EndOfEventAction
virtual void EndOfEventAction(const G4Event *) override
Definition: SG_StepNtuple.cxx:101
G4UA::SG_StepNtuple::BeginOfEventAction
virtual void BeginOfEventAction(const G4Event *) override
Definition: SG_StepNtuple.cxx:93
G4UA::SG_StepNtuple::m_nsteps
NTuple::Item< long > m_nsteps
Definition: SG_StepNtuple.h:35
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
G4UA::SG_StepNtuple::m_rhs
std::set< int > m_rhs
Definition: SG_StepNtuple.h:43
lumiFormat.i
int i
Definition: lumiFormat.py:85
G4UA::SG_StepNtuple::m_rh
NTuple::Array< int > m_rh
Definition: SG_StepNtuple.h:42
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
G4UA::SG_StepNtuple::m_ke1
NTuple::Array< float > m_ke1
Definition: SG_StepNtuple.h:41
G4UA::SG_StepNtuple::m_t1
NTuple::Array< float > m_t1
Definition: SG_StepNtuple.h:37
G4UA::SG_StepNtuple::m_z2
NTuple::Array< float > m_z2
Definition: SG_StepNtuple.h:38
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
G4UA::SG_StepNtuple::m_z1
NTuple::Array< float > m_z1
Definition: SG_StepNtuple.h:37
G4UA::SG_StepNtuple::m_baryon
NTuple::Array< int > m_baryon
Definition: SG_StepNtuple.h:36
G4UA::SG_StepNtuple::m_step
NTuple::Array< int > m_step
Definition: SG_StepNtuple.h:42
G4UA::SG_StepNtuple::m_minA
NTuple::Array< float > m_minA
Definition: SG_StepNtuple.h:39
G4UA::SG_StepNtuple::m_rhid
NTuple::Array< int > m_rhid
Definition: SG_StepNtuple.h:42
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
G4UA::SG_StepNtuple::BeginOfRunAction
virtual void BeginOfRunAction(const G4Run *) override
Definition: SG_StepNtuple.cxx:38
G4UA::SG_StepNtuple::m_charge
NTuple::Array< int > m_charge
Definition: SG_StepNtuple.h:36
G4UA::SG_StepNtuple::m_pdg
NTuple::Array< int > m_pdg
Definition: SG_StepNtuple.h:36
G4UA::SG_StepNtuple::m_dep
NTuple::Array< float > m_dep
Definition: SG_StepNtuple.h:40
G4UA::SG_StepNtuple::m_rhadronIndex
long m_rhadronIndex
Definition: SG_StepNtuple.h:45
G4UA::SG_StepNtuple::m_vbelowthresh
NTuple::Array< float > m_vbelowthresh
Definition: SG_StepNtuple.h:39
isSquarkLH
bool isSquarkLH(const T &p)
Definition: AtlasPID.h:402
isRHadron
bool isRHadron(const T &p)
Definition: AtlasPID.h:871
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
G4UA::SG_StepNtuple::m_ke2
NTuple::Array< float > m_ke2
Definition: SG_StepNtuple.h:41
beamspotnt.nt
def nt
Definition: bin/beamspotnt.py:1063
ntupleSvc
INTupleSvc * ntupleSvc()
Definition: ServiceAccessor.h:14
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
HepMCHelpers.h
G4UA::SG_StepNtuple::m_x2
NTuple::Array< float > m_x2
Definition: SG_StepNtuple.h:38
G4UA::SG_StepNtuple::m_pt1
NTuple::Array< float > m_pt1
Definition: SG_StepNtuple.h:37
SG_StepNtuple.h
G4UA::SG_StepNtuple::m_pt2
NTuple::Array< float > m_pt2
Definition: SG_StepNtuple.h:38
G4UA::SG_StepNtuple::m_vthresh
NTuple::Array< float > m_vthresh
Definition: SG_StepNtuple.h:39