Belle II Software development
TOPNtupleModule.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// Own header.
10#include <top/modules/TOPNtuple/TOPNtupleModule.h>
11
12// TOP headers.
13#include <top/geometry/TOPGeometryPar.h>
14#include <top/reconstruction_cpp/TOPRecoManager.h>
15
16// framework - DataStore
17#include <framework/datastore/StoreArray.h>
18#include <framework/datastore/StoreObjPtr.h>
19
20// framework aux
21#include <framework/gearbox/Const.h>
22#include <framework/logging/Logger.h>
23
24// DataStore classes
25#include <framework/dataobjects/EventMetaData.h>
26#include <framework/dataobjects/MCInitialParticles.h>
27#include <mdst/dataobjects/Track.h>
28#include <mdst/dataobjects/MCParticle.h>
29#include <top/dataobjects/TOPLikelihood.h>
30#include <top/dataobjects/TOPBarHit.h>
31#include <top/dataobjects/TOPDigit.h>
32#include <tracking/dataobjects/ExtHit.h>
33
34// ROOT
35#include <TDirectory.h>
36
37using namespace std;
38
39namespace Belle2 {
44
45 using namespace TOP;
46
47 //-----------------------------------------------------------------
49 //-----------------------------------------------------------------
50
51 REG_MODULE(TOPNtuple);
52
53 //-----------------------------------------------------------------
54 // Implementation
55 //-----------------------------------------------------------------
56
58 {
59 // set module description
60 setDescription("Writes ntuple of TOPLikelihoods with tracking info into a root file");
61
62 // Add parameters
63 addParam("outputFileName", m_outputFileName, "Output file name",
64 string("TOPNtuple.root"));
65
66 }
67
69 {
70 TDirectory::TContext context;
71 m_file = TFile::Open(m_outputFileName.c_str(), "RECREATE");
72 if (m_file->IsZombie()) {
73 B2FATAL("Couldn't open file '" << m_outputFileName << "' for writing!");
74 return;
75 }
76
77 m_tree = new TTree("top", "TOP validation ntuple");
78
79 m_tree->Branch("evt", &m_top.evt, "evt/I");
80 m_tree->Branch("run", &m_top.run, "run/I");
81
82 m_tree->Branch("p", &m_top.p, "p/F");
83 m_tree->Branch("cth", &m_top.cth, "cth/F");
84 m_tree->Branch("phi", &m_top.phi, "phi/F");
85 m_tree->Branch("pValue", &m_top.pValue, "pValue/F");
86
87 m_tree->Branch("PDG", &m_top.PDG, "PDG/I");
88 m_tree->Branch("motherPDG", &m_top.motherPDG, "motherPDG/I");
89 m_tree->Branch("primary", &m_top.primary, "primary/S");
90 m_tree->Branch("seen", &m_top.seen, "seen/S");
91 m_tree->Branch("rhoProd", &m_top.rhoProd, "rhoProd/F");
92 m_tree->Branch("zProd", &m_top.zProd, "zProd/F");
93 m_tree->Branch("phiProd", &m_top.phiProd, "phiProd/F");
94 m_tree->Branch("rhoDec", &m_top.rhoDec, "rhoDec/F");
95 m_tree->Branch("zDec", &m_top.zDec, "zDec/F");
96 m_tree->Branch("phiDec", &m_top.phiDec, "phiDec/F");
97 m_tree->Branch("yieldMC", &m_top.yieldMC, "yieldMC/I");
98
99 m_tree->Branch("numPhot", &m_top.numPhot, "numPhot/I");
100 m_tree->Branch("numBkg", &m_top.numBkg, "numBkg/F");
101 m_tree->Branch("moduleID", &m_top.moduleID, "moduleID/I");
102 m_tree->Branch("phot", &m_top.phot, "e/F:mu:pi:K:p:d");
103 m_tree->Branch("yield", &m_top.yield, "e/F:mu:pi:K:p:d");
104 m_tree->Branch("logL", &m_top.logL, "e/F:mu:pi:K:p:d");
105
106 m_tree->Branch("extHit", &m_top.extHit, "moduleID/I:PDG:x/F:y:z:p:theta:phi:time");
107 m_tree->Branch("barHit", &m_top.barHit, "moduleID/I:PDG:x/F:y:z:p:theta:phi:time");
108
109 StoreArray<Track> tracks;
110 tracks.isRequired();
111 StoreArray<ExtHit> extHits;
112 extHits.isRequired();
113 StoreArray<TOPLikelihood> likelihoods;
114 likelihoods.isRequired();
115 StoreArray<MCParticle> mcParticles;
116 mcParticles.isOptional();
117 StoreArray<TOPBarHit> barHits;
118 barHits.isOptional();
119 StoreObjPtr<MCInitialParticles> mcInitialParticles;
120 mcInitialParticles.isOptional();
121 }
122
124 {
125
126 StoreObjPtr<EventMetaData> evtMetaData;
127 StoreArray<Track> tracks;
128 StoreObjPtr<MCInitialParticles> mcInitialParticles;
129 double trueEventT0 = 0;
130 if (mcInitialParticles.isValid()) trueEventT0 = mcInitialParticles->getTime();
131
132 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
133
134 for (const auto& track : tracks) {
135 const auto* trackFit = track.getTrackFitResultWithClosestMass(Const::pion);
136 if (!trackFit) continue;
137 const TOPLikelihood* top = track.getRelated<TOPLikelihood>();
138 if (!top) continue;
139 if (top->getFlag() != 1) continue;
140
141 const ExtHit* extHit = top->getRelated<ExtHit>();
142 const TOPBarHit* barHit = top->getRelated<TOPBarHit>();
143 const MCParticle* mcParticle = track.getRelated<MCParticle>();
144 const MCParticle* mother = 0;
145 if (mcParticle) {
146 mother = mcParticle->getMother();
147 if (not barHit) { // Track MC matching probably done after TOPReconstructor so no relation from TOPLikelihood
148 const auto barHits = mcParticle->getRelationsWith<TOPBarHit>();
149 for (const auto& bHit : barHits) {
150 if (bHit.getModuleID() == extHit->getCopyID()) barHit = &bHit;
151 }
152 }
153 }
154
155 m_top.clear();
156
157 m_top.evt = evtMetaData->getEvent();
158 m_top.run = evtMetaData->getRun();
159
160 ROOT::Math::XYZVector mom = trackFit->getMomentum();
161 m_top.p = mom.R();
162 m_top.cth = cos(mom.Theta());
163 m_top.phi = mom.Phi();
164 m_top.pValue = trackFit->getPValue();
165
166 if (mcParticle) {
167 m_top.PDG = mcParticle->getPDG();
168 if (mother) m_top.motherPDG = mother->getPDG();
169 m_top.primary = mcParticle->getStatus(MCParticle::c_PrimaryParticle);
170 m_top.seen = mcParticle->hasSeenInDetector(Const::TOP);
171 ROOT::Math::XYZVector prodVertex = mcParticle->getProductionVertex();
172 m_top.rhoProd = prodVertex.Rho();
173 m_top.zProd = prodVertex.Z();
174 m_top.phiProd = prodVertex.Phi();
175 ROOT::Math::XYZVector decVertex = mcParticle->getDecayVertex();
176 m_top.rhoDec = decVertex.Rho();
177 m_top.zDec = decVertex.Z();
178 m_top.phiDec = decVertex.Phi();
179 const auto digits = mcParticle->getRelationsWith<TOPDigit>();
180 for (size_t i = 0; i < digits.size(); i++) {
181 double wt = digits.weight(i);
182 if (wt <= 0) continue; // photon not from this MC particle
183 const auto* digit = digits[i];
184 if (digit->getHitQuality() != TOPDigit::c_Good) continue;
185 if (digit->getModuleID() != top->getModuleID()) continue;
186 if (digit->getTime() < TOPRecoManager::getMinTime() or digit->getTime() > TOPRecoManager::getMaxTime()) continue;
187 m_top.yieldMC++;
188 }
189 }
190
191 m_top.numPhot = top->getNphot();
192 m_top.numBkg = top->getEstBkg();
193 m_top.moduleID = top->getModuleID();
194
195 m_top.phot.e = top->getEstPhot(Const::electron);
196 m_top.phot.mu = top->getEstPhot(Const::muon);
197 m_top.phot.pi = top->getEstPhot(Const::pion);
198 m_top.phot.K = top->getEstPhot(Const::kaon);
199 m_top.phot.p = top->getEstPhot(Const::proton);
200 m_top.phot.d = top->getEstPhot(Const::deuteron);
201
202 m_top.yield.e = top->getEffectiveSignalYield(Const::electron);
203 m_top.yield.mu = top->getEffectiveSignalYield(Const::muon);
204 m_top.yield.pi = top->getEffectiveSignalYield(Const::pion);
205 m_top.yield.K = top->getEffectiveSignalYield(Const::kaon);
206 m_top.yield.p = top->getEffectiveSignalYield(Const::proton);
207 m_top.yield.d = top->getEffectiveSignalYield(Const::deuteron);
208
209 m_top.logL.e = top->getLogL(Const::electron);
210 m_top.logL.mu = top->getLogL(Const::muon);
211 m_top.logL.pi = top->getLogL(Const::pion);
212 m_top.logL.K = top->getLogL(Const::kaon);
213 m_top.logL.p = top->getLogL(Const::proton);
214 m_top.logL.d = top->getLogL(Const::deuteron);
215
216 if (extHit) {
217 int moduleID = extHit->getCopyID();
218 auto position = static_cast<ROOT::Math::XYZPoint>(extHit->getPosition());
219 auto momentum = extHit->getMomentum();
220 if (geo->isModuleIDValid(moduleID)) {
221 const auto& module = geo->getModule(moduleID);
222 position = module.pointToLocal(position);
223 momentum = module.momentumToLocal(momentum);
224 }
225 m_top.extHit.moduleID = moduleID;
226 m_top.extHit.PDG = extHit->getPdgCode();
227 m_top.extHit.x = position.X();
228 m_top.extHit.y = position.Y();
229 m_top.extHit.z = position.Z();
230 m_top.extHit.p = momentum.R();
231 m_top.extHit.theta = momentum.Theta();
232 m_top.extHit.phi = momentum.Phi();
233 m_top.extHit.time = extHit->getTOF();
234 }
235
236 if (barHit) {
237 int moduleID = barHit->getModuleID();
238 auto position = barHit->getPosition();
239 auto momentum = barHit->getMomentum();
240 if (geo->isModuleIDValid(moduleID)) {
241 const auto& module = geo->getModule(moduleID);
242 position = module.pointToLocal(position);
243 momentum = module.momentumToLocal(momentum);
244 }
245 m_top.barHit.moduleID = moduleID;
246 m_top.barHit.PDG = barHit->getPDG();
247 m_top.barHit.x = position.X();
248 m_top.barHit.y = position.Y();
249 m_top.barHit.z = position.Z();
250 m_top.barHit.p = momentum.R();
251 m_top.barHit.theta = momentum.Theta();
252 m_top.barHit.phi = momentum.Phi();
253 m_top.barHit.time = barHit->getTime() - trueEventT0;
254 }
255
256 m_tree->Fill();
257 }
258
259 }
260
261
263 {
264 TDirectory::TContext context;
265 m_file->cd();
266 m_tree->Write();
267 m_file->Close();
268 }
269
271} // end Belle2 namespace
272
static const ChargedStable muon
muon particle
Definition Const.h:660
static const ChargedStable pion
charged pion particle
Definition Const.h:661
static const ChargedStable proton
proton particle
Definition Const.h:663
static const ChargedStable kaon
charged kaon particle
Definition Const.h:662
static const ChargedStable electron
electron particle
Definition Const.h:659
static const ChargedStable deuteron
deuteron particle
Definition Const.h:664
Store one Ext hit as a ROOT object.
Definition ExtHit.h:31
int getPdgCode() const
Get PDG code of this extrapolation's hypothesis.
Definition ExtHit.h:117
int getCopyID() const
Get detector-element ID of sensitive element within detector.
Definition ExtHit.h:125
ROOT::Math::XYZVector getMomentum() const
Get momentum at this extrapolation hit.
Definition ExtHit.h:151
ROOT::Math::XYZVector getPosition() const
Get position of this extrapolation hit.
Definition ExtHit.h:144
double getTOF() const
Get time of flight from the point of closest approach near the origin to this hit.
Definition ExtHit.h:136
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
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
Class to store track parameters of incoming MC particles relation to MCParticle filled in top/simulat...
Definition TOPBarHit.h:27
Class to store TOP digitized hits (output of TOPDigitizer or raw data unpacker) relations to TOPSimHi...
Definition TOPDigit.h:24
Class to store TOP log likelihoods (output of TOPReconstructor).
TTree * m_tree
TTree with TOPTree structure.
TOP::TOPTree m_top
ntuple structure
std::string m_outputFileName
output file name (root file)
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
static double getMaxTime()
Returns time window upper edge.
static double getMinTime()
Returns time window lower edge.
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
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual void terminate() override
Termination action.
Abstract base class for different kinds of events.
STL namespace.