Belle II Software development
ECLChargedPIDDataAnalysisModule.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 <iostream>
10#include <ecl/modules/eclChargedPIDDataAnalysisExpert/ECLChargedPIDDataAnalysisModule.h>
11#include <framework/datastore/RelationVector.h>
12#include <framework/logging/Logger.h>
13#include <framework/gearbox/Const.h>
14
15#include <mdst/dataobjects/MCParticle.h>
16#include <mdst/dataobjects/Track.h>
17#include <ecl/dataobjects/ECLShower.h>
18
19using namespace std;
20using namespace Belle2;
21
22//-----------------------------------------------------------------
23// Register the Module
24//-----------------------------------------------------------------
25
26REG_MODULE(ECLChargedPIDDataAnalysis);
27
28//-----------------------------------------------------------------
29// Implementation
30//-----------------------------------------------------------------
31
33 Module(),
34 m_rootFilePtr(0),
35 m_writeToRoot(1),
36 m_eclShowers(eclShowerArrayName()),
37
38 // N1 Hypothesis
39 n1_tree(0),
40 n1_iExperiment(0),
41 n1_iRun(0),
42 n1_iEvent(0),
43
44 // Shower
45 n1_eclShowerMultip(0),
46 n1_eclShowerEnergy(0),
47 n1_eclShowerTheta(0),
48 n1_eclShowerPhi(0),
49 n1_eclShowerR(0),
50 n1_eclShowerHypothesisId(0),
51 n1_eclShowerAbsZernike40(0),
52 n1_eclShowerAbsZernike51(0),
53
54 // MC
55 n1_mcMultip(0),
56 n1_mcPdg(0),
57 n1_mcMothPdg(0),
58 n1_mcEnergy(0),
59 n1_mcP(0),
60 n1_mcTheta(0),
61 n1_mcPhi(0),
62
63 // Tracks
64 n1_trkMultip(0),
65 n1_trkPdg(0),
66 n1_trkCharge(0),
67 n1_trkP(0),
68 n1_trkTheta(0),
69 n1_trkPhi(0),
70
71 n1_eclEoP(0),
72
73 // N2 Hypothesis
74 n2_tree(0),
75 n2_iExperiment(0),
76 n2_iRun(0),
77 n2_iEvent(0),
78
79 // Shower
80 n2_eclShowerMultip(0),
81 n2_eclShowerEnergy(0),
82 n2_eclShowerTheta(0),
83 n2_eclShowerPhi(0),
84 n2_eclShowerR(0),
85 n2_eclShowerHypothesisId(0),
86 n2_eclShowerAbsZernike40(0),
87 n2_eclShowerAbsZernike51(0),
88
89 // MC
90 n2_mcMultip(0),
91 n2_mcPdg(0),
92 n2_mcMothPdg(0),
93 n2_mcEnergy(0),
94 n2_mcP(0),
95 n2_mcTheta(0),
96 n2_mcPhi(0),
97
98 // Tracks
99 n2_trkMultip(0),
100 n2_trkPdg(0),
101 n2_trkCharge(0),
102 n2_trkP(0),
103 n2_trkTheta(0),
104 n2_trkPhi(0),
105
106 n2_eclEoP(0)
107{
108 // Set module properties
109 setDescription("This module produces an ntuple with ECL-related quantities starting from mdst");
110 addParam("writeToRoot", m_writeToRoot,
111 "set true if you want to save the information in a root file named by parameter 'rootFileName'",
112 bool(true));
113 addParam("rootFileName", m_rootFileName,
114 "fileName used for root file where info are saved. Will be ignored if parameter 'writeToRoot' is false (standard)",
115 string("eclChargedPID"));
116}
117
119{
120}
121
123{
124 B2INFO("[ECLChargedPIDDataAnalysis Module]: Starting initialization of ECLChargedPIDDataAnalysis Module.");
125
126 if (m_writeToRoot) {
127 m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
128 } else {
129 m_rootFilePtr = nullptr;
130 }
131 // initialize N1 tree
132 n1_tree = new TTree("n1_tree", "ECL Charged PID tree: N1 Hypothesis");
133
134 n1_tree->Branch("expNo", &n1_iExperiment, "expNo/I");
135 n1_tree->Branch("runNo", &n1_iRun, "runNo/I");
136 n1_tree->Branch("evtNo", &n1_iEvent, "evtNo/I");
137
138 // shower
139 n1_tree->Branch("eclShowerMultip", &n1_eclShowerMultip, "eclShowerMultip/I");
140 n1_tree->Branch("eclShowerEnergy", "std::vector<double>", &n1_eclShowerEnergy);
141 n1_tree->Branch("eclShowerTheta", "std::vector<double>", &n1_eclShowerTheta);
142 n1_tree->Branch("eclShowerPhi", "std::vector<double>", &n1_eclShowerPhi);
143 n1_tree->Branch("eclShowerR", "std::vector<double>", &n1_eclShowerR);
144 n1_tree->Branch("eclShowerHypothesisId", "std::vector<int>", &n1_eclShowerHypothesisId);
145 n1_tree->Branch("eclShowerAbsZernike40", "std::vector<double>", &n1_eclShowerAbsZernike40);
146 n1_tree->Branch("eclShowerAbsZernike51", "std::vector<double>", &n1_eclShowerAbsZernike51);
147
148 // MC particle
149 n1_tree->Branch("mcMultip", &n1_mcMultip, "mcMultip/I");
150 n1_tree->Branch("mcPdg", "std::vector<int>", &n1_mcPdg);
151 n1_tree->Branch("mcMothPdg", "std::vector<int>", &n1_mcMothPdg);
152 n1_tree->Branch("mcEnergy", "std::vector<double>", &n1_mcEnergy);
153 n1_tree->Branch("mcP", "std::vector<double>", &n1_mcP);
154 n1_tree->Branch("mcTheta", "std::vector<double>", &n1_mcTheta);
155 n1_tree->Branch("mcPhi", "std::vector<double>", &n1_mcPhi);
156
157 // tracks
158 n1_tree->Branch("trkMultip", &n1_trkMultip, "trkMulti/I");
159 n1_tree->Branch("trkPdg", "std::vector<int>", &n1_trkPdg);
160 n1_tree->Branch("trkCharge", "std::vector<int>", &n1_trkCharge);
161 n1_tree->Branch("trkP", "std::vector<double>", &n1_trkP);
162 n1_tree->Branch("trkTheta", "std::vector<double>", &n1_trkTheta);
163 n1_tree->Branch("trkPhi", "std::vector<double>", &n1_trkPhi);
164
165 n1_tree->Branch("eclEoP", "std::vector<double>", &n1_eclEoP);
166
167 // initialize N2 tree
168 n2_tree = new TTree("n2_tree", "ECL Charged PID tree: N2 Hypothesis");
169
170 n2_tree->Branch("expNo", &n2_iExperiment, "expNo/I");
171 n2_tree->Branch("runNo", &n2_iRun, "runNo/I");
172 n2_tree->Branch("evtNo", &n2_iEvent, "evtNo/I");
173
174 // shower
175 n2_tree->Branch("eclShowerMultip", &n2_eclShowerMultip, "eclShowerMultip/I");
176 n2_tree->Branch("eclShowerEnergy", "std::vector<double>", &n2_eclShowerEnergy);
177 n2_tree->Branch("eclShowerTheta", "std::vector<double>", &n2_eclShowerTheta);
178 n2_tree->Branch("eclShowerPhi", "std::vector<double>", &n2_eclShowerPhi);
179 n2_tree->Branch("eclShowerR", "std::vector<double>", &n2_eclShowerR);
180 n2_tree->Branch("eclShowerHypothesisId", "std::vector<int>", &n2_eclShowerHypothesisId);
181 n2_tree->Branch("eclShowerAbsZernike40", "std::vector<double>", &n2_eclShowerAbsZernike40);
182 n2_tree->Branch("eclShowerAbsZernike51", "std::vector<double>", &n2_eclShowerAbsZernike51);
183
184 // MC particle
185 n2_tree->Branch("mcMultip", &n2_mcMultip, "mcMultip/I");
186 n2_tree->Branch("mcPdg", "std::vector<int>", &n2_mcPdg);
187 n2_tree->Branch("mcMothPdg", "std::vector<int>", &n2_mcMothPdg);
188 n2_tree->Branch("mcEnergy", "std::vector<double>", &n2_mcEnergy);
189 n2_tree->Branch("mcP", "std::vector<double>", &n2_mcP);
190 n2_tree->Branch("mcTheta", "std::vector<double>", &n2_mcTheta);
191 n2_tree->Branch("mcPhi", "std::vector<double>", &n2_mcPhi);
192
193 // tracks
194 n2_tree->Branch("trkMultip", &n2_trkMultip, "trkMulti/I");
195 n2_tree->Branch("trkPdg", "std::vector<int>", &n2_trkPdg);
196 n2_tree->Branch("trkCharge", "std::vector<int>", &n2_trkCharge);
197 n2_tree->Branch("trkP", "std::vector<double>", &n2_trkP);
198 n2_tree->Branch("trkTheta", "std::vector<double>", &n2_trkTheta);
199 n2_tree->Branch("trkPhi", "std::vector<double>", &n2_trkPhi);
200
201 n2_tree->Branch("eclEoP", "std::vector<double>", &n2_eclEoP);
202
203 B2INFO("[ECLChargedPIDDataAnalysis Module]: Initialization of ECLChargedPIDDataAnalysis Module completed.");
204}
205
207{
208}
209
211{
212
213 B2DEBUG(1, " ++++++++++++++ ECLChargedPIDDataAnalysisModule");
214
215 // Showers
217 n1_eclShowerEnergy->clear();
218 n1_eclShowerTheta->clear();
219 n1_eclShowerPhi->clear();
220 n1_eclShowerR->clear();
224
225 // MC
226 n1_mcMultip = 0;
227 n1_mcPdg->clear();
228 n1_mcMothPdg->clear();
229 n1_mcEnergy->clear();
230 n1_mcP->clear();
231 n1_mcTheta->clear();
232 n1_mcPhi->clear();
233
234 // Tracks
235 n1_trkMultip = 0;
236 n1_trkPdg->clear();
237 n1_trkCharge->clear();
238 n1_trkP->clear();
239 n1_trkTheta->clear();
240 n1_trkPhi->clear();
241
242 n1_eclEoP->clear();
243
244 // Showers
246 n2_eclShowerEnergy->clear();
247 n2_eclShowerTheta->clear();
248 n2_eclShowerPhi->clear();
249 n2_eclShowerR->clear();
253
254 // MC
255 n2_mcMultip = 0;
256 n2_mcPdg->clear();
257 n2_mcMothPdg->clear();
258 n2_mcEnergy->clear();
259 n2_mcP->clear();
260 n2_mcTheta->clear();
261 n2_mcPhi->clear();
262
263 // Tracks
264 n2_trkMultip = 0;
265 n2_trkPdg->clear();
266 n2_trkCharge->clear();
267 n2_trkP->clear();
268 n2_trkTheta->clear();
269 n2_trkPhi->clear();
270
271 n2_eclEoP->clear();
272
273 if (m_EventMetaData) {
274 n1_iExperiment = m_EventMetaData->getExperiment();
275 n1_iRun = m_EventMetaData->getRun();
276 n1_iEvent = m_EventMetaData->getEvent();
277 n2_iExperiment = m_EventMetaData->getExperiment();
278 n2_iRun = m_EventMetaData->getRun();
279 n2_iEvent = m_EventMetaData->getEvent();
280 } else {
281 n1_iExperiment = -1;
282 n1_iRun = -1;
283 n1_iEvent = -1;
284 n2_iExperiment = -1;
285 n2_iRun = -1;
286 n2_iEvent = -1;
287 }
288
289 // get the matched MC particle
290 for (const MCParticle& imcpart : m_mcParticles) {
291 if (!imcpart.hasStatus(MCParticle::c_PrimaryParticle)) continue; // only check primaries
292 if (imcpart.hasStatus(MCParticle::c_Initial)) continue; // ignore initial particles
293 if (imcpart.hasStatus(MCParticle::c_IsVirtual)) continue; // ignore virtual particles
294
295 n1_mcMultip++;
296 n2_mcMultip++;
297
298 // get mc particle kinematics
299 n1_mcPdg->push_back(imcpart.getPDG());
300 if (imcpart.getMother() != nullptr) n1_mcMothPdg->push_back(imcpart.getMother()->getPDG());
301 else n1_mcMothPdg->push_back(-999);
302 n1_mcEnergy->push_back(imcpart.getEnergy());
303 n1_mcP->push_back(imcpart.getMomentum().R());
304 n1_mcTheta->push_back(imcpart.getMomentum().Theta());
305 n1_mcPhi->push_back(imcpart.getMomentum().Phi());
306
307 n2_mcPdg->push_back(imcpart.getPDG());
308 if (imcpart.getMother() != nullptr) n2_mcMothPdg->push_back(imcpart.getMother()->getPDG());
309 else n2_mcMothPdg->push_back(-999);
310 n2_mcEnergy->push_back(imcpart.getEnergy());
311 n2_mcP->push_back(imcpart.getMomentum().R());
312 n2_mcTheta->push_back(imcpart.getMomentum().Theta());
313 n2_mcPhi->push_back(imcpart.getMomentum().Phi());
314
315 // loop over all matched tracks to find index of max momentum
316 int index = 0;
317 int index_max_mom = -1;
318 double max_mom = -1;
319 for (const auto& itrk : imcpart.getRelationsFrom<Track>()) {
320 // get the track fit results
321 const TrackFitResult* atrkF = itrk.getTrackFitResult(Const::pion);
322 if (atrkF == nullptr) continue; //go to next track if no fit result
323 if (atrkF->getMomentum().R() > max_mom) {
324 max_mom = atrkF->getMomentum().R();
325 index_max_mom = index;
326 }
327 index++;
328 }
329 if (index_max_mom == -1) continue; // go to next mc part if no track found
330
331 // get the track w/ max momentum
332 const auto itrack = imcpart.getRelationsFrom<Track>()[index_max_mom];
333 // get the track fit results
334 const TrackFitResult* atrkF = itrack->getTrackFitResult(Const::pion);
335
336 n1_trkMultip++;
337 n2_trkMultip++;
338
339 // get trk kinematics
340 n1_trkPdg->push_back(atrkF->getParticleType().getPDGCode());
341 n1_trkCharge->push_back(atrkF->getChargeSign());
342 n1_trkP->push_back(atrkF->getMomentum().R());
343 n1_trkTheta->push_back(atrkF->getMomentum().Theta());
344 n1_trkPhi->push_back(atrkF->getMomentum().Phi());
345
346 n2_trkPdg->push_back(atrkF->getParticleType().getPDGCode());
347 n2_trkCharge->push_back(atrkF->getChargeSign());
348 n2_trkP->push_back(atrkF->getMomentum().R());
349 n2_trkTheta->push_back(atrkF->getMomentum().Theta());
350 n2_trkPhi->push_back(atrkF->getMomentum().Phi());
351
352 // loop over all matched ECLShowers (N1,N2) to find index of max energy
353 int jndex1 = -1;
354 int jndex1_max_e = -1;
355 double max_e1 = -1;
356 for (const auto& i1sh : itrack->getRelationsTo<ECLShower>()) {
357 ++jndex1;
358 // use HypoID 5 (N1 Photon hypothesis)
359 if (i1sh.getHypothesisId() != 5) continue;
360 // look only at showers passing the timing selection
361 if (abs(i1sh.getTime()) > i1sh.getDeltaTime99()) continue;
362 if (i1sh.getEnergy() > max_e1) {
363 max_e1 = i1sh.getEnergy();
364 jndex1_max_e = jndex1;
365 }
366 }
367 int jndex2 = -1;
368 int jndex2_max_e = -1;
369 double max_e2 = -1;
370 for (const auto& i2sh : itrack->getRelationsTo<ECLShower>()) {
371 ++jndex2;
372 // use Hypo ID 6 (N2 neutral hadron hypothesis)
373 if (i2sh.getHypothesisId() != 6) continue;
374 // look only at showers passing the timing selection
375 if (abs(i2sh.getTime()) > i2sh.getDeltaTime99()) continue;
376 if (i2sh.getEnergy() > max_e2) {
377 max_e2 = i2sh.getEnergy();
378 jndex2_max_e = jndex2;
379 }
380 }
381
382 // get the N1, N2 shower w/ max energy
383 if (jndex1_max_e != -1) {
384 const auto i1shower = itrack->getRelationsTo<ECLShower>()[jndex1_max_e];
385 // get shower kinematics
386 n1_eclShowerEnergy->push_back(i1shower->getEnergy());
387 n1_eclShowerTheta->push_back(i1shower->getTheta());
388 n1_eclShowerPhi->push_back(i1shower->getPhi());
389 n1_eclShowerR->push_back(i1shower->getR());
390 n1_eclShowerHypothesisId->push_back(i1shower->getHypothesisId());
391 // get shower Zernike moments
392 n1_eclShowerAbsZernike40->push_back(i1shower->getAbsZernikeMoment(4, 0));
393 n1_eclShowerAbsZernike51->push_back(i1shower->getAbsZernikeMoment(5, 1));
394 // get E/p
395 n1_eclEoP->push_back((i1shower->getEnergy()) / (atrkF->getMomentum().R()));
397 }
398 if (jndex2_max_e != -1) {
399 const auto i2shower = itrack->getRelationsTo<ECLShower>()[jndex2_max_e];
400 // get shower kinematics
401 n2_eclShowerEnergy->push_back(i2shower->getEnergy());
402 n2_eclShowerTheta->push_back(i2shower->getTheta());
403 n2_eclShowerPhi->push_back(i2shower->getPhi());
404 n2_eclShowerR->push_back(i2shower->getR());
405 n2_eclShowerHypothesisId->push_back(i2shower->getHypothesisId());
406 // get shower Zernike moments
407 n2_eclShowerAbsZernike40->push_back(i2shower->getAbsZernikeMoment(4, 0));
408 n2_eclShowerAbsZernike51->push_back(i2shower->getAbsZernikeMoment(5, 1));
409 // get E/p
410 n2_eclEoP->push_back((i2shower->getEnergy()) / (atrkF->getMomentum().R()));
412 }
413 }
414
415 n1_tree->Fill();
416 n2_tree->Fill();
417
418}
419
421{
422}
423
425{
426 if (m_rootFilePtr != nullptr) {
427 m_rootFilePtr->cd();
428 n1_tree->Write();
429 n2_tree->Write();
430 }
431
432}
433
434
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
std::vector< double > * n1_trkPhi
Track azimuthal direction.
bool m_writeToRoot
if true, a rootFile named by m_rootFileName will be filled with info
std::vector< double > * n2_eclShowerAbsZernike40
Shower Zernike40 Moment.
virtual void initialize() override
Initializes the Module.
int n1_eclShowerMultip
Number of ECLShowers per event.
virtual void event() override
Called once for each event.
std::vector< int > * n2_mcMothPdg
MCParticle mother particle PDG code.
std::vector< double > * n2_mcP
MCParticle momentum.
std::vector< double > * n2_eclShowerEnergy
Shower Energy.
TTree * n2_tree
Root tree and file for saving the output.
virtual void endRun() override
Called once when a run ends.
std::vector< int > * n1_eclShowerHypothesisId
Shower Particle Hypothesis ID.
int n2_eclShowerMultip
Number of ECLShowers per event.
std::vector< double > * n1_mcP
MCParticle momentum.
virtual void terminate() override
Termination action.
std::vector< double > * n2_mcTheta
MCParticle Theta.
TTree * n1_tree
Root tree and file for saving the output.
std::vector< double > * n1_eclShowerEnergy
Shower Energy.
std::vector< double > * n1_mcPhi
MCParticle Phi.
std::vector< double > * n1_eclShowerAbsZernike51
Shower Zernike51 Moment.
std::vector< int > * n1_mcMothPdg
MCParticle mother particle PDG code.
virtual void beginRun() override
Called once before a new run begins.
std::vector< double > * n2_eclEoP
ECL Shower Energy on Track Momentum.
std::vector< double > * n2_trkPhi
Track azimuthal direction.
std::vector< double > * n1_trkTheta
Track polar direction.
std::vector< double > * n1_mcEnergy
MCParticle energyx.
std::vector< int > * n2_mcPdg
MCParticle PDG code.
std::vector< double > * n1_eclShowerAbsZernike40
Shower Zernike40 Moment.
std::vector< double > * n1_eclEoP
ECL Shower Energy on Track Momentum.
std::vector< int > * n1_mcPdg
MCParticle PDG code.
std::vector< double > * n2_eclShowerTheta
Shower Theta.
std::vector< double > * n2_eclShowerPhi
Shower Phi.
StoreArray< MCParticle > m_mcParticles
MCParticles StoreArray.
std::vector< double > * n2_trkTheta
Track polar direction.
std::vector< double > * n2_mcPhi
MCParticle Phi.
std::vector< double > * n1_eclShowerTheta
Shower Theta.
virtual ~ECLChargedPIDDataAnalysisModule()
Destructor of the module.
std::vector< double > * n2_trkP
Track momentum.
std::vector< double > * n1_trkP
Track momentum.
std::vector< double > * n2_eclShowerAbsZernike51
Shower Zernike51 Moment.
TFile * m_rootFilePtr
members of ECLReconstructor Module
std::vector< double > * n2_mcEnergy
MCParticle energyx.
StoreObjPtr< EventMetaData > m_EventMetaData
Event metadata.
std::vector< int > * n2_eclShowerHypothesisId
Shower Particle Hypothesis ID.
std::vector< double > * n1_mcTheta
MCParticle Theta.
std::vector< double > * n1_eclShowerPhi
Shower Phi.
Class to store ECL Showers.
Definition: ECLShower.h:30
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition: MCParticle.h:57
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
Definition: MCParticle.h:55
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Values of the result of a track fit with a given particle hypothesis.
ROOT::Math::XYZVector getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Class that bundles various TrackFitResults.
Definition: Track.h:25
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
Abstract base class for different kinds of events.
STL namespace.