Belle II Software  release-06-01-15
KlId.h
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 #pragma once
10 
11 #include <framework/datastore/StoreArray.h>
12 #include <mdst/dataobjects/MCParticle.h>
13 #include <mdst/dataobjects/KLMCluster.h>
14 #include <mdst/dataobjects/ECLCluster.h>
15 #include <mdst/dataobjects/TrackFitResult.h>
16 
17 #include <framework/gearbox/Const.h>
18 #include <framework/logging/Logger.h>
19 #include <tracking/dataobjects/RecoTrack.h>
20 #include <genfit/Exception.h>
21 #include <utility>
22 #include <math.h>
23 
25 namespace Belle2::KlongId {
26 
28  int BelleTrackFlag(const Belle2::KLMCluster& cluster, const float angle = 0.26)
29  {
30  const TVector3& pos = cluster.getClusterPosition();
31 
33  for (const Belle2::TrackFitResult& track : tracks) {
34  const TVector3& trackPos = track.getPosition();
35 
36  if (trackPos.Angle(pos) < angle) {
37  B2DEBUG(20, "BelleFlagTracklAngle::" << trackPos.Angle(pos));
38  return 1;
39  }
40  }
41  return 0;
42  }
43 
44 
46  int BelleECLFlag(const Belle2::KLMCluster& cluster, const float angle = 0.26)
47  {
48  const TVector3& pos = cluster.getClusterPosition();
50 
51  for (const Belle2::ECLCluster& eclcluster : eclclusters) {
52 
53  const TVector3& clusterPos = eclcluster.getClusterPosition();
54 
55  if (clusterPos.Angle(pos) < angle) {
56  B2DEBUG(20, "BelleFlagECLAngle::" << clusterPos.Angle(pos));
57  return 1;
58  }
59  }
60  return 0;
61  }
62 
65  {
66  if (part == nullptr) {
67  return 1;
68  } else {
69  return 0;
70  }
71  }
72 
75  {
76  unsigned int hirachy_counter = 0;
77  if (mcParticleIsBeamBKG(part)) {
78  return 0;
79  }
80  bool stop = false;
81  while (!stop) {
82  ++hirachy_counter;
83  if (part -> getPDG() == Const::Klong.getPDGCode()) {
84  return hirachy_counter;
85  }
86  if ((part -> getMother() == nullptr)) {
87  stop = true;
88  } else {
89  part = part -> getMother();
90  }
91  }
92  return 0;
93  }
94 
96  bool isKLMClusterSignal(const Belle2::KLMCluster& cluster, float mcWeigthCut = 0.66)
97  {
98  const auto mcParticleWeightPair = cluster.getRelatedToWithWeight<Belle2::MCParticle>();
99  Belle2::MCParticle* part = mcParticleWeightPair.first;
100  if (!part) {return false; }
101  float mcWeight = mcParticleWeightPair.second;
102  if (mcParticleIsKlong(part) && (mcWeight > mcWeigthCut)) {
103  return true;
104  } else {
105  return false;
106  }
107  }
108 
110  bool isECLClusterSignal(const Belle2::ECLCluster& cluster, float mcWeigthCut = 0.66)
111  {
112  const auto mcParticleWeightPair = cluster.getRelatedToWithWeight<Belle2::MCParticle>();
113  Belle2::MCParticle* part = mcParticleWeightPair.first;
114  if (!part) {return false; }
115  float mcWeight = mcParticleWeightPair.second;
116  if (mcParticleIsKlong(part) && (mcWeight > mcWeigthCut)) {
117  return true;
118  } else {
119  return false;
120  }
121  }
122 
125  {
126  bool stop = false;
127  while (!stop) {
128  if (std::abs(part -> getPDG()) == pdg) {
129  return true;
130  }
131  if ((part -> getMother() == nullptr)) {
132  stop = true;
133  } else {
134  part = part -> getMother();
135  }
136  }
137  return false;
138  }
139 
140 
148  {
149 
150  if (mcParticleIsBeamBKG(part)) {
151  return -999;
152  }
153 
154  bool stop = false;
155  while (!stop) {
156  if (isMCParticlePDG(part, Const::Klong.getPDGCode())) {
157  return Const::Klong.getPDGCode();
158  }
159  if (isMCParticlePDG(part, Const::Kshort.getPDGCode())) {
160  return Const::Kshort.getPDGCode();
161  }
162  if (isMCParticlePDG(part, Const::kaon.getPDGCode())) {
163  return Const::kaon.getPDGCode();
164  }
165  if (isMCParticlePDG(part, Const::neutron.getPDGCode())) {
166  return Const::neutron.getPDGCode();
167  }
168  if (isMCParticlePDG(part, Const::proton.getPDGCode())) {
169  return Const::proton.getPDGCode();
170  }
171  if (isMCParticlePDG(part, Const::pion.getPDGCode())) {
172  return Const::pion.getPDGCode();
173  }
174  if (isMCParticlePDG(part, Const::pi0.getPDGCode())) {
175  return Const::pi0.getPDGCode();
176  }
177  if (isMCParticlePDG(part, Const::muon.getPDGCode())) {
178  return Const::muon.getPDGCode();
179  }
180  if (isMCParticlePDG(part, Const::electron.getPDGCode())) {
181  return Const::electron.getPDGCode();
182  }
183  if (isMCParticlePDG(part, Const::photon.getPDGCode())) {
184  return Const::photon.getPDGCode();
185  }
186  if ((part -> getMother() == nullptr)) {
187  stop = true;
188  } else {
189  part = part -> getMother();
190  }
191  }
192  return part ->getPDG();
193  }
194 
199  std::pair<Belle2::ECLCluster*, double> findClosestECLCluster(const TVector3& klmClusterPosition,
201  {
202 
203  Belle2::ECLCluster* closestECL = nullptr;
204  double closestECLAngleDist = 1e10;
206 
207  if (eclClusters.getEntries() > 0) {
208  int index = 0;
209  int indexOfClosestCluster = -1;
210  for (Belle2::ECLCluster& eclcluster : eclClusters) {
211 
212  if (eclcluster.hasHypothesis(eclhypothesis)) {
213 
214  const TVector3& eclclusterPos = eclcluster.getClusterPosition();
215  double angularDist = eclclusterPos.Angle(klmClusterPosition);
216  if (angularDist < closestECLAngleDist) {
217  closestECLAngleDist = angularDist;
218  indexOfClosestCluster = index;
219  }
220  }
221  ++index;
222  }
223  if (indexOfClosestCluster > -1)
224  closestECL = eclClusters[indexOfClosestCluster];
225  }
226  return std::make_pair(closestECL, closestECLAngleDist);
227  }
228 
229 
231  std::tuple<const Belle2::KLMCluster*, double, double> findClosestKLMCluster(const TVector3& klmClusterPosition)
232  {
233 
235  const Belle2::KLMCluster* closestKLM = nullptr;
236  double closestKLMDist = 1e10;
237  double avInterClusterDist = 0;
238  double nKLMCluster = klmClusters.getEntries();
239 
240  if (nKLMCluster > 1) {
241 
242  unsigned int index = 0;
243  unsigned int indexOfClosestCluster = 0;
244  for (const Belle2::KLMCluster& nextCluster : klmClusters) {
245 
246  const TVector3& nextClusterPos = nextCluster.getClusterPosition();
247  const TVector3& clustDistanceVec = nextClusterPos - klmClusterPosition;
248 
249  double nextClusterDist = clustDistanceVec.Mag2();
250  avInterClusterDist = avInterClusterDist + nextClusterDist;
251 
252  if ((nextClusterDist < closestKLMDist) and not(nextClusterDist == 0)) {
253  closestKLMDist = nextClusterDist ;
254  indexOfClosestCluster = index;
255  }
256  ++index;
257  }// for next_cluster
258 
259  closestKLM = klmClusters[indexOfClosestCluster];
260  avInterClusterDist = avInterClusterDist / (1. * nKLMCluster);
261  }
262 
263  return std::make_tuple(closestKLM, closestKLMDist, avInterClusterDist);
264  }
265 
266 
268  std::tuple<Belle2::RecoTrack*, double, std::unique_ptr<const TVector3> > findClosestTrack(const TVector3& clusterPosition,
269  float cutAngle)
270  {
272  double oldDistance = 10000000;//dont wanna use infty cos that kills tmva...
273  Belle2::RecoTrack* closestTrack = nullptr;
274  TVector3 poca = TVector3(0, 0, 0);
275 
276 
277  for (Belle2::RecoTrack& track : genfitTracks) {
278 
279  try {
281  genfit::MeasuredStateOnPlane state_for_cut;
282  state_for_cut = track.getMeasuredStateOnPlaneFromFirstHit();
283 
284  // only use tracks that are close cos the extrapolation takes ages
285  if (clusterPosition.Angle(state_for_cut.getPos()) < cutAngle) {
286  state = track.getMeasuredStateOnPlaneFromLastHit();
287  state.extrapolateToPoint(clusterPosition);
288  const TVector3& trackPos = state.getPos();
289 
290  const TVector3& distanceVecCluster = clusterPosition - trackPos;
291  double newDistance = distanceVecCluster.Mag2();
292 
293  // overwrite old distance
294  if (newDistance < oldDistance) {
295  oldDistance = newDistance;
296  closestTrack = &track;
297  poca = trackPos;
298  }
299  }
300  } catch (genfit::Exception& e) {
301  }// try
302  }// for gftrack
303 
304  if (not closestTrack) {
305  return std::make_tuple(nullptr, oldDistance, std::unique_ptr<const TVector3>(nullptr));
306  } else {
307  // actually this is fine because of the datastore
308  // cppcheck-suppress returnDanglingLifetime
309  return std::make_tuple(closestTrack, oldDistance, std::unique_ptr<const TVector3>(new TVector3(poca)));
310  }
311  }
312 }//end namespace
int getPDGCode() const
PDG code.
Definition: Const.h:354
static const ParticleType neutron
neutron particle
Definition: Const.h:556
static const ParticleType pi0
neutral pion particle
Definition: Const.h:555
static const ChargedStable muon
muon particle
Definition: Const.h:541
static const ChargedStable pion
charged pion particle
Definition: Const.h:542
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:558
static const ChargedStable proton
proton particle
Definition: Const.h:544
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:557
static const ChargedStable kaon
charged kaon particle
Definition: Const.h:543
static const ParticleType photon
photon particle
Definition: Const.h:554
static const ChargedStable electron
electron particle
Definition: Const.h:540
ECL cluster data.
Definition: ECLCluster.h:27
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
Definition: ECLCluster.h:31
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
KLM cluster data.
Definition: KLMCluster.h:28
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
Values of the result of a track fit with a given particle hypothesis.
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
#StateOnPlane with additional covariance matrix.
Helper functions for all klid modules to improve readability of the code.
Definition: KlId.h:25
int mcParticleIsBeamBKG(Belle2::MCParticle *part)
return if MCparticle is beambkg
Definition: KlId.h:64
bool isKLMClusterSignal(const Belle2::KLMCluster &cluster, float mcWeigthCut=0.66)
checks if a cluster is signal under the mcWeightcondition (mcWeight = energy deposition)
Definition: KlId.h:96
int BelleTrackFlag(const Belle2::KLMCluster &cluster, const float angle=0.26)
get Belle stle track flag
Definition: KlId.h:28
bool isECLClusterSignal(const Belle2::ECLCluster &cluster, float mcWeigthCut=0.66)
checks if a cluster is signal under the mcWeightcondition (mcWeight = energy deposition)
Definition: KlId.h:110
int isMCParticlePDG(Belle2::MCParticle *part, int pdg)
return if mc particle has a certain pdg in the decay chain
Definition: KlId.h:124
int BelleECLFlag(const Belle2::KLMCluster &cluster, const float angle=0.26)
get Belle stle ECL flag
Definition: KlId.h:46
int getPrimaryPDG(Belle2::MCParticle *part)
return if mc particles primary pdg.
Definition: KlId.h:147
std::tuple< const Belle2::KLMCluster *, double, double > findClosestKLMCluster(const TVector3 &klmClusterPosition)
find nearest KLMCluster, tis distance and the av intercluster distance
Definition: KlId.h:231
int mcParticleIsKlong(Belle2::MCParticle *part)
return the mc hirachy of the klong 0:not a klong 1:final particle, 2: klong is mother etc
Definition: KlId.h:74
std::tuple< Belle2::RecoTrack *, double, std::unique_ptr< const TVector3 > > findClosestTrack(const TVector3 &clusterPosition, float cutAngle)
find nearest genfit track and return it and its distance
Definition: KlId.h:268
std::pair< Belle2::ECLCluster *, double > findClosestECLCluster(const TVector3 &klmClusterPosition, const Belle2::ECLCluster::EHypothesisBit eclhypothesis=Belle2::ECLCluster::EHypothesisBit::c_neutralHadron)
Find the closest ECLCluster with a neutral hadron hypothesis, and return it with its distance.
Definition: KlId.h:199