ATLAS Offline Software
Loading...
Searching...
No Matches
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
25namespace 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
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
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
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
ATLAS-specific HepMC functions.
INTupleSvc * ntupleSvc()
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
NTuple::Array< float > m_x1
NTuple::Array< float > m_y2
NTuple::Item< long > m_nsteps
NTuple::Array< float > m_pt1
NTuple::Array< float > m_t1
NTuple::Array< float > m_v2
virtual void UserSteppingAction(const G4Step *) override
NTuple::Array< int > m_baryon
virtual void BeginOfEventAction(const G4Event *) override
NTuple::Array< float > m_ke2
NTuple::Array< float > m_dep
NTuple::Array< float > m_z2
NTuple::Item< long > m_evtid
NTuple::Array< int > m_step
NTuple::Array< float > m_ke1
NTuple::Array< float > m_vthresh
NTuple::Array< float > m_x2
NTuple::Array< float > m_mass
NTuple::Array< float > m_minA
NTuple::Array< float > m_t2
SG_StepNtuple(const std::vector< int > &)
NTuple::Array< float > m_vbelowthresh
virtual void EndOfEventAction(const G4Event *) override
NTuple::Array< int > m_rhid
NTuple::Array< float > m_z1
NTuple::Array< float > m_y1
std::set< int > m_rhs
NTuple::Array< int > m_rh
NTuple::Array< float > m_pt2
NTuple::Array< int > m_pdg
NTuple::Array< int > m_charge
virtual void BeginOfRunAction(const G4Run *) override
=============================================================================
bool isSquarkLH(const T &p)
bool isRHadron(const T &p)
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.