Belle II Software development
StandardTrackingPerformanceModule.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/standardTrackingPerformance/StandardTrackingPerformanceModule.h>
10
11#include <framework/datastore/StoreObjPtr.h>
12#include <framework/dataobjects/EventMetaData.h>
13#include <framework/datastore/RelationVector.h>
14#include <framework/gearbox/Const.h>
15
16#include <tracking/dataobjects/RecoTrack.h>
17#include <genfit/TrackPoint.h>
18#include <genfit/KalmanFitterInfo.h>
19
20#include <pxd/reconstruction/PXDRecoHit.h>
21#include <svd/reconstruction/SVDRecoHit.h>
22#include <svd/reconstruction/SVDRecoHit2D.h>
23#include <cdc/dataobjects/CDCRecoHit.h>
24
25#include <root/TFile.h>
26#include <root/TTree.h>
27
28using namespace Belle2;
29
30//-----------------------------------------------------------------
31// Register the Module
32//-----------------------------------------------------------------
33REG_MODULE(StandardTrackingPerformance);
34
35StandardTrackingPerformanceModule::StandardTrackingPerformanceModule() :
36 Module(), m_outputFile(nullptr), m_dataTree(nullptr), m_trackProperties(-999), m_pValue(-999),
37 m_nGeneratedChargedStableMcParticles(-999), m_nReconstructedChargedStableTracks(-999),
38 m_nFittedChargedStabletracks(-999)
39{
40 setDescription("Module to test the tracking efficiency. Writes information about the tracks and MCParticles in a ROOT file.");
41 setPropertyFlags(c_ParallelProcessingCertified);
42
43 addParam("outputFileName", m_outputFileName, "Name of output root file.",
44 std::string("StandardTrackingPerformanceOutput.root"));
45 addParam("recoTracksStoreArrayName", m_recoTracksStoreArrayName, "Name of the RecoTracks StoreArray.",
46 std::string(""));
47 addParam("daughterPDGs", m_signalDaughterPDGs, "PDG codes of B daughters.",
48 std::vector<int>(0));
49}
50
52{
53 // MCParticles and Tracks needed for this module
55
56 m_outputFile = new TFile(m_outputFileName.c_str(), "RECREATE");
57 TDirectory* oldDir = gDirectory;
58 m_outputFile->cd();
59 m_dataTree = new TTree("data", "data");
60 oldDir->cd();
61
62 setupTree();
63}
64
66{
67 StoreObjPtr<EventMetaData> eventMetaData("EventMetaData", DataStore::c_Event);
68 unsigned long eventNumber = eventMetaData->getEvent();
69 unsigned long runNumber = eventMetaData->getRun();
70 unsigned long expNumber = eventMetaData->getExperiment();
71
72 B2DEBUG(29,
73 "Processes experiment " << expNumber << " run " << runNumber << " event " << eventNumber);
74
78
79 for (MCParticle& mcParticle : m_MCParticles) {
80 // check status of mcParticle
81 if (isPrimaryMcParticle(mcParticle) && isChargedStable(mcParticle) && mcParticle.hasStatus(MCParticle::c_StableInGenerator)) {
83
84 int pdgCode = mcParticle.getPDG();
85 B2DEBUG(29, "Primary MCParticle has PDG code " << pdgCode);
86
88
89 m_trackProperties.cosTheta_gen = cos(mcParticle.getMomentum().Theta());
90 m_trackProperties.ptot_gen = mcParticle.getMomentum().R();
91 m_trackProperties.pt_gen = mcParticle.getMomentum().Rho();
92 m_trackProperties.px_gen = mcParticle.getMomentum().X();
93 m_trackProperties.py_gen = mcParticle.getMomentum().Y();
94 m_trackProperties.pz_gen = mcParticle.getMomentum().Z();
95 m_trackProperties.x_gen = mcParticle.getVertex().X();
96 m_trackProperties.y_gen = mcParticle.getVertex().Y();
97 m_trackProperties.z_gen = mcParticle.getVertex().Z();
98
99
100 const RecoTrack* recoTrack = nullptr;
101 double maximumWeight = -2;
102 /*// MIMIK OLD MODULE, which took always the last one (which is probably a CDC track).
103 for(const Track& relatedTrack : mcParticle.getRelationsWith<Track>()) {
104 b2Track = &relatedTrack;
105 }*/
106 // find highest rated Track
107 const auto& relatedRecoTracks = mcParticle.getRelationsWith<RecoTrack>(m_recoTracksStoreArrayName);
108 for (unsigned int index = 0; index < relatedRecoTracks.size(); ++index) {
109 const RecoTrack* relatedRecoTrack = relatedRecoTracks.object(index);
110 const double weight = relatedRecoTracks.weight(index);
111
112 const unsigned int numberOfRelatedTracks = relatedRecoTrack->getRelationsWith<Track>().size();
113 B2ASSERT("B2Track <-> RecoTrack is not a 1:1 relation as expected!", numberOfRelatedTracks <= 1);
114 // use only the fitted reco tracks
115 if (numberOfRelatedTracks == 1) {
116 if (weight > maximumWeight) {
117 maximumWeight = weight;
118 recoTrack = relatedRecoTrack;
119 }
120 }
121 }
122
123 if (recoTrack) {
124 const Track* b2Track = recoTrack->getRelated<Track>();
126 B2ASSERT("Related Belle2 Track has no related track fit result for pion!", fitResult);
127
129 // write some data to the root tree
130 ROOT::Math::XYZVector mom = fitResult->getMomentum();
131 m_trackProperties.cosTheta = cos(mom.Theta());
132 m_trackProperties.ptot = mom.R();
133 m_trackProperties.pt = mom.Rho();
134 m_trackProperties.px = mom.X();
135 m_trackProperties.py = mom.Y();
136 m_trackProperties.pz = mom.Z();
137 m_trackProperties.x = fitResult->getPosition().X();
138 m_trackProperties.y = fitResult->getPosition().Y();
139 m_trackProperties.z = fitResult->getPosition().Z();
140
141 m_pValue = fitResult->getPValue();
142
143 // Count hits
148 for (genfit::TrackPoint* tp : recoTrack->getHitPointsWithMeasurement()) {
149 for (genfit::AbsMeasurement* m : tp->getRawMeasurements()) {
150 if (dynamic_cast<PXDRecoHit*>(m))
152 else if (dynamic_cast<SVDRecoHit*>(m))
154 else if (dynamic_cast<SVDRecoHit2D*>(m))
156 else if (dynamic_cast<CDCRecoHit*>(m))
158 else
159 B2ERROR("Unknown AbsMeasurement in track.");
160
161 std::vector<double> weights;
162 genfit::KalmanFitterInfo* kalmanInfo = tp->getKalmanFitterInfo();
163 if (kalmanInfo)
164 weights = kalmanInfo->getWeights();
165
166 for (size_t i = 0;
167 (i < weights.size()
169 ++i) {
171 }
172 }
173 }
174 }
175
176 m_dataTree->Fill(); // write data to tree
177 }
178 }
179}
180
181
183{
184 writeData();
185}
186
188{
189 return mcParticle.hasStatus(MCParticle::c_PrimaryParticle);
190}
191
193{
194 return Const::chargedStableSet.find(abs(mcParticle.getPDG()))
196}
197
199{
200 if (m_dataTree == nullptr) {
201 B2FATAL("Data tree was not created.");
202 }
203
206
209
212
215
218
221
224
227
230
233
234 addVariableToTree("pValue", m_pValue);
235
239
240 m_dataTree->Branch("nWeights", &m_trackProperties.nWeights, "nWeights/I");
241 m_dataTree->Branch("weights", &m_trackProperties.weights, "weights[nWeights]/F");
242}
243
245{
246 if (m_dataTree != nullptr) {
247 TDirectory* oldDir = gDirectory;
248 if (m_outputFile)
249 m_outputFile->cd();
250 m_dataTree->Write();
251 oldDir->cd();
252 }
253 if (m_outputFile != nullptr) {
254 m_outputFile->Close();
255 }
256}
257
259{
260 std::sort(m_signalDaughterPDGs.begin(), m_signalDaughterPDGs.end());
261
262 for (const MCParticle& mcParticle : m_MCParticles) {
263 // continue if mcParticle is not a B meson
264 if (abs(mcParticle.getPDG()) != 511 && abs(mcParticle.getPDG()) != 521)
265 continue;
266
267 if (isSignalDecay(mcParticle)) {
268 addChargedStable(mcParticle);
269 break;
270 }
271 }
272}
273
275{
276 std::vector<int> daughterPDGs;
277 std::vector<MCParticle*> daughterMcParticles = mcParticle.getDaughters();
278
279 // remove photons from list
280 daughterMcParticles = removeFinalStateRadiation(daughterMcParticles);
281
282 for (auto daughterMCParticle : daughterMcParticles) {
283 daughterPDGs.push_back(daughterMCParticle->getPDG());
284 }
285
286 std::sort(daughterPDGs.begin(), daughterPDGs.end());
287
288 bool isSignal = (daughterPDGs == m_signalDaughterPDGs);
289
290 if (isSignal)
291 m_signalMCParticles = daughterMcParticles;
292
293 return isSignal;
294}
295
298std::vector<MCParticle*> StandardTrackingPerformanceModule::removeFinalStateRadiation(const std::vector<MCParticle*>& in_daughters)
299{
300 std::vector<MCParticle*> daughtersWOFSR;
301 for (unsigned int iDaughter = 0; iDaughter < in_daughters.size(); iDaughter++)
302 if (abs(in_daughters[iDaughter]->getPDG()) != Const::photon.getPDGCode())
303 daughtersWOFSR.push_back(in_daughters[iDaughter]);
304
305 return daughtersWOFSR;
306}
307
309{
310
311 // mcparticle is not a charged stable decays into daughters
312 // loop over daughters and add the charged stable particles recursively to the vector
313 std::vector<MCParticle*> daughters = mcParticle.getDaughters();
314 if (daughters.size() != 0) {
315 for (auto daughterMcParticle : daughters) {
316 addChargedStable(*daughterMcParticle);
317 }
318 }
319
320 // charged stable particle is added to the interesting particle vector
321 if (isChargedStable(mcParticle) && isPrimaryMcParticle(mcParticle)
323// B2DEBUG(29,
324// "Found a charged stable particle. Add it to interesting MCParticles. PDG(" << mcParticle->getPDG() << ").");
325 m_interestingChargedStableMcParcticles.push_back(&mcParticle);
326 return;
327 }
328
329 return;
330}
331
333{
334 m_trackProperties = -999;
335
336 m_pValue = -999;
337}
338
339void StandardTrackingPerformanceModule::addVariableToTree(const std::string& varName, double& varReference)
340{
341 std::stringstream leaf;
342 leaf << varName << "/D";
343 m_dataTree->Branch(varName.c_str(), &varReference, leaf.str().c_str());
344}
345
346void StandardTrackingPerformanceModule::addVariableToTree(const std::string& varName, int& varReference)
347{
348 std::stringstream leaf;
349 leaf << varName << "/I";
350 m_dataTree->Branch(varName.c_str(), &varReference, leaf.str().c_str());
351}
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:32
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
Definition: Const.h:571
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:618
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:681
static const ParticleType photon
photon particle
Definition: Const.h:673
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
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
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:49
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition: MCParticle.cc:52
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
PXDRecoHit - an extended form of PXDCluster containing geometry information.
Definition: PXDRecoHit.h:49
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
const std::vector< genfit::TrackPoint * > & getHitPointsWithMeasurement() const
Return a list of measurements and track points, which can be used e.g. to extrapolate....
Definition: RecoTrack.h:708
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
RelationVector< T > getRelationsWith(const std::string &name="", const std::string &namedRelation="") const
Get the relations between this object and another store array.
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit2D.h:46
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:47
double m_nReconstructedChargedStableTracks
total number of reconstructed track candidates
void initialize() override
Register the needed StoreArrays and open th output TFile.
void event() override
Fill the tree with the event data.
std::vector< const MCParticle * > m_interestingChargedStableMcParcticles
vector with all interesting charged stable MCParticles in the event
std::vector< MCParticle * > m_signalMCParticles
vector with all MCParticles of the searched signal decay
double m_nGeneratedChargedStableMcParticles
total number of generated charged stable MCParticles
void terminate() override
Write the tree into the opened root file.
void addChargedStable(const MCParticle &mcParticle)
Add all charged stable particles to a vector which originate from.
ParticleProperties m_trackProperties
properties of a reconstructed track
bool isChargedStable(const MCParticle &mcParticle)
Tests if MCPArticle is a charged stable particle.
void setVariablesToDefaultValue()
Sets all variables to the default value, here -999.
void findSignalMCParticles()
Find a MCParticle of a decay chain specified by the user (not implemented yet).
bool isPrimaryMcParticle(const MCParticle &mcParticle)
Tests if MCParticle is a primary one.
void addVariableToTree(const std::string &varName, double &varReference)
add a variable with double format
TTree * m_dataTree
root tree with all output data.
std::vector< MCParticle * > removeFinalStateRadiation(const std::vector< MCParticle * > &in_daughters)
Remove all photons from a MCParticle vector.
double m_nFittedChargedStabletracks
total number of fitted tracks
void writeData()
write root tree to output file and close the file
bool isSignalDecay(const MCParticle &mcParticle)
Tests if mcParticle has the searched decay chain.
std::string m_recoTracksStoreArrayName
genfit::Track collection name
StoreArray< MCParticle > m_MCParticles
MCParticles StoreArray.
std::vector< int > m_signalDaughterPDGs
PDG codes of the B daughters of the interesting decay channel.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
Values of the result of a track fit with a given particle hypothesis.
Class that bundles various TrackFitResults.
Definition: Track.h:25
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for a fit hypothesis with the closest mass.
Definition: Track.cc:104
#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.
double pt
measured transverse momentum
int nCDChits
Number of CDC hits in reconstructed track
double pz
measured momentum in z direction
double x_gen
x value of generated position
float weights[maxNweights]
Weights of the hits in sequence
double pt_gen
generated transverse momentum
double mass_gen
generated mass
double y_gen
y value of generated position
int nPXDhits
Number of PXD hits in reconstructed track
int nSVDhits
Number of SVD hits in reconstructed track
double px
measured momentum in x direction
static const int maxNweights
the maximum number of stored weights
double z
measured z value of position
int nWeights
Number of entries in weights array
double y
measured y value of position
double ptot_gen
generated total momentum
double py
measured momentum in y direction
double cosTheta
polar angle of measured momentum vector
double pz_gen
generated momentum in z direction
double py_gen
generated momentum in y direction
double cosTheta_gen
polar angle of generated momentum vector
double px_gen
generated momentum in x direction
double z_gen
z value of generated position
double x
measured x value of position
double ptot
measured total momentum