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
48{
49
50}
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 = (TH1F*)duplicateHistogram("h1nV0perMCvsR", "entry per V0 related to a MCParticle", m_h1_MCParticle_R,
126
127
128 m_h3_MCParticle = createHistogram3D("h3MCParticle", "entry per MCParticle",
129 9, bins_pt, "p_{t} (GeV/c)",
130 10, bins_theta, "#theta",
131 14, bins_phi, "#phi" /*, m_histoList*/);
132
133 m_h3_V0sPerMCParticle = (TH3F*)duplicateHistogram("h3V0sPerMCParticle",
134 "entry per V0 connected to a MCParticle",
135 m_h3_MCParticle /*, m_histoList*/);
136
137 m_h3_V0s = (TH3F*)duplicateHistogram("h3V0s", "entry per V0",
138 m_h3_MCParticle /*, m_histoList*/);
139
140 //histograms to produce purity plots
141 m_h3_MCParticlesPerV0 = (TH3F*)duplicateHistogram("h3MCParticlesPerV0",
142 "entry per MCParticle connected to a V0",
143 m_h3_MCParticle /*, m_histoList*/);
144}
145
147{
148
149}
150
152{
153
154 ROOT::Math::XYZVector magField = BFieldManager::getField(0, 0, 0) / Unit::T;
155
156 B2DEBUG(29, "+++++ 1. loop on MCParticles");
157 for (const MCParticle& mcParticle : m_MCParticles) {
158
159 if (! isV0(mcParticle))
160 continue;
161
162 int nMatchedDau = nMatchedDaughters(mcParticle);
163 m_h1_nMatchedDau->Fill(nMatchedDau);
164
165 //proceed only in case the MCParticle daughters have both one associated reconstructed track:
166 if (nMatchedDau != 2)
167 continue;
168
169 int pdgCode = mcParticle.getPDG();
170 B2DEBUG(29, "MCParticle has PDG code " << pdgCode);
171 m_MCParticlePDGcode->Fill(mcParticle.getPDG());
172
173 MCParticleInfo mcParticleInfo(mcParticle, magField);
174
175 ROOT::Math::XYZVector MC_prodvtx = mcParticle.getVertex();
176 ROOT::Math::XYZVector MC_vtx = mcParticle.getDecayVertex();
177 float MC_mom = mcParticle.getMomentum().R();
178 float MC_mass = mcParticle.getMass();
179 ROOT::Math::XYZVector MC_FL = MC_vtx - MC_prodvtx;
180 float flightR = sqrt(MC_FL.X() * MC_FL.X() + MC_FL.Y() * MC_FL.Y());
181 m_h1_MCParticle_R->Fill(flightR);
182
183 m_h3_MCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
184
185 //1. retrieve all the V0s related to the MCParticle
186
187 //1.0 check if there is a V0
188 RelationVector<V0ValidationVertex> V0s_toMCParticle =
189 DataStore::getRelationsWithObj<V0ValidationVertex>(&mcParticle, m_V0sName);
190
191 m_multiplicityV0s->Fill(V0s_toMCParticle.size());
192
193 if (V0s_toMCParticle.size() > 0)
194 m_h3_V0sPerMCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
195
196 for (int v0 = 0; v0 < (int)V0s_toMCParticle.size(); v0++) {
197
198 ROOT::Math::XYZVector V0_vtx = V0s_toMCParticle[v0]->getVertexPosition();
199 float V0_mom = V0s_toMCParticle[v0]->getFittedMomentum();
200 float V0_chi2 = V0s_toMCParticle[v0]->getVertexChi2();
201 float V0_mass = V0s_toMCParticle[v0]->getFittedInvariantMass();
202 TMatrixDSym V0_cov = V0s_toMCParticle[v0]->getVertexPositionCovariance();
203
204 m_h1_vtxX_err->Fill(sqrt(V0_cov[0][0]));
205 m_h1_vtxY_err->Fill(sqrt(V0_cov[1][1]));
206 m_h1_vtxZ_err->Fill(sqrt(V0_cov[2][2]));
207 m_h2_vtxTvsR_err->Fill(flightR, sqrt(V0_cov[0][0] + V0_cov[1][1]));
208
209 m_h1_V0sPerMCParticle_R->Fill(flightR);
210
211 m_h1_vtxX_res->Fill(V0_vtx.X() - MC_vtx.X());
212 m_h1_vtxY_res->Fill(V0_vtx.Y() - MC_vtx.Y());
213 m_h1_vtxZ_res->Fill(V0_vtx.Z() - MC_vtx.Z());
214
215 m_h1_mom_res->Fill(V0_mom - MC_mom);
216 m_h2_mom->Fill(V0_mom, MC_mom);
217 m_h1_mass_res->Fill(V0_mass - MC_mass);
218 m_h2_mass->Fill(V0_mass, MC_mass);
219
220 m_h1_vtxX_pll->Fill((V0_vtx.X() - MC_vtx.X()) / sqrt(V0_cov[0][0]));
221 m_h1_vtxY_pll->Fill((V0_vtx.Y() - MC_vtx.Y()) / sqrt(V0_cov[1][1]));
222 m_h1_vtxZ_pll->Fill((V0_vtx.Z() - MC_vtx.Z()) / sqrt(V0_cov[2][2]));
223
224 m_h1_ChiSquare->Fill(V0_chi2);
225
226 }
227
228
229 }
230
231
232 B2DEBUG(29, "+++++ 2. loop on V0s");
233
235
236 int nMCParticles = 0;
237
238 // m_h3_V0s>Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
239 //2. retrieve all the MCParticles related to the V0s
240 RelationVector<MCParticle> MCParticles_fromV0 =
241 DataStore::getRelationsWithObj<MCParticle>(&v0, m_MCParticlesName);
242
243 nMCParticles = MCParticles_fromV0.size();
244
245 if (nMCParticles == 0)
246 continue;
247
248 MCParticleInfo mcParticleInfo(* MCParticles_fromV0[0], magField);
249 m_h3_MCParticlesPerV0->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
250 m_multiplicityMCParticles->Fill(nMCParticles);
251
252 }
253
254}
255
257{
258
259 double num = 0;
260 double den = 0;
261
262 for (int bin = 1; bin < m_multiplicityV0s->GetNbinsX(); bin ++)
263 num += m_multiplicityV0s->GetBinContent(bin + 1);
264 den = m_multiplicityV0s->GetEntries();
265 double efficiency = num / den ;
266 double efficiencyErr = sqrt(efficiency * (1 - efficiency)) / sqrt(den);
267
268 double nMCParticles = 0;
269 for (int bin = 1; bin < m_multiplicityMCParticles->GetNbinsX(); bin ++)
270 nMCParticles += m_multiplicityMCParticles->GetBinContent(bin + 1);
271 double purity = nMCParticles / m_multiplicityMCParticles->GetEntries();
272 double purityErr = sqrt(purity * (1 - purity)) / sqrt(m_multiplicityMCParticles->GetEntries());
273
274 B2INFO("");
275 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
276 B2INFO("~ V0 Finding Performance Evaluation ~ SHORT SUMMARY ~");
277 B2INFO("");
278 B2INFO(" + overall:");
279 B2INFO(" efficiency = (" << efficiency * 100 << " +/- " << efficiencyErr * 100 << ")% ");
280 B2INFO(" purity = (" << purity * 100 << " +/- " << purityErr * 100 << ")% ");
281 B2INFO("");
282 B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
283}
284
286{
287
288 TH1F* h_eff_R = (TH1F*)duplicateHistogram("h_eff_R", "efficiency vs R", m_h1_MCParticle_R, m_histoList_efficiency);
289
290 for (int bin = 0; bin < h_eff_R->GetXaxis()->GetNbins(); bin++) {
291 float num = m_h1_V0sPerMCParticle_R->GetBinContent(bin + 1);
292 float den = m_h1_MCParticle_R->GetBinContent(bin + 1);
293 double eff = 0;
294 double err = 0;
295
296 if (den > 0) {
297 eff = (double)num / den;
298 err = sqrt(eff * (1 - eff)) / sqrt(den);
299 }
300
301 h_eff_R->SetBinContent(bin + 1, eff);
302 h_eff_R->SetBinError(bin + 1, err);
303 }
304
306
308
309 // addPurityPlots(m_histoList_purity, m_h3_MCParticlesPerV0, m_h3_V0s);
310
311 if (m_rootFilePtr != nullptr) {
312 m_rootFilePtr->cd();
313
314 TDirectory* oldDir = gDirectory;
315
316 TDirectory* dir_multiplicity = oldDir->mkdir("multiplicity");
317 dir_multiplicity->cd();
318 TIter nextH_multiplicity(m_histoList_multiplicity);
319 TObject* obj;
320 while ((obj = nextH_multiplicity()))
321 obj->Write();
322
323 TDirectory* dir_efficiency = oldDir->mkdir("efficiency");
324 dir_efficiency->cd();
325 TIter nextH_efficiency(m_histoList_efficiency);
326 while ((obj = nextH_efficiency()))
327 obj->Write();
328
329 TDirectory* dir_purity = oldDir->mkdir("purity");
330 dir_purity->cd();
331 TIter nextH_purity(m_histoList_purity);
332 while ((obj = nextH_purity()))
333 obj->Write();
334
335 TDirectory* dir_trkQuality = oldDir->mkdir("trkQuality");
336 dir_trkQuality->cd();
337 TIter nextH_trkQuality(m_histoList_trkQuality);
338 while ((obj = nextH_trkQuality()))
339 obj->Write();
340
341 TIter nextH(m_histoList);
342 while ((obj = nextH()))
343 obj->Write();
344
345
346 m_rootFilePtr->Close();
347 }
348
349}
350
351
353{
354
355 bool isGamma = false;
356 if (abs(the_mcParticle.getPDG()) == Const::photon.getPDGCode())
357 isGamma = true;
358
359 bool isK_S0 = false;
360 if (abs(the_mcParticle.getPDG()) == Const::Kshort.getPDGCode())
361 isK_S0 = true;
362
363 bool isK_0 = false;
364 if (abs(the_mcParticle.getPDG()) == 311)
365 isK_0 = true;
366
367 bool isLambda = false;
368 if (abs(the_mcParticle.getPDG()) == Const::Lambda.getPDGCode())
369 isLambda = true;
370
371 bool twoProngs = false;
372 bool twoChargedProngs = false;
373
374 if (the_mcParticle.getDaughters().size() == 2)
375 twoProngs = true;
376
377 if (twoProngs)
378 if (the_mcParticle.getDaughters()[0]->getCharge() * the_mcParticle.getDaughters()[1]->getCharge() < 0)
379 twoChargedProngs = true;
380
381 return ((isGamma || isK_S0 || isK_0 || isLambda) && twoChargedProngs);
382
383}
384
386{
387
388 int nMatchedDau = 0;
389
390 std::vector< MCParticle* > MCPart_dau = the_mcParticle.getDaughters();
391
392 bool first = false;
393 bool second = false;
394
395 RelationVector<Track> Tracks_fromMCParticle_0 = DataStore::getRelationsWithObj<Track>(MCPart_dau[0]);
396 if (Tracks_fromMCParticle_0.size() > 0)
397 first = true;
398
399 RelationVector<Track> Tracks_fromMCParticle_1 = DataStore::getRelationsWithObj<Track>(MCPart_dau[1]);
400 if (Tracks_fromMCParticle_1.size() > 0)
401 second = true;
402
403
404 if (first)
405 nMatchedDau++;
406
407 if (second)
408 nMatchedDau++;
409
410
411 return nMatchedDau;
412
413}
int getPDGCode() const
PDG code.
Definition: Const.h:473
static const ParticleType Lambda
Lambda particle.
Definition: Const.h:679
static const ParticleType antiLambda
Anti-Lambda particle.
Definition: Const.h:680
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:677
static const ParticleType photon
photon particle
Definition: Const.h:673
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:52
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
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.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
static const double T
[tesla]
Definition: Unit.h:120
Class which stores some additional information on V0 vertices.
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.
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
Definition: BFieldManager.h:91
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.