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(),
37
38 // N1 Hypothesis
39 n1_tree(0),
41 n1_iRun(0),
42 n1_iEvent(0),
43
44 // Shower
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),
76 n2_iRun(0),
77 n2_iEvent(0),
78
79 // Shower
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
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 B2DEBUG(1, " ++++++++++++++ ECLChargedPIDDataAnalysisModule");
210
211 // Showers
213 n1_eclShowerEnergy->clear();
214 n1_eclShowerTheta->clear();
215 n1_eclShowerPhi->clear();
216 n1_eclShowerR->clear();
220
221 // MC
222 n1_mcMultip = 0;
223 n1_mcPdg->clear();
224 n1_mcMothPdg->clear();
225 n1_mcEnergy->clear();
226 n1_mcP->clear();
227 n1_mcTheta->clear();
228 n1_mcPhi->clear();
229
230 // Tracks
231 n1_trkMultip = 0;
232 n1_trkPdg->clear();
233 n1_trkCharge->clear();
234 n1_trkP->clear();
235 n1_trkTheta->clear();
236 n1_trkPhi->clear();
237
238 n1_eclEoP->clear();
239
240 // Showers
242 n2_eclShowerEnergy->clear();
243 n2_eclShowerTheta->clear();
244 n2_eclShowerPhi->clear();
245 n2_eclShowerR->clear();
249
250 // MC
251 n2_mcMultip = 0;
252 n2_mcPdg->clear();
253 n2_mcMothPdg->clear();
254 n2_mcEnergy->clear();
255 n2_mcP->clear();
256 n2_mcTheta->clear();
257 n2_mcPhi->clear();
258
259 // Tracks
260 n2_trkMultip = 0;
261 n2_trkPdg->clear();
262 n2_trkCharge->clear();
263 n2_trkP->clear();
264 n2_trkTheta->clear();
265 n2_trkPhi->clear();
266
267 n2_eclEoP->clear();
268
269 if (m_EventMetaData) {
270 n1_iExperiment = m_EventMetaData->getExperiment();
271 n1_iRun = m_EventMetaData->getRun();
272 n1_iEvent = m_EventMetaData->getEvent();
273 n2_iExperiment = m_EventMetaData->getExperiment();
274 n2_iRun = m_EventMetaData->getRun();
275 n2_iEvent = m_EventMetaData->getEvent();
276 } else {
277 n1_iExperiment = -1;
278 n1_iRun = -1;
279 n1_iEvent = -1;
280 n2_iExperiment = -1;
281 n2_iRun = -1;
282 n2_iEvent = -1;
283 }
284
285 // get the matched MC particle
286 for (const MCParticle& imcpart : m_mcParticles) {
287 if (!imcpart.hasStatus(MCParticle::c_PrimaryParticle)) continue; // only check primaries
288 if (imcpart.hasStatus(MCParticle::c_Initial)) continue; // ignore initial particles
289 if (imcpart.hasStatus(MCParticle::c_IsVirtual)) continue; // ignore virtual particles
290
291 n1_mcMultip++;
292 n2_mcMultip++;
293
294 // get mc particle kinematics
295 n1_mcPdg->push_back(imcpart.getPDG());
296 if (imcpart.getMother() != nullptr) n1_mcMothPdg->push_back(imcpart.getMother()->getPDG());
297 else n1_mcMothPdg->push_back(-999);
298 n1_mcEnergy->push_back(imcpart.getEnergy());
299 n1_mcP->push_back(imcpart.getMomentum().R());
300 n1_mcTheta->push_back(imcpart.getMomentum().Theta());
301 n1_mcPhi->push_back(imcpart.getMomentum().Phi());
302
303 n2_mcPdg->push_back(imcpart.getPDG());
304 if (imcpart.getMother() != nullptr) n2_mcMothPdg->push_back(imcpart.getMother()->getPDG());
305 else n2_mcMothPdg->push_back(-999);
306 n2_mcEnergy->push_back(imcpart.getEnergy());
307 n2_mcP->push_back(imcpart.getMomentum().R());
308 n2_mcTheta->push_back(imcpart.getMomentum().Theta());
309 n2_mcPhi->push_back(imcpart.getMomentum().Phi());
310
311 // loop over all matched tracks to find index of max momentum
312 int index = 0;
313 int index_max_mom = -1;
314 double max_mom = -1;
315 for (const auto& itrk : imcpart.getRelationsFrom<Track>()) {
316 // get the track fit results
317 const TrackFitResult* atrkF = itrk.getTrackFitResult(Const::pion);
318 if (atrkF == nullptr) continue; //go to next track if no fit result
319 if (atrkF->getMomentum().R() > max_mom) {
320 max_mom = atrkF->getMomentum().R();
321 index_max_mom = index;
322 }
323 index++;
324 }
325 if (index_max_mom == -1) continue; // go to next mc part if no track found
326
327 // get the track w/ max momentum
328 const auto itrack = imcpart.getRelationsFrom<Track>()[index_max_mom];
329 // get the track fit results
330 const TrackFitResult* atrkF = itrack->getTrackFitResult(Const::pion);
331
332 n1_trkMultip++;
333 n2_trkMultip++;
334
335 // get trk kinematics
336 n1_trkPdg->push_back(atrkF->getParticleType().getPDGCode());
337 n1_trkCharge->push_back(atrkF->getChargeSign());
338 n1_trkP->push_back(atrkF->getMomentum().R());
339 n1_trkTheta->push_back(atrkF->getMomentum().Theta());
340 n1_trkPhi->push_back(atrkF->getMomentum().Phi());
341
342 n2_trkPdg->push_back(atrkF->getParticleType().getPDGCode());
343 n2_trkCharge->push_back(atrkF->getChargeSign());
344 n2_trkP->push_back(atrkF->getMomentum().R());
345 n2_trkTheta->push_back(atrkF->getMomentum().Theta());
346 n2_trkPhi->push_back(atrkF->getMomentum().Phi());
347
348 // loop over all matched ECLShowers (N1,N2) to find index of max energy
349 int jndex1 = -1;
350 int jndex1_max_e = -1;
351 double max_e1 = -1;
352 for (const auto& i1sh : itrack->getRelationsTo<ECLShower>()) {
353 ++jndex1;
354 // use HypoID 5 (N1 Photon hypothesis)
355 if (i1sh.getHypothesisId() != 5) continue;
356 // look only at showers passing the timing selection
357 if (abs(i1sh.getTime()) > i1sh.getDeltaTime99()) continue;
358 if (i1sh.getEnergy() > max_e1) {
359 max_e1 = i1sh.getEnergy();
360 jndex1_max_e = jndex1;
361 }
362 }
363 int jndex2 = -1;
364 int jndex2_max_e = -1;
365 double max_e2 = -1;
366 for (const auto& i2sh : itrack->getRelationsTo<ECLShower>()) {
367 ++jndex2;
368 // use Hypo ID 6 (N2 neutral hadron hypothesis)
369 if (i2sh.getHypothesisId() != 6) continue;
370 // look only at showers passing the timing selection
371 if (abs(i2sh.getTime()) > i2sh.getDeltaTime99()) continue;
372 if (i2sh.getEnergy() > max_e2) {
373 max_e2 = i2sh.getEnergy();
374 jndex2_max_e = jndex2;
375 }
376 }
377
378 // get the N1, N2 shower w/ max energy
379 if (jndex1_max_e != -1) {
380 const auto i1shower = itrack->getRelationsTo<ECLShower>()[jndex1_max_e];
381 // get shower kinematics
382 n1_eclShowerEnergy->push_back(i1shower->getEnergy());
383 n1_eclShowerTheta->push_back(i1shower->getTheta());
384 n1_eclShowerPhi->push_back(i1shower->getPhi());
385 n1_eclShowerR->push_back(i1shower->getR());
386 n1_eclShowerHypothesisId->push_back(i1shower->getHypothesisId());
387 // get shower Zernike moments
388 n1_eclShowerAbsZernike40->push_back(i1shower->getAbsZernikeMoment(4, 0));
389 n1_eclShowerAbsZernike51->push_back(i1shower->getAbsZernikeMoment(5, 1));
390 // get E/p
391 n1_eclEoP->push_back((i1shower->getEnergy()) / (atrkF->getMomentum().R()));
393 }
394 if (jndex2_max_e != -1) {
395 const auto i2shower = itrack->getRelationsTo<ECLShower>()[jndex2_max_e];
396 // get shower kinematics
397 n2_eclShowerEnergy->push_back(i2shower->getEnergy());
398 n2_eclShowerTheta->push_back(i2shower->getTheta());
399 n2_eclShowerPhi->push_back(i2shower->getPhi());
400 n2_eclShowerR->push_back(i2shower->getR());
401 n2_eclShowerHypothesisId->push_back(i2shower->getHypothesisId());
402 // get shower Zernike moments
403 n2_eclShowerAbsZernike40->push_back(i2shower->getAbsZernikeMoment(4, 0));
404 n2_eclShowerAbsZernike51->push_back(i2shower->getAbsZernikeMoment(5, 1));
405 // get E/p
406 n2_eclEoP->push_back((i2shower->getEnergy()) / (atrkF->getMomentum().R()));
408 }
409 }
410
411 n1_tree->Fill();
412 n2_tree->Fill();
413
414}
415
417{
418 if (m_rootFilePtr != nullptr) {
419 m_rootFilePtr->cd();
420 n1_tree->Write();
421 n2_tree->Write();
422 }
423
424}
425
426
static const ChargedStable pion
charged pion particle
Definition Const.h:662
virtual const char * eclShowerArrayName() const
Default name ECLShower.
std::vector< double > * n1_trkPhi
Track azimuthal direction.
StoreArray< ECLShower > m_eclShowers
Store array: ECLShower.
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.
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.
std::vector< double > * n2_eclEoP
ECL Shower Energy on Track Momentum.
virtual ~ECLChargedPIDDataAnalysisModule() override
Destructor of the module.
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.
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.
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.
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
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.