ATLAS Offline Software
Loading...
Searching...
No Matches
TruthTestTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TruthTestTool.h"
6
9
11#include <TH1.h>
12#include <TH2D.h>
13
14#include <fstream>
15
16
17TruthTestTool::TruthTestTool(const std::string& type, const std::string& name, const IInterface* parent)
18 : SimTestToolBase(type, name, parent),
19 m_n_vert(0), m_n_part(0),
22 m_x_vert(0), m_y_vert(0), m_z_vert(0),
24 m_vtx_r(0), m_vtx_z(0),
29 m_origin(0),
32{
33 declareProperty("DumpMcEvent", m_mcEventDump=10);
34}
35
36
38{
39 ATH_CHECK(m_eventInfoKey.initialize());
40
41 // initialize standard TruthTestTool
42 std::string histdirname("Truth");
43 if (m_key!="TruthEvent") {
44 // initialize alternative TruthTestTool e.g. for GEN_EVENT
45 histdirname = m_key;
46 }
47 m_path+=histdirname+"/";
48
49 _TH1D(m_n_vert,"N_vert_all",50,0.,1000.);
50 _SET_TITLE(m_n_vert,"total number of verticies","n","dN/dn");
51 m_n_vert -> StatOverflows();
52 _TH1D(m_n_part,"N_part_all",50,0.,5000.);
53 _SET_TITLE(m_n_part,"total number of particles","n","dN/dn");
54 m_n_part -> StatOverflows();
55
56 _TH1D(m_n_vert_prim,"N_vert_prim",25,0.,750.);
57 _SET_TITLE(m_n_vert_prim,"number of primary verticies","n","dN/dn");
58 m_n_vert_prim -> StatOverflows();
59 _TH1D(m_n_part_prim,"N_part_prim",25,0.,1500.);
60 _SET_TITLE(m_n_part_prim,"number of primary particles","n","dN/dn");
61 m_n_part_prim -> StatOverflows();
62 _TH1D(m_n_vert_sec,"N_vert_sec",25,0.,750.);
63 _SET_TITLE(m_n_vert_sec,"number of secondary verticies","n","dN/dn");
64 m_n_vert_sec -> StatOverflows();
65 _TH1D(m_n_part_sec,"N_part_sec",25,0.,1500.);
66 _SET_TITLE(m_n_part_sec,"number of secondary particles","n","dN/dn");
67 m_n_part_sec -> StatOverflows();
68
69 _TH1D(m_x_vert,"X_vert_gen",100,-0.5,0.5);
70 _SET_TITLE(m_x_vert,"x vertex distribution","x [mm]","dN/dx [1/mm]");
71 _TH1D(m_y_vert,"Y_vert_gen",100,0.5,1.5);
72 _SET_TITLE(m_y_vert,"y vertex distribution","y [mm]","dN/dy [1/mm]");
73 _TH1D(m_z_vert,"Z_vert_gen",100,-300.,300.);
74 _SET_TITLE(m_z_vert,"z vertex distribution","z [mm]","dN/dz [1/mm]");
75
76 _TH1D(m_n_generations,"part_generation",26,-0.5,25.5);
77 _SET_TITLE(m_n_generations,"number of particles per generation (prim,sec,...)","n","dN/dn");
78 m_n_generations -> StatOverflows();
79
80 _TH1D(m_vtx_r,"vertex_r",150,0.,4500.);
81 _SET_TITLE(m_vtx_r, "GenVertex r positions","r [mm]","dN/dr");
82 _TH1D(m_vtx_z,"vertex_z",150,-25000.,25000.);
83 _SET_TITLE(m_vtx_z, "GenVertex z positions","z [mm]", "dN/dz");
84
85 _TH2D(m_vtx_zr_indet,"vertex_zr_indet",100,-3200.,3200.,100,0.,1200.);
86 _SET_TITLE(m_vtx_zr_indet, "GenVertex zr positions","z [mm]","r [mm]");
87 _TH2D(m_vtx_xy_indet,"vertex_xy_indet",100,-1200.,1200.,100,-1200.,1200.);
88 _SET_TITLE(m_vtx_xy_indet, "GenVertex xy positions","x [mm]","y [mm]");
89
90
91 _TH1D(m_meanx_vert,"MeanX_vert_gen",100,-0.5,0.5);
92 _SET_TITLE(m_meanx_vert,"mean x vertex distribution","x [mm]","dN/dx [1/mm]");
93 _TH1D(m_meany_vert,"MeanY_vert_gen",100,0.5,1.5);
94 _SET_TITLE(m_meany_vert,"mean y vertex distribution","y [mm]","dN/dy [1/mm]");
95 _TH1D(m_meanz_vert,"MeanZ_vert_gen",100,-300.,300.);
96 _SET_TITLE(m_meanz_vert,"mean z vertex distribution","z [mm]","dN/dz [1/mm]");
97
98 // MC truth (incl. G4 particles created in the inner detector
99 _TH1D(m_pt_truth,"Pt_truth",25,0.,50000.);
100 _SET_TITLE(m_pt_truth,"pt distribution of MC truth","pt [MeV]","dN/dpt [1/MeV]");
101 _TH1D(m_log_pt_truth,"log_Pt_truth",100.,0.,16.);
102 _SET_TITLE(m_log_pt_truth,"log(pt) distribution of MC truth","log(pt [MeV])","dN/dlog(pt) [1/log(MeV)]");
103
104
105 _TH1D(m_px_truth,"PX_truth",25,-50000.,50000.);
106 _SET_TITLE(m_px_truth,"px distribution of MC truth","px [MeV]","dN/dp [1/MeV]");
107 _TH1D(m_py_truth,"PY_truth",25,-50000.,50000.);
108 _SET_TITLE(m_py_truth,"py distribution of MC truth","py [MeV]","dN/dp [1/MeV]");
109 _TH1D(m_pz_truth,"PZ_truth",25,-50000.,50000.);
110 _SET_TITLE(m_pz_truth,"pz distribution of MC truth","pz [MeV]","dN/dp [1/MeV]");
111
112 _TH1D(m_theta_truth,"theta_truth",25,0,M_PI);
113 _SET_TITLE(m_theta_truth,"theta distribution of MC truth","theta","dN/dtheta");
114 _TH1D(m_eta_truth,"eta_truth",25,-5.,5.);
115 _SET_TITLE(m_eta_truth,"eta distribution of MC truth","eta","dN/deta");
116 _TH1D(m_phi_truth,"phi_truth",25,-M_PI,M_PI);
117 _SET_TITLE(m_phi_truth,"phi distribution of MC truth","phi","dN/dphi");
118 _TH1D(m_origin,(histdirname+"_origin").c_str(),2,0.,1.);
119 _TH1D(m_particle_status,"particle_status",5,-0.5,4.5);
120 _SET_TITLE(m_particle_status,"Particle Status (1==undecayed, 2==decayed, 4==beam particle)","GenParticle Status","N GenParticles");
121 _TH1D(m_particle_type,"particle_type",15,-7.5,7.5);
122 _SET_TITLE(m_particle_type,"Type (Type 0 = PDG 22, 1=11, 2=13,15, 3=111,211, 4=130,310,311,321, 5=2122, 6=2212, 7=else)","Particle Type (negative for anti-particles)","N Particles");
123
124
125 // generator particles
126 _TH1D(m_eta_gen,"eta_gen",25,-5.,5.);
127 _SET_TITLE(m_eta_gen,"eta distribution of generator particles","eta","dN/deta");
128 _TH1D(m_phi_gen,"phi_gen",25,-M_PI,M_PI);
129 _SET_TITLE(m_phi_gen,"phi distribution of generator particles","phi","dN/dphi");
130 _TH1D(m_p_gen,"p_gen",50,0.,250000.);
131 _SET_TITLE(m_p_gen,"momentum distribution of generator particles","p","dN/dp [1/MeV]");
132 _TH1D(m_log_p_gen,"log_p_gen",50,0.,16.);
133 _SET_TITLE(m_log_p_gen,"momentum distribution of generator particles","log(p)","dN/dlog(p) [1/log(MeV)]");
134
135
136 _TH1D(m_pion_mass,"p_pion_mass",50,114.,164.);
137 _SET_TITLE(m_pion_mass,"pion mass distribution (generator particles)","m [MeV]","dN/dm [1/MeV]");
138
139 return StatusCode::SUCCESS;
140}
141
142
144{
145 SG::ReadHandle<xAOD::EventInfo> eventInfo (m_eventInfoKey,Gaudi::Hive::currentContext());
146 ATH_CHECK(eventInfo.isValid());
147
148 const int evtnum(eventInfo->eventNumber());
149
150 const McEventCollection* mcCollection;
151 if (evtStore()->retrieve(mcCollection,m_key).isSuccess()) {
152 McEventCollection::const_iterator currentGenEventIter = mcCollection->begin();
153
154 if (currentGenEventIter!=mcCollection->end() ) {
155 {
156 auto vtx = HepMC::signal_process_vertex(*currentGenEventIter);
157 if (!vtx && (*currentGenEventIter)->vertices().size()>0) vtx=((*currentGenEventIter)->vertices()).front();
158 if ( vtx )
159 {
160 m_x_vert->Fill( vtx->position().x() );
161 m_y_vert->Fill( vtx->position().y() );
162 m_z_vert->Fill( vtx->position().z() );
163 }
164 }
165
166 int nvtx=0;
167 int nvtx_sec=0;
168 float mx=0.,my=0.,mz=0.;
169 for (const auto& vtx: (*currentGenEventIter)->vertices()) {
170 double x = vtx->position().x();
171 double y = vtx->position().y();
172 double z = vtx->position().z();
173 double r = std::sqrt(x*x+y*y);
174 m_vtx_r->Fill(r);
175 m_vtx_z->Fill(z);
176 m_vtx_zr_indet->Fill(z, r);
177 m_vtx_xy_indet->Fill(x, y);
178 if ( !HepMC::is_simulation_vertex(vtx) ) {
179 mx+=x;
180 my+=y;
181 mz+=z;
182 ++nvtx;
183 }
184 else {
185 // TODO: add 2D distribution of secondary verticies (and primary ?)
186 ++nvtx_sec;
187 }
188 }
189 if (nvtx>0) {
190 m_meanx_vert->Fill( mx/nvtx );
191 m_meany_vert->Fill( my/nvtx );
192 m_meanz_vert->Fill( mz/nvtx );
193 }
194
195 m_n_vert->Fill( nvtx + nvtx_sec );
196 m_n_vert_prim->Fill( nvtx);
197 m_n_vert_sec->Fill( nvtx_sec );
198
199 }
200
201 for (;currentGenEventIter!=mcCollection->end(); ++currentGenEventIter) {
202 if (evtnum<m_mcEventDump) {
203 char fname[80];
204 sprintf(fname,"%s.event%d.txt",m_key.c_str(),evtnum);
205 std::ofstream of(fname);
206 HepMC::Print::line(of,*(*currentGenEventIter)); // verbose output
207 of.close();
208 }
209
210 int npart_prim=0, npart_sec=0;
211 for (const auto& currentGenParticle: *(*currentGenEventIter)) {
212 bool is_simulation = HepMC::is_simulation_particle(currentGenParticle);
213 const HepMC::FourVector mom = currentGenParticle->momentum();
214 m_px_truth->Fill( mom.x() );
215 m_py_truth->Fill( mom.y() );
216 m_pz_truth->Fill( mom.z() );
217 m_pt_truth->Fill( mom.perp() );
218 m_log_pt_truth->Fill( mom.perp() > 0 ? log(mom.perp()) : -1 );
219
220 m_theta_truth->Fill( mom.theta() );
221 m_eta_truth->Fill( mom.eta() );
222 m_phi_truth->Fill( mom.phi() );
223
224 if(std::abs(currentGenParticle->pdg_id())==211) {
225 m_pion_mass->Fill(mom.m());
226 }
227 m_origin->Fill(is_simulation?1:0);
228
229 m_particle_status->Fill(currentGenParticle->status());
230
231 int pdg = currentGenParticle->pdg_id();
232 int particleType = 100;
233 switch ( abs(pdg) ) {
234 case 22:
235 particleType = 0;
236 break;
237 case 11:
238 particleType = 1;
239 break;
240 case 13:
241 case 15:
242 particleType = 2;
243 break;
244 case 111:
245 case 211:
246 particleType = 3;
247 break;
248 case 130:
249 case 310:
250 case 311:
251 case 321:
252 particleType = 4;
253 break;
254 case 2112:
255 particleType = 5;
256 break;
257 case 2212:
258 particleType = 6;
259 break;
260 default:
261 particleType = 7;
262 break;
263 }
266
267 if ( !is_simulation ) {
268 double momentum=std::sqrt(mom.x()*mom.x()+mom.y()*mom.y()+mom.z()*mom.z());
269 m_p_gen->Fill( momentum );
270 m_log_p_gen->Fill( std::log(momentum) );
271 m_eta_gen->Fill( mom.eta() );
272 m_phi_gen->Fill( mom.phi() );
273 ++npart_prim;
274 }
275 else {
276 ++npart_sec;
277 }
278 m_n_generations ->Fill(HepMC::generations(currentGenParticle));
279 }
280 m_n_part_prim->Fill(npart_prim);
281 m_n_part_sec->Fill(npart_sec);
282 m_n_part->Fill(npart_prim+npart_sec);
283 }
284 }
285
286 return StatusCode::SUCCESS;
287}
#define M_PI
#define ATH_CHECK
Evaluate an expression and check for errors.
#define _TH2D(var, name, nbinx, xmin, xmax, nbiny, ymin, ymax)
#define _TH1D(var, name, nbin, xmin, xmax)
#define _SET_TITLE(var, title, xaxis, yaxis)
#define y
#define x
#define z
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string m_path
std::string m_key
The MC truth key.
SimTestToolBase(const std::string &type, const std::string &name, const IInterface *parent)
TH1 * m_particle_type
virtual StatusCode initialize() override
TH1 * m_particle_status
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG key for Event Info.
TH1 * m_n_generations
TruthTestTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode processEvent() override
int r
Definition globals.cxx:22
bool is_simulation_vertex(const T &v)
Method to establish if the vertex was created during simulation (TODO migrate to be based on status).
HepMC3::FourVector FourVector
ConstGenVertexPtr signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:597
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (TODO migrate to be...