Belle II Software  release-08-01-10
ECLTrackClusterMatchingParametrizationExpertModule.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 <ecl/modules/eclTrackClusterMatching/ECLTrackClusterMatchingParametrizationExpertModule.h>
10 #include <framework/datastore/RelationVector.h>
11 #include <framework/gearbox/Const.h>
12 #include <vector>
13 #include <cmath>
14 #include "TFile.h"
15 #include "TTree.h"
16 
17 using namespace std;
18 using namespace Belle2;
19 
20 REG_MODULE(ECLTrackClusterMatchingParametrizationExpert);
21 
22 ECLTrackClusterMatchingParametrizationExpertModule::ECLTrackClusterMatchingParametrizationExpertModule() : Module(),
23  m_writeToRoot(1),
24  m_iExperiment(0),
25  m_iRun(0),
26  m_iEvent(0),
27  m_trackNo(0),
28  m_trackMomentum(0),
29  m_pT(0),
30  m_trackTheta(0),
31  m_deltaPhi(0),
32  m_phiCluster(0),
33  m_phiHit(0),
34  m_errorPhi(0),
35  m_deltaTheta(0),
36  m_thetaCluster(0),
37  m_thetaHit(0),
38  m_errorTheta(0),
39  m_hitstatus(0),
40  m_true_track_pdg(0),
41  m_true_match(0)
42 {
43  setDescription("Store ExtHit related infos for track cluster matching");
45  addParam("writeToRoot", m_writeToRoot,
46  "set true if you want to save the information in a root file named by parameter 'rootFileName'", bool(false));
47  addParam("useArray", m_useArray,
48  "set true if you want to save the information event-wise using an array structure", bool(false));
49  addParam("rootFileName", m_rootFileName,
50  "fileName used for root file where info are saved. Will be ignored if parameter 'writeToRoot' is false (standard)",
51  string("eclTrackClusterMatchingAnalysis.root"));
52 }
53 
55 {
56 }
57 
59 {
60  // Check dependencies
61  m_tracks.isRequired();
62  m_eclClusters.isRequired();
63  m_tracks.registerRelationTo(m_eclClusters);
64  m_extHits.isRequired();
65  m_trackFitResults.isRequired();
67 
68  m_eventMetaData.isOptional();
69 
70  m_rootFilePtr = new TFile(m_rootFileName.c_str(), "RECREATE");
71  m_tree = new TTree("tree", "ECL Track Cluster Matching Analysis tree");
72 
73  m_tree->Branch("expNo", &m_iExperiment, "expNo/I");
74  m_tree->Branch("runNo", &m_iRun, "runNo/I");
75  m_tree->Branch("evtNo", &m_iEvent, "evtNo/I");
76 
77  if (m_useArray) {
78  m_tree->Branch("trackNo", "std::vector<int>", &m_trackNo_array);
79  m_tree->Branch("trackMomentum", "std::vector<float>", &m_trackMomentum_array);
80  m_tree->Branch("pT", "std::vector<float>", &m_pT_array);
81  m_tree->Branch("trackTheta", "std::vector<float>", &m_trackTheta_array);
82  m_tree->Branch("deltaPhi", "std::vector<float>", &m_deltaPhi_array);
83  m_tree->Branch("phiCluster", "std::vector<float>", &m_phiCluster_array);
84  m_tree->Branch("phiHit", "std::vector<float>", &m_phiHit_array);
85  m_tree->Branch("errorPhi", "std::vector<float>", &m_errorPhi_array);
86  m_tree->Branch("deltaTheta", "std::vector<float>", &m_deltaTheta_array);
87  m_tree->Branch("thetaCluster", "std::vector<float>", &m_thetaCluster_array);
88  m_tree->Branch("thetaHit", "std::vector<float>", &m_thetaHit_array);
89  m_tree->Branch("errorTheta", "std::vector<float>", &m_errorTheta_array);
90  m_tree->Branch("hitStatus", "std::vector<int>", &m_hitstatus_array);
91  m_tree->Branch("trueTrackPDG", "std::vector<int>", &m_true_track_pdg_array);
92  m_tree->Branch("trueMatch", "std::vector<int>", &m_true_match_array);
93  } else {
94  m_tree->Branch("trackNo", &m_trackNo, "trackNo/I");
95  m_tree->Branch("trackMomentum", &m_trackMomentum, "trackMomentum/F");
96  m_tree->Branch("pT", &m_pT, "pT/F");
97  m_tree->Branch("trackTheta", &m_trackTheta, "trackTheta/F");
98  m_tree->Branch("deltaPhi", &m_deltaPhi, "deltaPhi/F");
99  m_tree->Branch("phiCluster", &m_phiCluster, "phiCluster/F");
100  m_tree->Branch("phiHit", &m_phiHit, "phiHit/F");
101  m_tree->Branch("errorPhi", &m_errorPhi, "errorPhi/F");
102  m_tree->Branch("deltaTheta", &m_deltaTheta, "deltaTheta/F");
103  m_tree->Branch("thetaCluster", &m_thetaCluster, "thetaCluster/F");
104  m_tree->Branch("thetaHit", &m_thetaHit, "thetaHit/F");
105  m_tree->Branch("errorTheta", &m_errorTheta, "errorTheta/F");
106  m_tree->Branch("hitStatus", &m_hitstatus, "hitStatus/I");
107  m_tree->Branch("trueTrackPDG", &m_true_track_pdg, "trueTrackPDG/I");
108  m_tree->Branch("trueMatch", &m_true_match, "trueMatch/I");
109  }
110 }
111 
113 {
114  if (m_useArray) {
115  m_deltaPhi_array->clear();
116  m_phiCluster_array->clear();
117  m_phiHit_array->clear();
118  m_errorPhi_array->clear();
119  m_deltaTheta_array->clear();
120  m_thetaCluster_array->clear();
121  m_thetaHit_array->clear();
122  m_errorTheta_array->clear();
123  m_trackNo_array->clear();
124  m_trackMomentum_array->clear();
125  m_pT_array->clear();
126  m_trackTheta_array->clear();
127  m_hitstatus_array->clear();
128  m_true_track_pdg_array->clear();
129  m_true_match_array->clear();
130  }
131 
132  if (m_eventMetaData) {
133  m_iExperiment = m_eventMetaData->getExperiment();
134  m_iRun = m_eventMetaData->getRun();
135  m_iEvent = m_eventMetaData->getEvent();
136  } else {
137  m_iExperiment = -1;
138  m_iRun = -1;
139  m_iEvent = -1;
140  }
141 
142  int i = 0;
143 
144  for (const Track& track : m_tracks) {
145 
146  const MCParticle* relatedMCParticle = track.getRelatedTo<MCParticle>();
147  if (!relatedMCParticle) continue;
148  int pdgCode = relatedMCParticle->getPDG();
149  Const::ChargedStable hypothesis = Const::pion;
150  if (Const::chargedStableSet.find(abs(pdgCode)) != Const::invalidParticle) {
151  hypothesis = Const::ChargedStable(abs(pdgCode));
152  }
153  const TrackFitResult* fitResult = track.getTrackFitResultWithClosestMass(hypothesis);
154 
155  double momentum = fitResult->getMomentum().R();
156  double pt = fitResult->getTransverseMomentum();
157  double theta = fitResult->getMomentum().Theta();
158  if (m_useArray) {
159  m_true_track_pdg_array->push_back(pdgCode);
160  m_trackNo_array->push_back(i);
161  m_trackMomentum_array->push_back(momentum);
162  m_pT_array->push_back(pt);
163  m_trackTheta_array->push_back(theta);
164  } else {
165  m_true_track_pdg = pdgCode;
166  m_trackNo = i;
167  m_trackMomentum = momentum;
168  m_pT = pt;
169  m_trackTheta = theta;
170  }
171  i++;
172  // Find extrapolated track hits in the ECL, considering only hit points
173  // that either are on the sphere, closest to, or on radial direction of an
174  // ECLCluster.
175  for (const auto& extHit : track.getRelationsTo<ExtHit>()) {
176  if (!isECLHit(extHit)) continue;
177  ECLCluster* eclCluster = extHit.getRelatedFrom<ECLCluster>();
178  if (eclCluster != nullptr) {
179  // only use c_nPhotons clusters
180  if (!eclCluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) continue;
181  double errorPhi = extHit.getErrorPhi();
182  double errorTheta = extHit.getErrorTheta();
183  double phiHit = extHit.getPosition().Phi();
184  double phiCluster = eclCluster->getPhi();
185  double deltaPhi = phiHit - phiCluster;
186  if (deltaPhi > M_PI) {
187  deltaPhi = deltaPhi - 2 * M_PI;
188  } else if (deltaPhi < -M_PI) {
189  deltaPhi = deltaPhi + 2 * M_PI;
190  }
191  double thetaHit = extHit.getPosition().Theta();
192  double thetaCluster = eclCluster->getTheta();
193  double deltaTheta = thetaHit - thetaCluster;
194  ExtHitStatus hitStatus = extHit.getStatus();
195  const auto& relatedMCParticles = eclCluster->getRelationsTo<MCParticle>();
196  bool found_match = false;
197  for (unsigned int index = 0; index < relatedMCParticles.size() && !found_match; ++index) {
198  const MCParticle* clusterRelatedMCParticle = relatedMCParticles.object(index);
199  if (clusterRelatedMCParticle == relatedMCParticle) {
200  found_match = true;
201  }
202  }
203  if (m_useArray) {
204  m_errorPhi_array->push_back(errorPhi);
205  m_errorTheta_array->push_back(errorTheta);
206  m_deltaPhi_array->push_back(deltaPhi);
207  m_phiCluster_array->push_back(phiCluster);
208  m_phiHit_array->push_back(phiHit);
209  m_deltaTheta_array->push_back(deltaTheta);
210  m_thetaCluster_array->push_back(thetaCluster);
211  m_thetaHit_array->push_back(thetaHit);
212  m_hitstatus_array->push_back(hitStatus);
213  m_true_match_array->push_back(int(found_match));
214  } else {
215  m_errorPhi = errorPhi;
216  m_errorTheta = errorTheta;
217  m_deltaPhi = deltaPhi;
218  m_phiCluster = phiCluster;
219  m_phiHit = phiHit;
220  m_deltaTheta = deltaTheta;
221  m_thetaCluster = thetaCluster;
222  m_thetaHit = thetaHit;
223  m_hitstatus = hitStatus;
224  m_true_match = int(found_match);
225  m_tree->Fill();
226  }
227  }
228  } // end loop on ExtHits related to Track
229  } // end loop on Tracks
230  if (m_useArray) m_tree->Fill();
231 }
232 
234 {
235  if (m_rootFilePtr != nullptr) {
236  m_rootFilePtr->cd();
237  m_tree->Write();
238  delete m_tree;
239  m_rootFilePtr->Close();
240  delete m_rootFilePtr;
241  }
242 }
243 
245 {
246  if ((extHit.getDetectorID() != Const::EDetector::ECL)) return false;
247  ExtHitStatus extHitStatus = extHit.getStatus();
248  if (extHitStatus == EXT_ECLCROSS || extHitStatus == EXT_ECLDL || extHitStatus == EXT_ECLNEAR) return true;
249  else return false;
250 }
251 
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:580
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
ECL cluster data.
Definition: ECLCluster.h:27
bool hasHypothesis(EHypothesisBit bitmask) const
Return if specific hypothesis bit is set.
Definition: ECLCluster.h:348
double getPhi() const
Return Corrected Phi of Shower (radian).
Definition: ECLCluster.h:301
double getTheta() const
Return Corrected Theta of Shower (radian).
Definition: ECLCluster.h:304
@ c_nPhotons
CR is split into n photons (N1)
std::vector< int > * m_true_match_array
array of booleans indicating if cluster of hit is related to same MCParticle as track
bool m_writeToRoot
if true, a rootFile named by m_rootFileName will be filled with info
virtual void initialize() override
Use this to initialize resources or memory your module needs.
virtual ~ECLTrackClusterMatchingParametrizationExpertModule()
Use to clean up anything you created in the constructor.
bool m_useArray
if true, info is stored event-wise using array, otherwise hit-wise
StoreArray< TrackFitResult > m_trackFitResults
Required input array of TrackFitResults.
virtual void terminate() override
Clean up anything you created in initialize().
float m_deltaTheta
difference in polar angle between hit position and cluster
StoreObjPtr< EventMetaData > m_eventMetaData
Optional input array of EventMetaData.
std::vector< float > * m_deltaTheta_array
array of differences in polar angle between hit and cluster
std::vector< float > * m_errorPhi_array
array of uncertainties on azimuthal angle of hit
bool isECLHit(const ExtHit &extHit) const
Check if extrapolated hit is inside ECL and matches one of the desired categories.
int m_true_match
cluster related to hit is related to same MCParticle as track
StoreArray< ECLCluster > m_eclClusters
Required input array of ECLClusters.
StoreArray< MCParticle > m_mcParticles
Required input array of MCParticles.
float m_deltaPhi
difference in azimuthal angle between hit position and cluster
std::vector< float > * m_errorTheta_array
array of uncertainties on polar angle of hit
std::vector< float > * m_deltaPhi_array
array of differences in azimuthal angle between hit and cluster
Store one Ext hit as a ROOT object.
Definition: ExtHit.h:32
ExtHitStatus getStatus() const
Get state of extrapolation at this hit.
Definition: ExtHit.h:130
Const::EDetector getDetectorID() const
Get detector ID of this extrapolation hit.
Definition: ExtHit.h:122
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Values of the result of a track fit with a given particle hypothesis.
double getTransverseMomentum() const
Getter for the absolute value of the transverse momentum at the perigee.
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
ExtHitStatus
Define state of extrapolation for each recorded hit.
Definition: ExtHit.h:27
Abstract base class for different kinds of events.