Belle II Software development
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
17using namespace std;
18using namespace Belle2;
19
20REG_MODULE(ECLTrackClusterMatchingParametrizationExpert);
21
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();
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:589
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
ECL cluster data.
Definition: ECLCluster.h:27
bool hasHypothesis(EHypothesisBit bitmask) const
Return if specific hypothesis bit is set.
Definition: ECLCluster.h:351
double getPhi() const
Return Corrected Phi of Shower (radian).
Definition: ECLCluster.h:304
double getTheta() const
Return Corrected Theta of Shower (radian).
Definition: ECLCluster.h:307
@ c_nPhotons
CR is split into n photons (N1)
ECLTrackClusterMatchingParametrizationExpertModule()
Constructor, for setting module description and parameters.
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:31
ExtHitStatus getStatus() const
Get state of extrapolation at this hit.
Definition: ExtHit.h:129
Const::EDetector getDetectorID() const
Get detector ID of this extrapolation hit.
Definition: ExtHit.h:121
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
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
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:26
Abstract base class for different kinds of events.
STL namespace.