Belle II Software  release-08-01-10
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 
28 using namespace Belle2;
29 
30 //-----------------------------------------------------------------
31 // Register the Module
32 //-----------------------------------------------------------------
33 REG_MODULE(StandardTrackingPerformance);
34 
35 StandardTrackingPerformanceModule::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 
51 void StandardTrackingPerformanceModule::initialize()
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>();
125  const TrackFitResult* fitResult = b2Track->getTrackFitResultWithClosestMass(Const::pion);
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 
298 std::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 
339 void 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 
346 void 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:562
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:609
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:672
static const ParticleType photon
photon particle
Definition: Const.h:664
@ 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 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 genrated 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
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
REG_MODULE(arichBtest)
Register the Module.
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