Belle II Software development
V0findingPerformanceEvaluationModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <tracking/modules/trackingPerformanceEvaluation/V0findingPerformanceEvaluationModule.h>
10
11#include <tracking/dataobjects/MCParticleInfo.h>
12
13#include <framework/datastore/StoreArray.h>
14#include <framework/datastore/RelationVector.h>
15
16#include <mdst/dataobjects/Track.h>
17
18#include <framework/gearbox/Const.h>
19
20#include <framework/geometry/BFieldManager.h>
21
22#include <root/TAxis.h>
23#include <root/TObject.h>
24
25#include <vector>
26
27using namespace Belle2;
28
29//-----------------------------------------------------------------
30// Register the Module
31//-----------------------------------------------------------------
32REG_MODULE(V0findingPerformanceEvaluation);
33
35 Module()
36{
37
38 setDescription("This module evaluates the V0 finding package performance");
39
40 addParam("outputFileName", m_rootFileName, "Name of output root file.",
41 std::string("V0findingPerformanceEvaluation_output.root"));
42 addParam("V0sName", m_V0sName, "Name of V0 collection.", std::string("V0ValidationVertexs"));
43 addParam("MCParticlesName", m_MCParticlesName, "Name of MC Particle collection.", std::string(""));
44
45}
46
51
53{
56
57 //create list of histograms to be saved in the rootfile
58 m_histoList = new TList;
59 m_histoList_multiplicity = new TList;
60 m_histoList_efficiency = new TList;
61 m_histoList_purity = new TList;
62 m_histoList_trkQuality = new TList;
63
64 //set the ROOT File
65 m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
66
67 //now create histograms
68
69 //multiplicity histograms
70 m_multiplicityV0s = createHistogram1D("h1nV0", "number of V0s per MC Particle", 8, -0.5, 7.5, "# V0s", m_histoList_multiplicity);
71
72 m_multiplicityMCParticles = createHistogram1D("h1nMCPrtcl", "number of MCParticles per V0s", 5, -0.5, 4.5,
73 "# MCParticles", m_histoList_multiplicity);
74
75 m_MCParticlePDGcode = createHistogram1D("h1PDGcode", "PDG code of MCParticles", 6244, Const::antiLambda.getPDGCode(),
76 Const::Lambda.getPDGCode(),
77 "PDG code", m_histoList_multiplicity);
78
79
80 //vertex and momentum parameters errors
81 m_h1_vtxX_err = createHistogram1D("h1vtxXerr", "vtxX error", 100, 0, 0.1, "#sigma_{vtxX} (cm)", m_histoList);
82 m_h1_vtxY_err = createHistogram1D("h1vtxYerr", "vtxY error", 100, 0, 0.1, "#sigma_{vtxY} (cm)", m_histoList);
83 m_h1_vtxZ_err = createHistogram1D("h1vtxZerr", "vtxZ error", 100, 0, 0.3, "#sigma_{vtxZ} (cm)", m_histoList);
84 m_h2_vtxTvsR_err = createHistogram2D("h2vtxTerrVsR", "vtxT error vs R", 100, 0, 100, "R (cm)", 100, 0, 0.3, "#sigma_{vtxT} (cm)",
86 // m_h1_mom_err = createHistogram1D("h1momerr", "mom error", 100, 0, 0.1, "#sigma_{p} (GeV/c)", m_histoList);
87 // m_h1_mass_err = createHistogram1D("h1masserr", "mass error", 100, 0, 1, "#sigma_{m} (GeV/c2)", m_histoList);
88 //vertex and momentum parameters residuals
89 m_h1_vtxX_res = createHistogram1D("h1vtxXres", "vtxX resid", 100, -0.2, 0.2, "vtxX resid (cm)", m_histoList);
90 m_h1_vtxY_res = createHistogram1D("h1vtxYres", "vtxY resid", 100, -0.2, 0.2, "vtxY resid (cm)", m_histoList);
91 m_h1_vtxZ_res = createHistogram1D("h1vtxZres", "vtxZ resid", 100, -0.5, 0.5, "vtxZ resid (cm)", m_histoList);
92 m_h1_mom_res = createHistogram1D("h1momres", "mom resid", 1000, -0.5, 0.5, "mom resid (GeV/c)", m_histoList);
93 m_h1_mass_res = createHistogram1D("h1massres", "mass resid", 500, -0.3, 0.3, "mass resid (GeV/c)", m_histoList);
94
95 //vertex and momentum parameters pulls
96 m_h1_vtxX_pll = createHistogram1D("h1vtxXpll", "vtxX pull", 100, -5, 5, "vtxX pull", m_histoList);
97 m_h1_vtxY_pll = createHistogram1D("h1vtxYpll", "vtxY pull", 100, -5, 5, "vtxY pull", m_histoList);
98 m_h1_vtxZ_pll = createHistogram1D("h1vtxZpll", "vtxZ pull", 100, -5, 5, "vtxZ pull", m_histoList);
99 // m_h1_mom_pll = createHistogram1D("h1mompll", "mom pull", 100, -5, 5, "momX pull", m_histoList);
100 // m_h1_mass_pll = createHistogram1D("h1masspll", "mass pull", 100, -5, 5, "momY pull", m_histoList);
101
102
103 m_h1_ChiSquare = createHistogram1D("h1Chi2", "Chi2 of the fit", 100, 0, 20, "Chi2", m_histoList_trkQuality);
104
105 m_h1_nMatchedDau = createHistogram1D("h1nMatchedDau", "Number of Matched MCParticle Daughters", 3, -0.5, 2.5, "# matched dau",
107
108
109 m_h2_mom = createHistogram2D("h2mom", "reco VS true momentum", 100, 0, 3, "V0 mom (GeV/c)", 100, 0, 3, "MC mom (GeV/c)",
111 m_h2_mass = createHistogram2D("h2mass", "reco VS true mass", 100, 0, 1.5, "V0 mass (GeV/c2)", 100, 0, 1.5, "MC mass (GeV/c)",
113
114 //histograms to produce efficiency plots
115 Double_t bins_pt[9 + 1] = {0, 0.05, 0.1, 0.15, 0.2, 0.3, 0.5, 1, 2, 3.5}; //GeV/c
116 Double_t bins_theta[10 + 1] = {0, 0.25, 0.5, 0.75, 0.75 + 0.32, 0.75 + 2 * 0.32, 0.75 + 3 * 0.32, 0.75 + 4 * 0.32, 0.75 + 5 * 0.32, 2.65, M_PI};
117 Double_t bins_phi[14 + 1];
118 Double_t width_phi = 2 * M_PI / 14;
119 for (int bin = 0; bin < 14 + 1; bin++)
120 bins_phi[bin] = - M_PI + bin * width_phi;
121
122 m_h1_MCParticle_R = createHistogram1D("h1nMCParticleVSr", "entry per MCParticles", 50, 0, 20, "transverse L", m_histoList);
123
124 m_h1_V0sPerMCParticle_R = dynamic_cast<TH1F*>(duplicateHistogram("h1nV0perMCvsR", "entry per V0 related to a MCParticle",
126 m_histoList));
127
128
129 m_h3_MCParticle = createHistogram3D("h3MCParticle", "entry per MCParticle",
130 9, bins_pt, "p_{t} (GeV/c)",
131 10, bins_theta, "#theta",
132 14, bins_phi, "#phi" /*, m_histoList*/);
133
134 m_h3_V0sPerMCParticle = dynamic_cast<TH3F*>(duplicateHistogram("h3V0sPerMCParticle",
135 "entry per V0 connected to a MCParticle",
136 m_h3_MCParticle /*, m_histoList*/));
137
138 m_h3_V0s = dynamic_cast<TH3F*>(duplicateHistogram("h3V0s", "entry per V0",
139 m_h3_MCParticle /*, m_histoList*/));
140
141 //histograms to produce purity plots
142 m_h3_MCParticlesPerV0 = dynamic_cast<TH3F*>(duplicateHistogram("h3MCParticlesPerV0",
143 "entry per MCParticle connected to a V0",
144 m_h3_MCParticle /*, m_histoList*/));
145}
146
151
153{
154
155 ROOT::Math::XYZVector magField = BFieldManager::getField(0, 0, 0) / Unit::T;
156
157 B2DEBUG(29, "+++++ 1. loop on MCParticles");
158 for (const MCParticle& mcParticle : m_MCParticles) {
159
160 if (! isV0(mcParticle))
161 continue;
162
163 int nMatchedDau = nMatchedDaughters(mcParticle);
164 m_h1_nMatchedDau->Fill(nMatchedDau);
165
166 //proceed only in case the MCParticle daughters have both one associated reconstructed track:
167 if (nMatchedDau != 2)
168 continue;
169
170 // cppcheck-suppress variableScope ; declaration kept at this scope for readability
171 int pdgCode = mcParticle.getPDG();
172 B2DEBUG(29, "MCParticle has PDG code " << pdgCode);
173 m_MCParticlePDGcode->Fill(mcParticle.getPDG());
174
175 MCParticleInfo mcParticleInfo(mcParticle, magField);
176
177 ROOT::Math::XYZVector MC_prodvtx = mcParticle.getVertex();
178 ROOT::Math::XYZVector MC_vtx = mcParticle.getDecayVertex();
179 float MC_mom = mcParticle.getMomentum().R();
180 float MC_mass = mcParticle.getMass();
181 ROOT::Math::XYZVector MC_FL = MC_vtx - MC_prodvtx;
182 float flightR = sqrt(MC_FL.X() * MC_FL.X() + MC_FL.Y() * MC_FL.Y());
183 m_h1_MCParticle_R->Fill(flightR);
184
185 m_h3_MCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
186
187 //1. retrieve all the V0s related to the MCParticle
188
189 //1.0 check if there is a V0
190 RelationVector<V0ValidationVertex> V0s_toMCParticle =
192
193 m_multiplicityV0s->Fill(V0s_toMCParticle.size());
194
195 if (V0s_toMCParticle.size() > 0)
196 m_h3_V0sPerMCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
197
198 for (int v0 = 0; v0 < (int)V0s_toMCParticle.size(); v0++) {
199
200 ROOT::Math::XYZVector V0_vtx = V0s_toMCParticle[v0]->getVertexPosition();
201 float V0_mom = V0s_toMCParticle[v0]->getFittedMomentum();
202 float V0_chi2 = V0s_toMCParticle[v0]->getVertexChi2();
203 float V0_mass = V0s_toMCParticle[v0]->getFittedInvariantMass();
204 TMatrixDSym V0_cov = V0s_toMCParticle[v0]->getVertexPositionCovariance();
205
206 m_h1_vtxX_err->Fill(sqrt(V0_cov[0][0]));
207 m_h1_vtxY_err->Fill(sqrt(V0_cov[1][1]));
208 m_h1_vtxZ_err->Fill(sqrt(V0_cov[2][2]));
209 m_h2_vtxTvsR_err->Fill(flightR, sqrt(V0_cov[0][0] + V0_cov[1][1]));
210
211 m_h1_V0sPerMCParticle_R->Fill(flightR);
212
213 m_h1_vtxX_res->Fill(V0_vtx.X() - MC_vtx.X());
214 m_h1_vtxY_res->Fill(V0_vtx.Y() - MC_vtx.Y());
215 m_h1_vtxZ_res->Fill(V0_vtx.Z() - MC_vtx.Z());
216
217 m_h1_mom_res->Fill(V0_mom - MC_mom);
218 m_h2_mom->Fill(V0_mom, MC_mom);
219 m_h1_mass_res->Fill(V0_mass - MC_mass);
220 m_h2_mass->Fill(V0_mass, MC_mass);
221
222 m_h1_vtxX_pll->Fill((V0_vtx.X() - MC_vtx.X()) / sqrt(V0_cov[0][0]));
223 m_h1_vtxY_pll->Fill((V0_vtx.Y() - MC_vtx.Y()) / sqrt(V0_cov[1][1]));
224 m_h1_vtxZ_pll->Fill((V0_vtx.Z() - MC_vtx.Z()) / sqrt(V0_cov[2][2]));
225
226 m_h1_ChiSquare->Fill(V0_chi2);
227
228 }
229
230
231 }
232
233
234 B2DEBUG(29, "+++++ 2. loop on V0s");
235
237
238 int nMCParticles = 0;
239
240 // m_h3_V0s>Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
241 //2. retrieve all the MCParticles related to the V0s
242 RelationVector<MCParticle> MCParticles_fromV0 =
244
245 nMCParticles = MCParticles_fromV0.size();
246
247 if (nMCParticles == 0)
248 continue;
249
250 MCParticleInfo mcParticleInfo(* MCParticles_fromV0[0], magField);
251 m_h3_MCParticlesPerV0->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
252 m_multiplicityMCParticles->Fill(nMCParticles);
253
254 }
255
256}
257
259{
260
261 double num = 0;
262 double den = 0;
263
264 for (int bin = 1; bin < m_multiplicityV0s->GetNbinsX(); bin ++)
265 num += m_multiplicityV0s->GetBinContent(bin + 1);
266 den = m_multiplicityV0s->GetEntries();
267 double efficiency = num / den ;
268 double efficiencyErr = sqrt(efficiency * (1 - efficiency)) / sqrt(den);
269
270 double nMCParticles = 0;
271 for (int bin = 1; bin < m_multiplicityMCParticles->GetNbinsX(); bin ++)
272 nMCParticles += m_multiplicityMCParticles->GetBinContent(bin + 1);
273 double purity = nMCParticles / m_multiplicityMCParticles->GetEntries();
274 double purityErr = sqrt(purity * (1 - purity)) / sqrt(m_multiplicityMCParticles->GetEntries());
275
276 B2INFO("");
277 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
278 B2INFO("~ V0 Finding Performance Evaluation ~ SHORT SUMMARY ~");
279 B2INFO("");
280 B2INFO(" + overall:");
281 B2INFO(" efficiency = (" << efficiency * 100 << " +/- " << efficiencyErr * 100 << ")% ");
282 B2INFO(" purity = (" << purity * 100 << " +/- " << purityErr * 100 << ")% ");
283 B2INFO("");
284 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
285}
286
288{
289
290 TH1F* h_eff_R = dynamic_cast<TH1F*>(duplicateHistogram("h_eff_R", "efficiency vs R", m_h1_MCParticle_R, m_histoList_efficiency));
291
292 for (int bin = 0; bin < h_eff_R->GetXaxis()->GetNbins(); bin++) {
293 float num = m_h1_V0sPerMCParticle_R->GetBinContent(bin + 1);
294 float den = m_h1_MCParticle_R->GetBinContent(bin + 1);
295 double eff = 0;
296 double err = 0;
297
298 if (den > 0) {
299 eff = (double)num / den;
300 err = sqrt(eff * (1 - eff)) / sqrt(den);
301 }
302
303 h_eff_R->SetBinContent(bin + 1, eff);
304 h_eff_R->SetBinError(bin + 1, err);
305 }
306
308
310
311 // addPurityPlots(m_histoList_purity, m_h3_MCParticlesPerV0, m_h3_V0s);
312
313 if (m_rootFilePtr != nullptr) {
314 m_rootFilePtr->cd();
315
316 TDirectory* oldDir = gDirectory;
317
318 TDirectory* dir_multiplicity = oldDir->mkdir("multiplicity");
319 dir_multiplicity->cd();
320 TIter nextH_multiplicity(m_histoList_multiplicity);
321 TObject* obj;
322 while ((obj = nextH_multiplicity()))
323 obj->Write();
324
325 TDirectory* dir_efficiency = oldDir->mkdir("efficiency");
326 dir_efficiency->cd();
327 TIter nextH_efficiency(m_histoList_efficiency);
328 while ((obj = nextH_efficiency()))
329 obj->Write();
330
331 TDirectory* dir_purity = oldDir->mkdir("purity");
332 dir_purity->cd();
333 TIter nextH_purity(m_histoList_purity);
334 while ((obj = nextH_purity()))
335 obj->Write();
336
337 TDirectory* dir_trkQuality = oldDir->mkdir("trkQuality");
338 dir_trkQuality->cd();
339 TIter nextH_trkQuality(m_histoList_trkQuality);
340 while ((obj = nextH_trkQuality()))
341 obj->Write();
342
343 TIter nextH(m_histoList);
344 while ((obj = nextH()))
345 obj->Write();
346
347
348 m_rootFilePtr->Close();
349 }
350
351}
352
353
355{
356
357 bool isGamma = false;
358 if (abs(the_mcParticle.getPDG()) == Const::photon.getPDGCode())
359 isGamma = true;
360
361 bool isK_S0 = false;
362 if (abs(the_mcParticle.getPDG()) == Const::Kshort.getPDGCode())
363 isK_S0 = true;
364
365 bool isK_0 = false;
366 if (abs(the_mcParticle.getPDG()) == 311)
367 isK_0 = true;
368
369 bool isLambda = false;
370 if (abs(the_mcParticle.getPDG()) == Const::Lambda.getPDGCode())
371 isLambda = true;
372
373 bool twoProngs = false;
374 bool twoChargedProngs = false;
375
376 if (the_mcParticle.getDaughters().size() == 2)
377 twoProngs = true;
378
379 if (twoProngs)
380 if (the_mcParticle.getDaughters()[0]->getCharge() * the_mcParticle.getDaughters()[1]->getCharge() < 0)
381 twoChargedProngs = true;
382
383 return ((isGamma || isK_S0 || isK_0 || isLambda) && twoChargedProngs);
384
385}
386
388{
389
390 int nMatchedDau = 0;
391
392 std::vector< MCParticle* > MCPart_dau = the_mcParticle.getDaughters();
393
394 bool first = false;
395 bool second = false;
396
397 RelationVector<Track> Tracks_fromMCParticle_0 = DataStore::getRelationsWithObj<Track>(MCPart_dau[0]);
398 if (Tracks_fromMCParticle_0.size() > 0)
399 first = true;
400
401 RelationVector<Track> Tracks_fromMCParticle_1 = DataStore::getRelationsWithObj<Track>(MCPart_dau[1]);
402 if (Tracks_fromMCParticle_1.size() > 0)
403 second = true;
404
405
406 if (first)
407 nMatchedDau++;
408
409 if (second)
410 nMatchedDau++;
411
412
413 return nMatchedDau;
414
415}
static const ParticleType Lambda
Lambda particle.
Definition Const.h:680
static const ParticleType antiLambda
Anti-Lambda particle.
Definition Const.h:681
static const ParticleType Kshort
K^0_S particle.
Definition Const.h:678
static const ParticleType photon
photon particle
Definition Const.h:674
static RelationVector< T > getRelationsWithObj(const TObject *object, const std::string &name="", const std::string &namedRelation="")
Get the relations between an object and other objects in a store array.
Definition DataStore.h:412
This struct is used by the TrackingPerformanceEvaluation Module to save information of reconstructed ...
double getPt()
Getter for transverse momentum.
double getPtheta()
Getter for theta of momentum vector.
double getPphi()
Getter for phi of momentum vector.
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition MCParticle.cc:50
int getPDG() const
Return PDG code of particle.
Definition MCParticle.h:101
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
TH1F * createHistogram1D(const char *name, const char *title, Int_t nbins, Double_t min, Double_t max, const char *xtitle, TList *histoList=nullptr)
Create a 1D histogram and add it to the TList of 1D-histograms.
TH1 * duplicateHistogram(const char *newname, const char *newtitle, TH1 *h, TList *histoList=nullptr)
Make a copy of a 1D histogram and add it to the TList of 1D-histograms.
void addInefficiencyPlots(TList *graphList=nullptr, TH3F *h3_xPerMCParticle=nullptr, TH3F *h3_MCParticle=nullptr)
Create pt-, theta- and phi-inefficiency 1D histograms and add them to the TList of 1D-histograms.
TList * m_histoList_trkQuality
List of track-quality histograms.
TList * m_histoList_purity
List of purity histograms.
TList * m_histoList
List of performance-evaluation histograms.
TList * m_histoList_multiplicity
List of multiplicity histograms.
void addEfficiencyPlots(TList *graphList=nullptr, TH3F *h3_xPerMCParticle=nullptr, TH3F *h3_MCParticle=nullptr)
Create pt-, theta- and phi-efficiency 1D histograms and add them to the TList of 1D-histograms.
TH3F * createHistogram3D(const char *name, const char *title, Int_t nbinsX, Double_t minX, Double_t maxX, const char *titleX, Int_t nbinsY, Double_t minY, Double_t maxY, const char *titleY, Int_t nbinsZ, Double_t minZ, Double_t maxZ, const char *titleZ, TList *histoList=nullptr)
Create a 3D histogram and add it to the TList of 3D-histograms.
TH2F * createHistogram2D(const char *name, const char *title, Int_t nbinsX, Double_t minX, Double_t maxX, const char *titleX, Int_t nbinsY, Double_t minY, Double_t maxY, const char *titleY, TList *histoList=nullptr)
Create a 2D histogram and add it to the TList of 2D-histograms.
TFile * m_rootFilePtr
pointer at root file used for storing histograms
TList * m_histoList_efficiency
List of efficiency histograms.
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
static const double T
[tesla]
Definition Unit.h:120
Class which stores some additional information on V0 vertices.
static bool isV0(const MCParticle &the_mcParticle)
is V0
TH2F * m_h2_vtxTvsR_err
vtx error on transverse plane VS transverse flight length
void event() override
This method is called for each event.
void endRun() override
This method is called if the current run ends.
void terminate() override
This method is called at the end of the event processing.
static int nMatchedDaughters(const MCParticle &the_mcParticle)
number of truth matched dauhters
void beginRun() override
Called when entering a new run.
StoreArray< V0ValidationVertex > m_V0ValidationVertices
V0ValidationVertices StoreArray.
TH1F * m_multiplicityMCParticles
number of MCParticles per fitted Track
StoreArray< MCParticle > m_MCParticles
MCParticles StoreArray.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Abstract base class for different kinds of events.