Belle II Software  release-06-01-15
TrackingPerformanceEvaluationModule.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/TrackingPerformanceEvaluationModule.h>
10 
11 #include <framework/datastore/StoreArray.h>
12 #include <framework/datastore/RelationVector.h>
13 
14 #include <framework/geometry/BFieldManager.h>
15 
16 #include <vxd/geometry/GeoCache.h>
17 
18 #include <mdst/dataobjects/MCParticle.h>
19 #include <mdst/dataobjects/Track.h>
20 #include <mdst/dataobjects/HitPatternCDC.h>
21 #include <mdst/dataobjects/HitPatternVXD.h>
22 
23 #include <pxd/reconstruction/PXDRecoHit.h>
24 #include <svd/reconstruction/SVDRecoHit.h>
25 #include <svd/reconstruction/SVDRecoHit2D.h>
26 #include <cdc/dataobjects/CDCRecoHit.h>
27 
28 #include <tracking/dataobjects/RecoTrack.h>
29 
30 #include <pxd/dataobjects/PXDTrueHit.h>
31 #include <pxd/dataobjects/PXDCluster.h>
32 #include <svd/dataobjects/SVDCluster.h>
33 #include <cdc/dataobjects/CDCHit.h>
34 
35 #include <genfit/KalmanFitterInfo.h>
36 
37 #include <root/TObject.h>
38 
39 #include <boost/foreach.hpp>
40 
41 using namespace Belle2;
42 
43 //-----------------------------------------------------------------
44 // Register the Module
45 //-----------------------------------------------------------------
46 REG_MODULE(TrackingPerformanceEvaluation)
47 
49  Module()
50 {
51 
52  setDescription("This module evaluates the tracking package performance");
53 
54  addParam("outputFileName", m_rootFileName, "Name of output root file.",
55  std::string("TrackingPerformanceEvaluation_output.root"));
56  addParam("MCParticlesName", m_MCParticlesName, "Name of MC Particle collection.", std::string(""));
57  addParam("TracksName", m_TracksName, "Name of Track collection.", std::string(""));
58  addParam("RecoTracksName", m_RecoTracksName, "Name of RecoTrack collection.", std::string("RecoTracks"));
59  addParam("MCRecoTracksName", m_MCRecoTracksName, "Name of MCRecoTrack collection.", std::string("MCRecoTracks"));
60  addParam("ParticleHypothesis", m_ParticleHypothesis, "Particle Hypothesis used in the track fit.", int(211));
61 
62 }
63 
65 {
66 
67 }
68 
70 {
71  // MCParticles, Tracks, RecoTracks, MCRecoTracks needed for this module
72  StoreArray<MCParticle> mcParticles;
73  mcParticles.isRequired(m_MCParticlesName);
74 
75  StoreArray<RecoTrack> recoTracks;
76  recoTracks.isRequired(m_RecoTracksName);
77 
78  StoreArray<RecoTrack> mcRecoTracks;
79  mcRecoTracks.isRequired(m_MCRecoTracksName);
80 
81  StoreArray<Track> tracks;
82  tracks.isRequired(m_TracksName);
83 
84  //create list of histograms to be saved in the rootfile
85  m_histoList = new TList;
86  m_histoList_multiplicity = new TList;
88  m_histoList_trkQuality = new TList;
89  m_histoList_firstHit = new TList;
90  m_histoList_pr = new TList;
91  m_histoList_fit = new TList;
92  m_histoList_efficiency = new TList;
93  m_histoList_purity = new TList;
94  m_histoList_others = new TList;
95 
96  //set the ROOT File
97  m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
98 
99  //now create histograms
100 
101  //multiplicity histograms
102  m_multiplicityTracks = createHistogram1D("h1nTrk", "number of tracks per MC Particle", 8, -0.5, 7.5, "# tracks",
104 
105  m_multiplicityRecoTracks = createHistogram1D("h1nRcTrk", "number of recoTracks per MC Particle", 8, -0.5, 7.5, "# tracks",
107 
108  m_multiplicityMCRecoTracks = createHistogram1D("h1nMCRcTrk", "number of MC recoTracks per MC Particle", 8, -0.5, 7.5, "# tracks",
110 
111  m_multiplicityFittedTracks = createHistogram1D("h1nFitTrk", "number of fitted tracks per MC Particle", 5, -0.5, 4.5,
112  "# fitted tracks", m_histoList_multiplicity);
113  m_multiplicityFittedTracksPerMCRT = createHistogram1D("h1nFitTrkMCRT", "number of fitted tracks per MCRecoTrack", 5, -0.5, 4.5,
114  "# fitted tracks", m_histoList_multiplicity);
115  m_multiplicityMCParticlesPerTrack = createHistogram1D("h1nMCPrtcl", "number of MCParticles per fitted tracks", 5, -0.5, 4.5,
116  "# MCParticles", m_histoList_multiplicity);
117  m_multiplicityRecoTracksPerMCRT = createHistogram1D("h1nRecoTrack", "number of RecoTrack per MCRecoTrack", 5, -0.5, 4.5,
118  "# RecoTrack",
120  m_multiplicityMCRecoTracksPerRT = createHistogram1D("h1nMCRecoTrack", "number of MCRecoTrack per RecoTrack", 5, -0.5, 4.5,
121  "# MCRecoTrack", m_histoList_multiplicity);
122 
123  //tracks pValue
124  m_h1_pValue = createHistogram1D("h1pValue", "pValue of the fit", 100, 0, 1, "pValue", m_histoList_trkQuality);
125 
126 
127  //track parameters errors
128  m_h1_d0_err = createHistogram1D("h1d0err", "d0 error", 100, 0, 0.1, "#sigma_{d0} (cm)", m_histoList_trkQuality);
129  m_h1_phi_err = createHistogram1D("h1phierr", "#phi error", 100, 0, 0.02, "#sigma_{#phi} (rad)", m_histoList_trkQuality);
130  m_h1_omega_err = createHistogram1D("h1omegaerr", "#omega error", 100, 0, 0.002, "#sigma_{#omega} (cm^{-1})",
132  m_h1_z0_err = createHistogram1D("h1z0err", "z0 error", 100, 0, 0.1, "#sigma_{z0} (cm)", m_histoList_trkQuality);
133  m_h1_cotTheta_err = createHistogram1D("h1cotThetaerr", "cot#theta error", 100, 0, 0.03, "#sigma_{cot#theta}",
135 
136  //track parameters residuals
137  m_h1_d0_res = createHistogram1D("h1d0res", "d0 residuals", 100, -0.1, 0.1, "d0 resid (cm)", m_histoList_trkQuality);
138  m_h1_phi_res = createHistogram1D("h1phires", "#phi residuals", 100, -0.1, 0.1, "#phi resid (rad)", m_histoList_trkQuality);
139  m_h1_omega_res = createHistogram1D("h1omegares", "#omega residuals", 100, -0.0005, 0.0005, "#omega resid (cm^{-1})",
141  m_h1_z0_res = createHistogram1D("h1z0res", "z0 residuals", 100, -0.1, 0.1, "z0 resid (cm)", m_histoList_trkQuality);
142  m_h1_cotTheta_res = createHistogram1D("h1cotThetares", "cot#theta residuals", 100, -0.1, 0.1, "cot#theta resid",
144 
145  //track parameters residuals - momentum
146  m_h1_px_res = createHistogram1D("h1pxres", "px absolute residuals", 200, -0.05, 0.05, "px_{reco} - px_{MC} (GeV/c)",
148  m_h1_py_res = createHistogram1D("h1pyres", "py absolute residuals", 200, -0.05, 0.05, "py_{reco} - py_{MC} (GeV/c)",
150  m_h1_pz_res = createHistogram1D("h1pzres", "pz absolute residuals", 200, -0.05, 0.05, "pz_{reco} - pz_{MC} (GeV/c)",
152  m_h1_p_res = createHistogram1D("h1pres", "p relative residuals", 200, -0.05, 0.05, "p_{reco} - p_{MC} / p_{MC}",
154  m_h1_pt_res = createHistogram1D("h1ptres", "pt relative residuals", 200, -0.05, 0.05, "pt_{reco} - pt_{MC} / pt_{MC}",
156  //track parameters residuals - position
157  m_h1_x_res = createHistogram1D("h1xres", " residuals", 200, -0.05, 0.05, "x_{reco} - x_{MC} (cm)", m_histoList_trkQuality);
158  m_h1_y_res = createHistogram1D("h1yres", " residuals", 200, -0.05, 0.05, "y_{reco} - y_{MC} (cm)", m_histoList_trkQuality);
159  m_h1_z_res = createHistogram1D("h1zres", " residuals", 200, -0.05, 0.05, "z_{reco} - z_{MC} (cm)", m_histoList_trkQuality);
160  m_h1_r_res = createHistogram1D("h1rres", " residuals", 200, -0.05, 0.05, "r_{reco} - r_{MC} (cm)", m_histoList_trkQuality);
161  m_h1_rtot_res = createHistogram1D("h1rtotres", " residuals", 200, -0.05, 0.05, "rtot_{reco} - rtot_{MC} (cm)",
163 
164  m_h2_chargeVSchargeMC = createHistogram2D("h2chargecheck", "chargeVSchargeMC", 3, -1.5, 1.5, "charge MC", 3, -1.5, 1.5,
165  "charge reco", m_histoList_trkQuality);
166 
167  //track parameters pulls
168  m_h1_d0_pll = createHistogram1D("h1d0pll", "d0 pulls", 100, -5, 5, "d0 pull", m_histoList_trkQuality);
169  m_h1_phi_pll = createHistogram1D("h1phipll", "#phi pulls", 100, -5, 5, "#phi pull", m_histoList_trkQuality);
170  m_h1_omega_pll = createHistogram1D("h1omegapll", "#omega pulls", 100, -5, 5, "#omega pull", m_histoList_trkQuality);
171  m_h1_z0_pll = createHistogram1D("h1z0pll", "z0 pulls", 100, -5, 5, "z0 pull", m_histoList_trkQuality);
172  m_h1_cotTheta_pll = createHistogram1D("h1cotThetapll", "cot#theta pulls", 100, -5, 5, "cot#theta pull", m_histoList_trkQuality);
173 
174 
175  //first hit position using track parameters errors
176  m_h2_d0errphi0err_xy = createHistogram2D("h2d0errphierrXY", "#sigma_{d0}/#sigma_{#phi} projected on x,y",
177  2000, -10, 10, "x (cm)",
178  2000, -10, 10, "y (cm)",
180 
181  m_h2_d0errphi0err_rz = createHistogram2D("h2d0errphierrRZ", "#sigma_{d0}/#sigma_{#phi} projected on z and r_{t}=#sqrt{x^{2}+y^{2}}",
182  2000, -30, 40, "z (cm)",
183  2000, 0, 15, "r_{t} (cm)",
185 
186  m_h2_z0errcotThetaerr_xy = (TH2F*)duplicateHistogram("h2z0errcotThetaerrXY", "#sigma_{z0}/#sigma_{cot#theta} projected on x,y",
189 
190  m_h2_OmegaerrOmegaVSpt = createHistogram2D("h2OmegaerrOmegaVSpt", "#sigma_{#omega}/#omega VS p_{t}",
191  100, 0, 3, "p_{t} (GeV/c)",
192  1000, 0, 0.2, "#sigma_{#omega}/#omega",
194 
195 
196  m_h2_z0errVSpt = createHistogram2D("h2z0errVSpt", "#sigma_{z0} VS p_{t}",
197  100, 0, 3, "p_{t} (GeV/c)",
198  100, 0, 0.1, "#sigma_{z0} (cm)",
200 
201  m_h2_z0errVSpt_wtpxd = (TH2F*)duplicateHistogram("h2z0errVSpt_wTruePXD", "#sigma_{z0} VS p_{t}, with True PXD hits", m_h2_z0errVSpt,
203  m_h2_z0errVSpt_wfpxd = (TH2F*)duplicateHistogram("h2z0errVSpt_wFalsePXD", "#sigma_{z0} VS p_{t}, with False PXD hits",
206  m_h2_z0errVSpt_wpxd = (TH2F*)duplicateHistogram("h2z0errVSpt_wPXD", "#sigma_{z0} VS p_{t}, with PXD hits", m_h2_z0errVSpt,
208 
209  m_h2_z0errVSpt_wopxd = (TH2F*)duplicateHistogram("h2z0errVSpt_woPXD", "#sigma_{z0} VS p_{t}, no PXD hits", m_h2_z0errVSpt,
211 
212  m_h2_d0errVSpt = createHistogram2D("h2d0errVSpt", "#sigma_{d0} VS p_{t}",
213  100, 0, 3, "p_{t} (GeV/c)",
214  100, 0, 0.1, "#sigma_{d0} (cm)",
216  m_h2_d0errVSpt_wtpxd = (TH2F*)duplicateHistogram("h2d0errVSpt_wTruePXD", "#sigma_{d0} VS p_{t}, with True PXD hits", m_h2_d0errVSpt,
218  m_h2_d0errVSpt_wfpxd = (TH2F*)duplicateHistogram("h2d0errVSpt_wFalsePXD", "#sigma_{d0} VS p_{t}, with False PXD hits",
221  m_h2_d0errVSpt_wpxd = (TH2F*)duplicateHistogram("h2d0errVSpt_wPXD", "#sigma_{d0} VS p_{t}, with PXD hits", m_h2_d0errVSpt,
223 
224  m_h2_d0errVSpt_wopxd = (TH2F*)duplicateHistogram("h2d0errVSpt_woPXD", "#sigma_{d0} VS p_{t}, no PXD hits", m_h2_d0errVSpt,
226  m_h2_d0errMSVSpt = createHistogram2D("h2d0errMSVSpt", "#sigma_{d0} * #betapsin^{3/2}#theta VS p_{t}",
227  50, 0, 2.5, "p_{t} (GeV/c)",
228  500, 0, 1, "cm",
230 
231  //hits used in the fit
232  m_h2_TrackPointFitWeightVXD = createHistogram2D("h2TPFitWeightVXD", "VXD TrackPoint Fit Weight", 6, 0.5, 6.5, "VXD layer", 20, 0, 1,
233  "weight", m_histoList);
234  m_h2_TrackPointFitWeightCDC = createHistogram2D("h2TPFitWeightCDC", "CDC TrackPoint Fit Weight", 56, -0.5, 55.5, "CDC layer", 20, 0,
235  1, "weight", m_histoList);
236 
237  m_h1_nHitDetID = createHistogram1D("h1nHitDetID", "detector ID per hit", 4, -0.5, 3.5, "0=PXD, 1=SVD2D, 2=SVD,3=CDC", m_histoList);
238  m_h1_nCDChitsPR = createHistogram1D("h1nCDCHitsPR", "number of CDC hits from PR per Layer", 56, -0.5, 55.5, "CDC Layer",
239  m_histoList);
240  m_h1_nCDChitsWeighted = (TH1F*)duplicateHistogram("h1nCDCHitsWeighted", "CDC hits used in the fit per Layer, weighted",
242  m_h1_nCDChitsUsed = (TH1F*)duplicateHistogram("h1nCDCHitsUsed",
243  "approximated number of CDC hits used in the fit per Layer, weighted", m_h1_nCDChitsPR, m_histoList);
244  m_h1_nVXDhitsPR = createHistogram1D("h1nVXDHitsPR", "number of VXD hits from PR per Layer", 6, 0.5, 6.5, "VXD Layer", m_histoList);
245  m_h1_nVXDhitsWeighted = (TH1F*)duplicateHistogram("h1nVXDHitsWeighted", "number of VXD hits used in the fit per Layer, weighted",
247  m_h1_nVXDhitsUsed = (TH1F*)duplicateHistogram("h1nVXDHitsUsed",
248  "approximate number of VXD hits used in the fit per Layer, weighted", m_h1_nVXDhitsPR, m_histoList);
249  m_h2_VXDhitsPR_xy = createHistogram2D("h2hitsPRXY", "Pattern Recognition hits, transverse plane",
250  2000, -15, 15, "x (cm)",
251  2000, -15, 15, "y (cm)",
252  m_histoList);
253 
254  m_h2_VXDhitsPR_rz = createHistogram2D("h2hitsPRRZ", "Pattern Recognition Hits, r_{t} z",
255  2000, -30, 40, "z (cm)",
256  2000, 0, 15, "r_{t} (cm)",
257  m_histoList);
258 
259 
260 
261  //histograms to produce efficiency plots
262  Double_t bins_pt[10 + 1] = {0, 0.05, 0.1, 0.15, 0.2, 0.3, 0.5, 1, 1.5, 2, 3.5}; //GeV/c
263  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, TMath::Pi()};
264  Double_t bins_phi[14 + 1];
265  Double_t width_phi = 2 * TMath::Pi() / 14;
266  for (int bin = 0; bin < 14 + 1; bin++)
267  bins_phi[bin] = - TMath::Pi() + bin * width_phi;
268 
269 
270  m_h3_MCParticle = createHistogram3D("h3MCParticle", "entry per MCParticle",
271  10, bins_pt, "p_{t} (GeV/c)",
272  10, bins_theta, "#theta",
273  14, bins_phi, "#phi" /*, m_histoList*/);
274 
275  m_h3_TracksPerMCParticle = (TH3F*)duplicateHistogram("h3TracksPerMCParticle",
276  "entry per Track connected to a MCParticle",
277  m_h3_MCParticle /*, m_histoList*/);
278 
279  m_h3_TrackswPXDHitsPerMCParticle = (TH3F*)duplicateHistogram("h3TrackswPXDHitsPerMCParticle",
280  "entry per Track with PXD hits connected to a MCParticle",
281  m_h3_MCParticle /*, m_histoList*/);
282 
283  m_h3_RecoTrackswPXDHitsPerMCParticle = (TH3F*)duplicateHistogram("h3RecoTrackswPXDHitsPerMCParticle",
284  "entry per RecoTrack with PXD hits connected to a MCParticle",
285  m_h3_MCParticle /*, m_histoList*/);
286 
287  m_h3_RecoTrackswPXDHitsPerMCParticlewPXDHits = (TH3F*)duplicateHistogram("h3RecoTrackswPXDHitsPerMCParticlewPXDHits",
288  "entry per RecoTrack with PXD hits connected to a MCParticle with PXD hits",
289  m_h3_MCParticle /*, m_histoList*/);
290 
291  m_h3_MCParticleswPXDHits = (TH3F*)duplicateHistogram("h3MCParticleswPXDHitsPerMCParticle",
292  "entry per MCParticle with PXD hits",
293  m_h3_MCParticle /*, m_histoList*/);
294 
295  m_h3_MCRecoTrack = (TH3F*)duplicateHistogram("h3MCRecoTrack",
296  "entry per MCRecoTrack connected to the MCParticle",
297  m_h3_MCParticle /*, m_histoList*/);
298 
299  m_h3_TracksPerMCRecoTrack = (TH3F*)duplicateHistogram("h3TracksPerMCRecoTrack",
300  "entry per Track connected to an MCRecoTrack",
301  m_h3_MCParticle /*, m_histoList*/);
302  //plus
303  m_h3_MCParticle_plus = (TH3F*)duplicateHistogram("h3MCParticle_plus", "entry per positive MCParticle",
304  m_h3_MCParticle /*, m_histoList*/);
305 
306  m_h3_TracksPerMCParticle_plus = (TH3F*)duplicateHistogram("h3TracksPerMCParticle_plus",
307  "entry per Track connected to a positive MCParticle",
308  m_h3_MCParticle /*, m_histoList*/);
309 
310  m_h3_MCRecoTrack_plus = (TH3F*)duplicateHistogram("h3MCRecoTrack_plus",
311  "entry per MCRecoTrack connected to the positive MCParticle",
312  m_h3_MCParticle /*, m_histoList*/);
313 
314  m_h3_TracksPerMCRecoTrack_plus = (TH3F*)duplicateHistogram("h3TracksPerMCRecoTrack_plus",
315  "entry per Track connected to a positive MCRecoTrack",
316  m_h3_MCParticle /*, m_histoList*/);
317 
318 
319  //minus
320  m_h3_MCParticle_minus = (TH3F*)duplicateHistogram("h3MCParticlee_minus", "entry per negative MCParticle",
321  m_h3_MCParticle /*, m_histoList*/);
322 
323  m_h3_TracksPerMCParticle_minus = (TH3F*)duplicateHistogram("h3TracksPerMCParticle_minus",
324  "entry per Track connected to a negative MCParticle",
325  m_h3_MCParticle /*, m_histoList*/);
326 
327  m_h3_MCRecoTrack_minus = (TH3F*)duplicateHistogram("h3MCRecoTrack_minus",
328  "entry per MCRecoTrack connected to the negative MCParticle",
329  m_h3_MCParticle /*, m_histoList*/);
330 
331  m_h3_TracksPerMCRecoTrack_minus = (TH3F*)duplicateHistogram("h3TracksPerMCRecoTrack_minus",
332  "entry per Track connected to a negative MCRecoTrack",
333  m_h3_MCParticle /*, m_histoList*/);
334 
335  //histograms to produce efficiency plots
336  m_h1_HitsRecoTrackPerMCRecoTrack = createHistogram1D("h1hitsTCperMCRT", "RecoTrack per MCRecoTrack Hit in VXD layers", 6, 0.5, 6.5,
337  "# VXD layer" /*, m_histoList*/);
338 
339  m_h1_HitsMCRecoTrack = (TH1F*) duplicateHistogram("h1hitsMCRT", " MCRecoTrack Hit in VXD layers",
340  m_h1_HitsRecoTrackPerMCRecoTrack /*, m_histoList*/);
341 
342 
343  //histograms to produce purity plots
344  m_h3_Tracks = (TH3F*)duplicateHistogram("h3Tracks", "entry per Track",
345  m_h3_MCParticle /*, m_histoList*/);
346 
347  m_h3_MCParticlesPerTrack = (TH3F*)duplicateHistogram("h3MCParticlesPerTrack",
348  "entry per MCParticle connected to a Track",
349  m_h3_MCParticle /*, m_histoList*/);
350 }
351 
353 {
354 
355 }
356 
358 {
359 
361 
362  B2Vector3D magField = BFieldManager::getField(0, 0, 0) / Unit::T;
363 
364  bool hasTrack = false;
365  B2DEBUG(99, "+++++ 1. loop on MCParticles");
366  BOOST_FOREACH(MCParticle & mcParticle, mcParticles) {
367 
368  if (! isTraceable(mcParticle))
369  continue;
370 
371  int pdgCode = mcParticle.getPDG();
372  B2DEBUG(99, "MCParticle has PDG code " << pdgCode);
373 
374  int nFittedTracksMCRT = 0;
375  int nFittedTracks = 0;
376  int nFittedTrackswPXDHits = 0;
377 
378  MCParticleInfo mcParticleInfo(mcParticle, magField);
379 
380  hasTrack = false;
381 
382  m_h3_MCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
383 
384  if (mcParticleInfo.getCharge() > 0)
385  m_h3_MCParticle_plus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
386  else if (mcParticleInfo.getCharge() < 0)
387  m_h3_MCParticle_minus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
388  else
389  continue;
390 
391  if (mcParticle.hasSeenInDetector(Const::PXD))
392  m_h3_MCParticleswPXDHits->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
393 
394  //1. retrieve all the Tracks related to the MCParticle
395 
396  //1.0 check if there is a RecoTrack
397  RelationVector<RecoTrack> MCRecoTracks_fromMCParticle =
398  DataStore::getRelationsWithObj<RecoTrack>(&mcParticle, m_MCRecoTracksName);
399 
400  if (MCRecoTracks_fromMCParticle.size() > 0)
401  if (MCRecoTracks_fromMCParticle[0]->hasPXDHits()) {
402  m_h3_RecoTrackswPXDHitsPerMCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
403  if (mcParticle.hasSeenInDetector(Const::PXD))
404  m_h3_RecoTrackswPXDHitsPerMCParticlewPXDHits->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
405  }
406  m_multiplicityMCRecoTracks->Fill(MCRecoTracks_fromMCParticle.size());
407 
408  RelationVector<RecoTrack> RecoTracks_fromMCParticle =
409  DataStore::getRelationsWithObj<RecoTrack>(&mcParticle, m_RecoTracksName);
410 
411  m_multiplicityRecoTracks->Fill(RecoTracks_fromMCParticle.size());
412 
413  if (MCRecoTracks_fromMCParticle.size() > 0) {
414  m_h3_MCRecoTrack->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
415 
416  if (mcParticleInfo.getCharge() > 0)
417  m_h3_MCRecoTrack_plus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
418  else if (mcParticleInfo.getCharge() < 0)
419  m_h3_MCRecoTrack_minus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
420  else
421  continue;
422  }
423 
424  //1.a retrieve all Tracks related to the MCParticle
425  RelationVector<Track> Tracks_fromMCParticle = DataStore::getRelationsWithObj<Track>(&mcParticle);
426  m_multiplicityTracks->Fill(Tracks_fromMCParticle.size());
427 
428  B2DEBUG(99, Tracks_fromMCParticle.size() << " Tracks related to this MCParticle");
429 
430  for (int trk = 0; trk < (int)Tracks_fromMCParticle.size(); trk++) {
431 
432  const TrackFitResult* fitResult = Tracks_fromMCParticle[trk]->getTrackFitResult(Const::ChargedStable(m_ParticleHypothesis));
433 
434  if ((fitResult == nullptr) || (fitResult->getParticleType() != Const::ChargedStable(m_ParticleHypothesis)))
435  B2WARNING(" the TrackFitResult is not found!");
436 
437  else { // valid TrackFitResult found
438 
439  if (!hasTrack) {
440 
441  hasTrack = true;
442 
443  nFittedTracks++;
444 
445  if (fitResult->getHitPatternVXD().getNPXDHits() > 0) {
446  m_h3_TrackswPXDHitsPerMCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
447  nFittedTrackswPXDHits++;
448  }
449 
450  m_h3_TracksPerMCParticle->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
451  if (mcParticleInfo.getCharge() > 0)
452  m_h3_TracksPerMCParticle_plus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
453  else if (mcParticleInfo.getCharge() < 0)
454  m_h3_TracksPerMCParticle_minus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
455  else
456  continue;
457 
458  if (MCRecoTracks_fromMCParticle.size() > 0) {
459  nFittedTracksMCRT++;
460  m_h3_TracksPerMCRecoTrack->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
461  if (mcParticleInfo.getCharge() > 0)
462  m_h3_TracksPerMCRecoTrack_plus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
463  else if (mcParticleInfo.getCharge() < 0)
464  m_h3_TracksPerMCRecoTrack_minus->Fill(mcParticleInfo.getPt(), mcParticleInfo.getPtheta(), mcParticleInfo.getPphi());
465  else
466  continue;
467  }
468 
469 
470  }
471 
472 
473  fillTrackParams1DHistograms(fitResult, mcParticleInfo);
474 
475  }
476  }
477 
478  m_multiplicityFittedTracks->Fill(nFittedTracks);
479  if (MCRecoTracks_fromMCParticle.size() > 0)
480  m_multiplicityFittedTracksPerMCRT->Fill(nFittedTracksMCRT);
481 
482  }
483 
484 
485  B2DEBUG(99, "+++++ 2. loop on Tracks");
486 
487  //2. retrieve all the MCParticles related to the Tracks
489 
490  BOOST_FOREACH(Track & track, tracks) {
491 
492  int nMCParticles = 0;
493 
494  //check if the track has been fitted
495  const TrackFitResult* fitResult = track.getTrackFitResult(Const::ChargedStable(m_ParticleHypothesis));
496 
497  if ((fitResult == nullptr) || (fitResult->getParticleType() != Const::ChargedStable(m_ParticleHypothesis)))
498  continue;
499 
500  m_h1_pValue->Fill(fitResult->getPValue());
501 
502  TVector3 momentum = fitResult->getMomentum();
503  m_h3_Tracks->Fill(momentum.Pt(), momentum.Theta(), momentum.Phi());
504 
506 
508 
509  for (int layer = 0; layer < 56; layer++) {
510  if (fitResult->getHitPatternCDC().hasLayer(layer))
511  m_h1_nCDChitsUsed->Fill(layer);
512  }
513  for (int layer = 1; layer <= 2; layer++) {
514  for (int i = 0; i < fitResult->getHitPatternVXD().getPXDLayer(layer); i++)
515  m_h1_nVXDhitsUsed->Fill(layer);
516  }
517  for (int layer = 3; layer <= 6; layer++) {
518  int n1 = fitResult->getHitPatternVXD().getSVDLayer(layer).first;
519  int n2 = fitResult->getHitPatternVXD().getSVDLayer(layer).second;
520  int N = n1 + n2;
521 
522  for (int i = 0; i < N; i++)
523  m_h1_nVXDhitsUsed->Fill(layer);
524  }
525 
526 
527  RelationVector<MCParticle> MCParticles_fromTrack = DataStore::getRelationsWithObj<MCParticle>(&track);
528 
529  for (int mcp = 0; mcp < (int)MCParticles_fromTrack.size(); mcp++)
530  if (isTraceable(*MCParticles_fromTrack[mcp])) {
531  nMCParticles ++;
532  m_h3_MCParticlesPerTrack->Fill(momentum.Pt(), momentum.Theta(), momentum.Phi());
533  }
534  // }
535 
536  m_multiplicityMCParticlesPerTrack->Fill(nMCParticles);
537 
538  }
539 
540 
541  B2DEBUG(99, "+++++ 3. loop on MCRecoTracks");
542 
543  //3. retrieve all MCRecoTracks
545  StoreArray<PXDCluster> pxdClusters;
546  StoreArray<SVDCluster> svdClusters;
547  StoreArray<CDCHit> cdcHit;
548 
549 
550  BOOST_FOREACH(RecoTrack & mcRecoTrack, mcRecoTracks) {
551 
552  int nRecoTrack = 0;
553  bool hasRecoTrack = false;
554 
555  //3.a retrieve the RecoTrack
556  RelationVector<RecoTrack> RecoTracks_fromMCRecoTrack = DataStore::getRelationsWithObj<RecoTrack>(&mcRecoTrack);
557  B2DEBUG(99, "~ " << RecoTracks_fromMCRecoTrack.size() << " RecoTracks related to this MCRecoTrack");
558  m_multiplicityRecoTracksPerMCRT->Fill(RecoTracks_fromMCRecoTrack.size());
559 
560  //3.a retrieve the MCParticle
561  RelationVector<MCParticle> MCParticles_fromMCRecoTrack = DataStore::getRelationsWithObj<MCParticle>(&mcRecoTrack);
562 
563  B2DEBUG(99, "~~~ " << MCParticles_fromMCRecoTrack.size() << " MCParticles related to this MCRecoTrack");
564  for (int mcp = 0; mcp < (int)MCParticles_fromMCRecoTrack.size(); mcp++) {
565 
566  //3.b retrieve all RecoTracks related to the MCRecoTrack
567  RelationVector<RecoTrack> RecoTracks_fromMCParticle = DataStore::getRelationsWithObj<RecoTrack>
568  (MCParticles_fromMCRecoTrack[mcp]);
569 
570  B2DEBUG(99, "~~~~~ " << RecoTracks_fromMCParticle.size() << " RecoTracks related to this MCParticle");
571  for (int tc = 0; tc < (int)RecoTracks_fromMCParticle.size(); tc++)
572  if (!hasRecoTrack) {
573  hasRecoTrack = true;
574  nRecoTrack++;
575  }
576 
577  }
578 
579  }
580 
581 
582  B2DEBUG(99, "+++++ 4. loop on RecoTracks");
583 
584  //4. retrieve all RecoTracks
585  StoreArray<RecoTrack> RecoTracks;
586 
587  BOOST_FOREACH(RecoTrack & recoTrack, RecoTracks) {
588 
589  // int nMCRecoTrack = 0;
590 
591  // retrieve the MCRecoTrack
592  RelationVector<RecoTrack> MCRecoTracks_fromRecoTrack = DataStore::getRelationsWithObj<RecoTrack>(&recoTrack, m_MCRecoTracksName);
593  m_multiplicityMCRecoTracksPerRT->Fill(MCRecoTracks_fromRecoTrack.size());
594 
595 
596  /*
597  //4.a retrieve the MCParticle
598  RelationVector<MCParticle> MCParticles_fromRecoTrack = DataStore::getRelationsWithObj<MCParticle>(&recoTrack);
599 
600  B2DEBUG(99, "~~~ " << MCParticles_fromRecoTrack.size() << " MCParticles related to this RecoTrack");
601  for (int mcp = 0; mcp < (int)MCParticles_fromRecoTrack.size(); mcp++) {
602 
603  //4.b retrieve all MCRecoTracks related to the RecoTrack
604  RelationVector<RecoTrack> mcRecoTracks_fromMCParticle = DataStore::getRelationsWithObj<RecoTrack>
605  (MCParticles_fromRecoTrack[mcp], m_MCRecoTracksName);
606 
607  B2DEBUG(99, "~~~~~ " << mcRecoTracks_fromMCParticle.size() << " MCRecoTracks related to this MCParticle");
608  for (int mctc = 0; mctc < (int)mcRecoTracks_fromMCParticle.size(); mctc++) {
609  nMCRecoTrack++;
610 
611  }
612  }
613 
614  // m_multiplicityMCRecoTracksPerRT->Fill(nMCRecoTrack);
615  */
616  }
617 
618 }
619 
621 {
622 
623  double num = 0;
624  double den = 0;
625 
626  for (int bin = 1; bin < m_multiplicityFittedTracks->GetNbinsX(); bin ++)
627  num += m_multiplicityFittedTracks->GetBinContent(bin + 1);
628  den = m_multiplicityFittedTracks->GetEntries();
629  double efficiency = num / den ;
630  double efficiencyErr = sqrt(efficiency * (1 - efficiency)) / sqrt(den);
631 
632  double nFittedTracksMCRT = 0;
633  for (int bin = 1; bin < m_multiplicityFittedTracksPerMCRT->GetNbinsX(); bin ++)
634  nFittedTracksMCRT += m_multiplicityFittedTracksPerMCRT->GetBinContent(bin + 1);
635  double efficiencyMCRT = nFittedTracksMCRT / m_multiplicityFittedTracksPerMCRT->GetEntries();
636  double efficiencyMCRTErr = sqrt(efficiencyMCRT * (1 - efficiencyMCRT)) / sqrt(m_multiplicityFittedTracksPerMCRT->GetEntries());
637 
638  double nRecoTrack = 0;
639  for (int bin = 1; bin < m_multiplicityRecoTracksPerMCRT->GetNbinsX(); bin ++)
640  nRecoTrack += m_multiplicityRecoTracksPerMCRT->GetBinContent(bin + 1);
641  double efficiencyPR = nRecoTrack / m_multiplicityRecoTracksPerMCRT->GetEntries();
642  double efficiencyPRErr = sqrt(efficiencyPR * (1 - efficiencyPR)) / sqrt(m_multiplicityRecoTracksPerMCRT->GetEntries());
643 
644  double nMCRecoTrack = 0;
645  for (int bin = 1; bin < m_multiplicityMCRecoTracksPerRT->GetNbinsX(); bin ++)
646  nMCRecoTrack += m_multiplicityMCRecoTracksPerRT->GetBinContent(bin + 1);
647  double purityPR = nMCRecoTrack / m_multiplicityMCRecoTracksPerRT->GetEntries();
648  double purityPRErr = sqrt(purityPR * (1 - purityPR)) / sqrt(m_multiplicityMCRecoTracksPerRT->GetEntries());
649 
650  double nMCParticles = 0;
651  for (int bin = 1; bin < m_multiplicityMCParticlesPerTrack->GetNbinsX(); bin ++)
652  nMCParticles += m_multiplicityMCParticlesPerTrack->GetBinContent(bin + 1);
653  double purity = nMCParticles / m_multiplicityMCParticlesPerTrack->GetEntries();
654  double purityErr = sqrt(purity * (1 - purity)) / sqrt(m_multiplicityMCParticlesPerTrack->GetEntries());
655 
656  B2INFO("");
657  B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
658  B2INFO("~ Tracking Performance Evaluation ~ SHORT SUMMARY ~");
659  B2INFO("");
660  B2INFO(" + overall:");
661  B2INFO(" efficiency = (" << efficiency * 100 << " +/- " << efficiencyErr * 100 << ")% ");
662  B2INFO(" purity = " << purity * 100 << " +/- " << purityErr * 100 << ")% ");
663  B2INFO("");
664  B2INFO(" + factorizing geometrical acceptance:");
665  B2INFO(" efficiency = " << efficiencyMCRT * 100 << " +/- " << efficiencyMCRTErr * 100 << ")% ");
666  B2INFO("");
667  B2INFO(" + pattern recognition:");
668  B2INFO(" efficiency = " << efficiencyPR * 100 << " +/- " << efficiencyPRErr * 100 << ")% ");
669  B2INFO(" purity = " << purityPR * 100 << " +/- " << purityPRErr * 100 << ")% ");
670  B2INFO("");
671  B2INFO("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
672 }
673 
675 {
676 
677 
680 
682 
683  if (m_rootFilePtr != nullptr) {
684  m_rootFilePtr->cd();
685 
686  TDirectory* oldDir = gDirectory;
687 
688  TDirectory* dir_multiplicity = oldDir->mkdir("multiplicity");
689  dir_multiplicity->cd();
690  TIter nextH_multiplicity(m_histoList_multiplicity);
691  TObject* obj;
692  while ((obj = nextH_multiplicity()))
693  obj->Write();
694 
695  TDirectory* dir_efficiency = oldDir->mkdir("efficiency");
696  dir_efficiency->cd();
697  TIter nextH_efficiency(m_histoList_efficiency);
698  while ((obj = nextH_efficiency()))
699  obj->Write();
700 
701  TDirectory* dir_trkQuality = oldDir->mkdir("trkQuality");
702  dir_trkQuality->cd();
703  TIter nextH_trkQuality(m_histoList_trkQuality);
704  while ((obj = nextH_trkQuality()))
705  obj->Write();
706 
707  TDirectory* dir_firstHit = oldDir->mkdir("firstHit");
708  dir_firstHit->cd();
709  TIter nextH_firstHit(m_histoList_firstHit);
710  while ((obj = nextH_firstHit()))
711  obj->Write();
712 
713 
714 
715 
716  m_rootFilePtr->Close();
717  }
718 
719 }
720 
721 
723  MCParticleInfo mcParticleInfo)
724 {
725 
726  //track parameters errors
727  double d0_err = sqrt((fitResult->getCovariance5())[0][0]);
728  double phi_err = sqrt((fitResult->getCovariance5())[1][1]);
729  double omega_err = sqrt((fitResult->getCovariance5())[2][2]);
730  double z0_err = sqrt((fitResult->getCovariance5())[3][3]);
731  double cotTheta_err = sqrt((fitResult->getCovariance5())[4][4]);
732 
733  //track parameters residuals:
734  double d0_res = fitResult->getD0() - mcParticleInfo.getD0();
735  double phi_res = TMath::ASin(TMath::Sin(fitResult->getPhi() - mcParticleInfo.getPhi()));
736  double omega_res = fitResult->getOmega() - mcParticleInfo.getOmega();
737  double z0_res = fitResult->getZ0() - mcParticleInfo.getZ0();
738  double cotTheta_res = fitResult->getCotTheta() - mcParticleInfo.getCotTheta();
739 
740  //track parameters residuals in momentum:
741  double px_res = fitResult->getMomentum().X() - mcParticleInfo.getPx();
742  double py_res = fitResult->getMomentum().Y() - mcParticleInfo.getPy();
743  double pz_res = fitResult->getMomentum().Z() - mcParticleInfo.getPz();
744  double p_res = (fitResult->getMomentum().Mag() - mcParticleInfo.getP()) / mcParticleInfo.getP();
745  double pt_res = (fitResult->getMomentum().Pt() - mcParticleInfo.getPt()) / mcParticleInfo.getPt();
746 
747  //track parameters residuals in position:
748  double x_res = fitResult->getPosition().X() - mcParticleInfo.getX();
749  double y_res = fitResult->getPosition().Y() - mcParticleInfo.getY();
750  double z_res = fitResult->getPosition().Z() - mcParticleInfo.getZ();
751  double r_res = fitResult->getPosition().Perp() - sqrt(mcParticleInfo.getX() * mcParticleInfo.getX() + mcParticleInfo.getY() *
752  mcParticleInfo.getY());
753  double rtot_res = fitResult->getPosition().Mag() - sqrt(mcParticleInfo.getX() * mcParticleInfo.getX() + mcParticleInfo.getY() *
754  mcParticleInfo.getY() + mcParticleInfo.getZ() * mcParticleInfo.getZ());
755 
756  m_h1_d0_err->Fill(d0_err);
757  m_h1_phi_err->Fill(phi_err);
758  m_h1_omega_err->Fill(omega_err);
759  m_h1_z0_err->Fill(z0_err);
760  m_h1_cotTheta_err->Fill(cotTheta_err);
761 
762  m_h1_d0_res->Fill(d0_res);
763  m_h1_phi_res->Fill(phi_res);
764  m_h1_omega_res->Fill(omega_res);
765  m_h1_z0_res->Fill(z0_res);
766  m_h1_cotTheta_res->Fill(cotTheta_res);
767 
768  m_h1_px_res->Fill(px_res);
769  m_h1_py_res->Fill(py_res);
770  m_h1_pz_res->Fill(pz_res);
771  m_h1_p_res->Fill(p_res);
772  m_h1_pt_res->Fill(pt_res);
773 
774  m_h1_x_res->Fill(x_res);
775  m_h1_y_res->Fill(y_res);
776  m_h1_z_res->Fill(z_res);
777  m_h1_r_res->Fill(r_res);
778  m_h1_rtot_res->Fill(rtot_res);
779 
780  m_h2_chargeVSchargeMC->Fill(mcParticleInfo.getCharge(), fitResult->getChargeSign());
781 
782  m_h1_d0_pll->Fill(d0_res / d0_err);
783  m_h1_phi_pll->Fill(phi_res / phi_err);
784  m_h1_omega_pll->Fill(omega_res / omega_err);
785  m_h1_z0_pll->Fill(z0_res / z0_err);
786  m_h1_cotTheta_pll->Fill(cotTheta_res / cotTheta_err);
787 
788 
789  m_h2_OmegaerrOmegaVSpt->Fill(fitResult->getMomentum().Pt(), omega_err / mcParticleInfo.getOmega());
790 
791 
792 }
793 
795 {
796 
797 
798  double d0_err = sqrt((fitResult->getCovariance5())[0][0]);
799  double phi_err = sqrt((fitResult->getCovariance5())[1][1]);
800  double z0_err = sqrt((fitResult->getCovariance5())[3][3]);
801  double cotTheta_err = sqrt((fitResult->getCovariance5())[4][4]);
802 
803  TVector3 momentum = fitResult->getMomentum();
804 
805  double px = momentum.Px();
806  double py = momentum.Py();
807  double pz = momentum.Pz();
808  double pt = momentum.Pt();
809  double p = momentum.Mag();
810  double mass = fitResult->getParticleType().getMass();
811  double beta = p / sqrt(p * p + mass * mass);
812  double sinTheta = TMath::Sin(momentum.Theta());
813 
814  m_h2_d0errphi0err_xy->Fill(d0_err / phi_err * px / pt,
815  d0_err / phi_err * py / pt);
816  m_h2_z0errcotThetaerr_xy->Fill(z0_err / cotTheta_err * px / pt,
817  z0_err / cotTheta_err * py / pt);
818  m_h2_d0errphi0err_rz->Fill(d0_err / phi_err * pz / pt,
819  d0_err / phi_err);
820 
821  m_h2_d0errVSpt->Fill(pt, d0_err);
822 
823  m_h2_z0errVSpt->Fill(pt, z0_err);
824 
825  m_h2_d0errMSVSpt->Fill(pt, d0_err * beta * p * pow(sinTheta, 3 / 2) / 0.0136);
826 
827 }
828 
830 {
831 
832  //hits used in the fit
833 
835 
836  const VXD::GeoCache& aGeometry = VXD::GeoCache::getInstance();
837 
838  bool hasPXDhit = false;
839  bool isTrueHit = false;
840 
841  double d0_err = -999;
842  double z0_err = -999;
843  double pt = -999;
844 
845  if (fitResult) {
846  d0_err = sqrt((fitResult->getCovariance5())[0][0]);
847  z0_err = sqrt((fitResult->getCovariance5())[3][3]);
848  pt = fitResult->getMomentum().Pt();
849  }
850 
851  bool hasCDChit[56] = { false };
852 
853  RelationVector<RecoTrack> RecoTracks_fromTrack = DataStore::getRelationsWithObj<RecoTrack>(&theTrack);
854 
855  for (int tc = 0; tc < (int)RecoTracks_fromTrack.size(); tc++) {
856 
857  const std::vector< genfit::TrackPoint* >& tp_vector = RecoTracks_fromTrack[tc]->getHitPointsWithMeasurement();
858  for (int i = 0; i < (int) tp_vector.size(); i++) {
859  genfit::TrackPoint* tp = tp_vector[i];
860 
861  int nMea = tp->getNumRawMeasurements();
862  for (int mea = 0; mea < nMea; mea++) {
863 
864  genfit::AbsMeasurement* absMeas = tp->getRawMeasurement(mea);
865  double weight = 0;
866 
867  std::vector<double> weights;
868  genfit::KalmanFitterInfo* kalmanInfo = tp->getKalmanFitterInfo();
869  if (kalmanInfo)
870  weights = kalmanInfo->getWeights();
871  else //no kalman fitter info, fill the weights vector with 0 (VXD), or 0,0 (CDC)
872  B2WARNING(" No KalmanFitterInfo associated to the TrackPoint!");
873 
874  double detId(-999);
875  TVector3 globalHit(-999, -999, -999);
876 
877  PXDRecoHit* pxdHit = dynamic_cast<PXDRecoHit*>(absMeas);
878  SVDRecoHit2D* svdHit2D = dynamic_cast<SVDRecoHit2D*>(absMeas);
879  SVDRecoHit* svdHit = dynamic_cast<SVDRecoHit*>(absMeas);
880  CDCRecoHit* cdcHit = dynamic_cast<CDCRecoHit*>(absMeas);
881 
882  if (pxdHit) {
883  hasPXDhit = true;
884  isTrueHit = false;
885 
886  if (kalmanInfo)
887  weight = weights.at(mea);
888 
889  detId = 0;
890  double uCoor = pxdHit->getU();
891  double vCoor = pxdHit->getV();
892  VxdID sensor = pxdHit->getSensorID();
893 
894  m_h1_nVXDhitsPR->Fill(sensor.getLayerNumber());
895 
896  m_h1_nVXDhitsWeighted->Fill(sensor.getLayerNumber() , weight);
897 
898  m_h2_TrackPointFitWeightVXD->Fill(sensor.getLayerNumber(), weight);
899  const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensor);
900  globalHit = aSensorInfo.pointToGlobal(TVector3(uCoor, vCoor, 0), true);
901 
902 
903  const PXDCluster* pxdcl = pxdHit->getCluster();
904  RelationVector<PXDTrueHit> pxdth_fromcl = DataStore::getRelationsWithObj<PXDTrueHit>(pxdcl);
905 
906  if ((int)pxdth_fromcl.size() != 0) {
907  const PXDTrueHit* trueHit = pxdth_fromcl[0];
908 
909  if (trueHit) {
910  int trueHitIndex = trueHit->getArrayIndex();
911  RelationVector<MCParticle> MCParticles_fromTrack = DataStore::getRelationsWithObj<MCParticle>(&theTrack);
912  for (int mcp = 0; mcp < (int)MCParticles_fromTrack.size(); mcp++) {
913  RelationVector<PXDTrueHit> trueHit_fromMCParticles = DataStore::getRelationsWithObj<PXDTrueHit>(MCParticles_fromTrack[mcp]);
914  for (int th = 0; th < (int)trueHit_fromMCParticles.size(); th++) {
915  if (trueHit_fromMCParticles[th]->getArrayIndex() == trueHitIndex)
916  isTrueHit = true;
917  }
918  }
919  }
920  }
921 
922  } else if (svdHit2D) {
923 
924  if (kalmanInfo)
925  weight = weights.at(mea);
926 
927  detId = 1;
928  double uCoor = svdHit2D->getU();
929  double vCoor = svdHit2D->getV();
930  VxdID sensor = svdHit2D->getSensorID();
931 
932  m_h1_nVXDhitsPR->Fill(sensor.getLayerNumber());
933 
934  m_h1_nVXDhitsWeighted->Fill(sensor.getLayerNumber() , weight);
935 
936  m_h2_TrackPointFitWeightVXD->Fill(sensor.getLayerNumber(), weight);
937 
938  const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensor);
939  globalHit = aSensorInfo.pointToGlobal(TVector3(uCoor, vCoor, 0), true);
940 
941  } else if (svdHit) {
942 
943  if (kalmanInfo)
944  weight = weights.at(mea);
945 
946  detId = 2;
947  double uCoor = 0;
948  double vCoor = 0;
949  if (svdHit->isU())
950  uCoor = svdHit->getPosition();
951  else
952  vCoor = svdHit->getPosition();
953 
954  VxdID sensor = svdHit->getSensorID();
955  m_h1_nVXDhitsPR->Fill(sensor.getLayerNumber());
956 
957  m_h1_nVXDhitsWeighted->Fill(sensor.getLayerNumber() , weight);
958 
959  m_h2_TrackPointFitWeightVXD->Fill(sensor.getLayerNumber(), weight);
960  const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensor);
961  globalHit = aSensorInfo.pointToGlobal(TVector3(uCoor, vCoor, 0), true);
962  } else if (cdcHit) {
963 
964  if (kalmanInfo)
965  weight = weights.at(mea);
966 
967  WireID wire = cdcHit->getWireID();
968  if (! hasCDChit[wire.getICLayer()]) { //needed to validate the HitPatternCDC filling
969  m_h1_nCDChitsPR->Fill(wire.getICLayer());
970 
971  m_h1_nCDChitsWeighted->Fill(wire.getICLayer() , weight);
972  // hasCDChit[wire.getICLayer()] = true; //to validate the HitPatternCDC filling: uncomment this
973  }
974  m_h2_TrackPointFitWeightCDC->Fill(wire.getICLayer(), weight);
975  detId = 3;
976  }
977 
978 
979  m_h1_nHitDetID ->Fill(detId);
980 
981  m_h2_VXDhitsPR_xy->Fill(globalHit.X(), globalHit.Y());
982 
983  m_h2_VXDhitsPR_rz->Fill(globalHit.Z(), globalHit.Perp());
984 
985  }
986 
987  }
988  }
989 
990  if ((fitResult != nullptr) && (fitResult->getParticleType() == Const::ChargedStable(m_ParticleHypothesis))) {
991  if (hasPXDhit) {
992  m_h2_d0errVSpt_wpxd->Fill(pt, d0_err);
993  m_h2_z0errVSpt_wpxd->Fill(pt, z0_err);
994  if (isTrueHit) {
995  m_h2_d0errVSpt_wtpxd->Fill(pt, d0_err);
996  m_h2_z0errVSpt_wtpxd->Fill(pt, z0_err);
997  } else {
998  m_h2_d0errVSpt_wfpxd->Fill(pt, d0_err);
999  m_h2_z0errVSpt_wfpxd->Fill(pt, z0_err);
1000  }
1001  } else {
1002  m_h2_d0errVSpt_wopxd->Fill(pt, d0_err);
1003  m_h2_z0errVSpt_wopxd->Fill(pt, z0_err);
1004  }
1005  }
1006 
1007 }
1008 
1010 {
1011 
1012  //normalized to MCParticles
1013  TH1F* h_ineff_pt = createHistogramsRatio("hineffpt", "inefficiency VS pt, normalized to MCParticles", m_h3_TracksPerMCParticle,
1014  m_h3_MCParticle, false, 0);
1015  histoList->Add(h_ineff_pt);
1016 
1017  TH1F* h_ineff_theta = createHistogramsRatio("hinefftheta", "inefficiency VS #theta, normalized to MCParticles",
1019  histoList->Add(h_ineff_theta);
1020 
1021  TH1F* h_ineff_phi = createHistogramsRatio("hineffphi", "inefficiency VS #phi, normalized to MCParticles", m_h3_TracksPerMCParticle,
1022  m_h3_MCParticle, false, 2);
1023  histoList->Add(h_ineff_phi);
1024 
1025  //normalized to MCRecoTracks
1026  TH1F* h_ineffMCRT_pt = createHistogramsRatio("hineffMCRTpt", "inefficiency VS pt, normalized to MCRecoTrack",
1028  histoList->Add(h_ineffMCRT_pt);
1029 
1030  TH1F* h_ineffMCRT_theta = createHistogramsRatio("hineffMCRTtheta", "inefficiency VS #theta, normalized to MCRecoTrack",
1032  histoList->Add(h_ineffMCRT_theta);
1033 
1034  TH1F* h_ineffMCRT_phi = createHistogramsRatio("hineffMCRTphi", "inefficiency VS #phi, normalized to MCRecoTrack",
1036  histoList->Add(h_ineffMCRT_phi);
1037 
1038 }
1039 
1041 {
1042 
1043 
1044  TH1F* h_MCPwPXDhits_pt = createHistogramsRatio("hMCPwPXDhits", "fraction of MCParticles with PXD hits VS pt",
1046  m_h3_MCParticle, true, 0);
1047  histoList->Add(h_MCPwPXDhits_pt);
1048 
1049  TH1F* h_RTwPXDhitsMCPwPXDHits_pt = createHistogramsRatio("hRecoTrkswPXDhitsMCPwPXDHits",
1050  "fraction of MCParticles with PXD Hits with RecoTracks with PXD hits VS pt",
1052  m_h3_MCParticleswPXDHits, true, 0);
1053  histoList->Add(h_RTwPXDhitsMCPwPXDHits_pt);
1054 
1055  TH1F* h_wPXDhits_pt = createHistogramsRatio("hTrkswPXDhits", "fraction of tracks with PXD hits VS pt",
1057  m_h3_TracksPerMCParticle, true, 0);
1058  histoList->Add(h_wPXDhits_pt);
1059 
1060  //normalized to MCParticles
1061  TH1F* h_eff_pt = createHistogramsRatio("heffpt", "efficiency VS pt, normalized to MCParticles", m_h3_TracksPerMCParticle,
1062  m_h3_MCParticle, true, 0);
1063  histoList->Add(h_eff_pt);
1064  // B2INFO(" efficiency in pt, NUM = "<<m_nFittedTracks<<", DEN = "<<m_nMCParticles<<", eff integrata = "<<(double)m_nFittedTracks/m_nMCParticles);
1065 
1066  TH1F* h_eff_theta = createHistogramsRatio("hefftheta", "efficiency VS #theta, normalized to MCParticles", m_h3_TracksPerMCParticle,
1067  m_h3_MCParticle, true, 1);
1068  histoList->Add(h_eff_theta);
1069 
1070  TH1F* h_eff_phi = createHistogramsRatio("heffphi", "efficiency VS #phi, normalized to MCParticles", m_h3_TracksPerMCParticle,
1071  m_h3_MCParticle, true, 2);
1072  histoList->Add(h_eff_phi);
1073 
1074  //normalized to MCRecoTracks
1075  TH1F* h_effMCRT_pt = createHistogramsRatio("heffMCRTpt", "efficiency VS pt, normalized to MCRecoTrack", m_h3_TracksPerMCRecoTrack,
1076  m_h3_MCRecoTrack, true, 0);
1077  histoList->Add(h_effMCRT_pt);
1078 
1079  TH1F* h_effMCRT_theta = createHistogramsRatio("heffMCRTtheta", "efficiency VS #theta, normalized to MCRecoTrack",
1081  histoList->Add(h_effMCRT_theta);
1082 
1083  TH1F* h_effMCRT_phi = createHistogramsRatio("heffMCRTphi", "efficiency VS #phi, normalized to MCRecoTrack",
1085  histoList->Add(h_effMCRT_phi);
1086 
1087  // plus
1088 
1089  //normalized to MCParticles
1090  TH1F* h_eff_pt_plus = createHistogramsRatio("heffpt_plus", "efficiency VS pt, normalized to positive MCParticles",
1092  histoList->Add(h_eff_pt_plus);
1093  // B2INFO(" efficiency in pt, NUM = "<<m_nFittedTracks<<", DEN = "<<m_nMCParticles<<", eff integrata = "<<(double)m_nFittedTracks/m_nMCParticles);
1094 
1095  TH1F* h_eff_theta_plus = createHistogramsRatio("hefftheta_plus", "efficiency VS #theta, normalized to positive MCParticles",
1097  histoList->Add(h_eff_theta_plus);
1098 
1099  TH1F* h_eff_phi_plus = createHistogramsRatio("heffphi_plus", "efficiency VS #phi, normalized to positive MCParticles",
1101  histoList->Add(h_eff_phi_plus);
1102 
1103  //normalized to MCRecoTracks
1104  TH1F* h_effMCRT_pt_plus = createHistogramsRatio("heffMCRTpt_plus", "efficiency VS pt, normalized to positive MCRecoTrack",
1106  histoList->Add(h_effMCRT_pt_plus);
1107 
1108  TH1F* h_effMCRT_theta_plus = createHistogramsRatio("heffMCRTtheta_plus", "efficiency VS #theta, normalized to positive MCRecoTrack",
1110  histoList->Add(h_effMCRT_theta_plus);
1111 
1112  TH1F* h_effMCRT_phi_plus = createHistogramsRatio("heffMCRTphi_plus", "efficiency VS #phi, normalized to positive MCRecoTrack",
1114  histoList->Add(h_effMCRT_phi_plus);
1115 
1116  // minus
1117 
1118  //normalized to MCParticles
1119  TH1F* h_eff_pt_minus = createHistogramsRatio("heffpt_minus", "efficiency VS pt, normalized to positive MCParticles",
1121  histoList->Add(h_eff_pt_minus);
1122  // B2INFO(" efficiency in pt, NUM = "<<m_nFittedTracks<<", DEN = "<<m_nMCParticles<<", eff integrata = "<<(double)m_nFittedTracks/m_nMCParticles);
1123 
1124  TH1F* h_eff_theta_minus = createHistogramsRatio("hefftheta_minus", "efficiency VS #theta, normalized to positive MCParticles",
1126  histoList->Add(h_eff_theta_minus);
1127 
1128  TH1F* h_eff_phi_minus = createHistogramsRatio("heffphi_minus", "efficiency VS #phi, normalized to positive MCParticles",
1130  histoList->Add(h_eff_phi_minus);
1131 
1132  //normalized to MCRecoTracks
1133  TH1F* h_effMCRT_pt_minus = createHistogramsRatio("heffMCRTpt_minus", "efficiency VS pt, normalized to positive MCRecoTrack",
1135  histoList->Add(h_effMCRT_pt_minus);
1136 
1137  TH1F* h_effMCRT_theta_minus = createHistogramsRatio("heffMCRTtheta_minus",
1138  "efficiency VS #theta, normalized to positive MCRecoTrack", m_h3_TracksPerMCRecoTrack_minus, m_h3_MCRecoTrack_minus, true, 1);
1139  histoList->Add(h_effMCRT_theta_minus);
1140 
1141  TH1F* h_effMCRT_phi_minus = createHistogramsRatio("heffMCRTphi_minus", "efficiency VS #phi, normalized to positive MCRecoTrack",
1143  histoList->Add(h_effMCRT_phi_minus);
1144 
1145  //pattern recognition efficiency
1146  TH1F* h_effPR = createHistogramsRatio("heffPR", "PR efficiency VS VXD Layer, normalized to MCRecoTrack",
1148  histoList->Add(h_effPR);
1149 
1150  //tracks used in the fit
1151  TH1F* h_effVXDHitFit = createHistogramsRatio("heffVXDHitFit",
1152  "weighted hits used in the fit VS VXD Layer, normalized to hits form PR", m_h1_nVXDhitsWeighted, m_h1_nVXDhitsPR, true, 0);
1153  histoList->Add(h_effVXDHitFit);
1154 
1155  TH1F* h_effCDCHitFit = createHistogramsRatio("heffCDCHitFit",
1156  "weighted hits used in the fit VS CDC Layer, normalized to hits form PR", m_h1_nCDChitsWeighted, m_h1_nCDChitsPR, true, 0);
1157  histoList->Add(h_effCDCHitFit);
1158 
1159 }
1160 
1161 
1162 
1163 
1165 {
1166 
1167  bool isChargedStable = Const::chargedStableSet.find(abs(the_mcParticle.getPDG())) != Const::invalidParticle;
1168 
1169  bool isPrimary = the_mcParticle.hasStatus(MCParticle::c_PrimaryParticle);
1170 
1171  return (isPrimary && isChargedStable);
1172 
1173 }
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:32
WireID getWireID() const
Getter for WireID object.
Definition: CDCRecoHit.h:49
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:470
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
Definition: Const.h:452
double getMass() const
Particle mass.
Definition: UnitConst.cc:323
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:499
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:561
bool hasLayer(const unsigned short layer) const
Getter for single layer.
unsigned short getNPXDHits() const
Get total number of hits in the PXD.
std::pair< const unsigned short, const unsigned short > getSVDLayer(const unsigned short layerId) const
Get the number of hits in a specific layer of the SVD.
This struct is used by the TrackingPerformanceEvaluation Module to save information of reconstructed ...
double getPx()
Getter for x component of momentum.
double getZ()
Getter for z component of vertex.
double getPt()
Getter for transverse momentum.
double getY()
Getter for y component of vertex.
double getCharge()
Getter for electric charge of particle.
double getPtheta()
Getter for theta of momentum vector.
double getZ0()
Getter for Z0.
double getX()
Getter for x component of vertex.
double getPy()
Getter for y component of momentum.
double getCotTheta()
Getter for Theta.
double getPhi()
Getter for Phi.
double getPz()
Getter for z component of momentum.
double getOmega()
Getter for Omega.
double getPphi()
Getter for phi of momentum vector.
double getD0()
Getter for D0.
double getP()
Getter for magnitut of momentum.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
bool hasSeenInDetector(Const::DetectorSet set) const
Return if the seen-in flag for a specific subdetector is set or not.
Definition: MCParticle.h:307
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition: MCParticle.h:129
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
Base class for Modules.
Definition: Module.h:72
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
PXDRecoHit - an extended form of PXDCluster containing geometry information.
Definition: PXDRecoHit.h:49
float getV() const
Get v coordinate.
Definition: PXDRecoHit.h:111
const PXDCluster * getCluster() const
Get pointer to the Cluster used when creating this RecoHit, can be NULL if created from something els...
Definition: PXDRecoHit.h:106
VxdID getSensorID() const
Get the compact ID.
Definition: PXDRecoHit.h:101
float getU() const
Get u coordinate.
Definition: PXDRecoHit.h:109
Class PXDTrueHit - Records of tracks that either enter or leave the sensitive volume.
Definition: PXDTrueHit.h:31
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.
TList * m_histoList_evtCharacterization
List of event-characterization histograms.
TList * m_histoList_fit
List of track-fit 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.
TList * m_histoList_others
List of other performance-evaluation histograms.
TList * m_histoList_pr
List of pattern-recognition 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 addPurityPlots(TList *graphList=nullptr, TH3F *h3_xPerMCParticle=nullptr, TH3F *h3_MCParticle=nullptr)
Create pt-, theta- and phi-purity 1D histograms and add them to the TList of 1D-histograms.
TList * m_histoList_firstHit
List of first-hit-position 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.
TH1F * createHistogramsRatio(const char *name, const char *title, TH1 *hNum, TH1 *hDen, bool isEffPlot, int axisRef)
Make a new 1D histogram from the ratio of two others and add it to the TList of 1D-histograms.
TFile * m_rootFilePtr
pointer at root file used for storing histograms
TList * m_histoList_efficiency
List of efficiency histograms.
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit2D.h:46
float getV() const
Get v coordinate.
Definition: SVDRecoHit2D.h:112
VxdID getSensorID() const
Get the compact ID.
Definition: SVDRecoHit2D.h:100
float getU() const
Get u coordinate.
Definition: SVDRecoHit2D.h:110
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:47
bool isU() const
Is the coordinate u or v?
Definition: SVDRecoHit.h:91
float getPosition() const
Get coordinate.
Definition: SVDRecoHit.h:94
VxdID getSensorID() const
Get the compact ID.
Definition: SVDRecoHit.h:82
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Values of the result of a track fit with a given particle hypothesis.
TMatrixDSym getCovariance5() const
Getter for covariance matrix of perigee parameters in matrix form.
double getPhi() const
Getter for phi0 with CDF naming convention.
short getChargeSign() const
Return track charge (1 or -1).
double getPValue() const
Getter for Chi2 Probability of the track fit.
double getCotTheta() const
Getter for tanLambda with CDF naming convention.
double getOmega() const
Getter for omega.
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
double getD0() const
Getter for d0.
TVector3 getPosition() const
Getter for vector of position at closest approach of track in r/phi projection.
Const::ParticleType getParticleType() const
Getter for ParticleType of the mass hypothesis of the track fit.
double getZ0() const
Getter for z0.
HitPatternCDC getHitPatternCDC() const
Getter for the hit pattern in the CDC;.
HitPatternVXD getHitPatternVXD() const
Getter for the hit pattern in the VXD;.
Class that bundles various TrackFitResults.
Definition: Track.h:25
const TrackFitResult * getTrackFitResult(const Const::ChargedStable &chargedStable) const
Access to TrackFitResults.
Definition: Track.cc:17
This module takes the MCParticles, the Tracks, the RecoTrack, and the MCRecoTracks input and produce ...
void addMoreEfficiencyPlots(TList *histoList)
add efficiency plots
TH1F * m_multiplicityMCRecoTracksPerRT
number of MCRecoTracks per RecoTracks
TH1F * m_multiplicityTracks
number of tracks per MCParticles
TH1F * m_multiplicityFittedTracks
number of fitted tracks per MCParticles
int m_ParticleHypothesis
Particle Hypothesis for the track fit (default: 211)
void event() override
This method is called for each event.
TH1F * m_multiplicityMCRecoTracks
number of MCRecoTracks per MCParticles
void endRun() override
This method is called if the current run ends.
TH1F * m_multiplicityRecoTracksPerMCRT
number of RecoTracks per MCRecoTracks
void terminate() override
This method is called at the end of the event processing.
TH1F * m_multiplicityMCParticlesPerTrack
number of MCParticles per fitted Track
bool isTraceable(const MCParticle &the_mcParticle)
is traceable
void beginRun() override
Called when entering a new run.
void fillTrackParams1DHistograms(const TrackFitResult *fitResult, MCParticleInfo mcParticleInfo)
fills err, resid and pull TH1F for each of the 5 track parameters
void addMoreInefficiencyPlots(TList *histoList)
add inefficiency plots
std::string m_MCParticlesName
MCParticle StoreArray name.
TH1F * m_h1_r_res
R residual (in cylindrical coordinates)
TH1F * m_multiplicityRecoTracks
number of recoTracks per MCParticles
void fillTrackErrParams2DHistograms(const TrackFitResult *fitResult)
fills TH2F
std::string m_MCRecoTracksName
MCRecoTrack StoreArray name.
TH1F * m_multiplicityFittedTracksPerMCRT
number of fitted tracks per MCRecoTrack
static const double T
[tesla]
Definition: Unit.h:120
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:66
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:213
Base class to provide Sensor Information for PXD and SVD.
TVector3 pointToGlobal(const TVector3 &local, bool reco=false) const
Convert a point from local to global coordinates.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
Class to identify a wire inside the CDC.
Definition: WireID.h:34
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:24
Contains the measurement and covariance in raw detector coordinates.
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
std::vector< double > getWeights() const
Get weights of measurements.
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
KalmanFitterInfo * getKalmanFitterInfo(const AbsTrackRep *rep=nullptr) const
Helper to avoid casting.
Definition: TrackPoint.cc:180
#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.
Abstract base class for different kinds of events.