Belle II Software  release-06-01-15
BelleVariables.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 <analysis/variables/BelleVariables.h>
10 
11 #include <analysis/dataobjects/Particle.h>
12 #include <analysis/variables/Variables.h>
13 #include <analysis/variables/VertexVariables.h>
14 #include <analysis/variables/ECLVariables.h>
15 #include <analysis/variables/TrackVariables.h>
16 #include <analysis/variables/V0DaughterTrackVariables.h>
17 #include <mdst/dataobjects/Track.h>
18 #include <analysis/variables/VertexVariables.h>
19 
20 #include <framework/logging/Logger.h>
21 #include <framework/gearbox/Const.h>
22 
23 #include <framework/database/DBObjPtr.h>
24 #include <mdst/dbobjects/BeamSpot.h>
25 
26 #include <framework/datastore/StoreArray.h>
27 #include <b2bii/dataobjects/BelleTrkExtra.h>
28 
29 #include <TVectorF.h>
30 
31 #include <limits>
32 
33 namespace Belle2 {
38  namespace Variable {
39  double goodBelleKshort(const Particle* KS)
40  {
41  // check input
42  if (KS->getNDaughters() != 2) {
43  B2WARNING("goodBelleKshort is only defined for a particle with two daughters");
44  return 0.0;
45  }
46  const Particle* d0 = KS->getDaughter(0);
47  const Particle* d1 = KS->getDaughter(1);
48  if ((d0->getCharge() == 0) || (d1->getCharge() == 0)) {
49  B2WARNING("goodBelleKshort is only defined for a particle with charged daughters");
50  return 0.0;
51  }
52  if (abs(KS->getPDGCode()) != Const::Kshort.getPDGCode())
53  B2WARNING("goodBelleKshort is being applied to a candidate with PDG " << KS->getPDGCode());
54 
55  // If goodKs exists, return the value
56  if (KS->hasExtraInfo("goodKs")) {
57  return KS->getExtraInfo("goodKs");
58  }
59 
60  // Belle selection
61  double p = particleP(KS);
62  double fl = particleDRho(KS);
63  double dphi = acos(((particleDX(KS) * particlePx(KS)) + (particleDY(KS) * particlePy(KS))) / (fl * sqrt(particlePx(KS) * particlePx(
64  KS) + particlePy(KS) * particlePy(KS))));
65  // particleDRho returns track d0 relative to IP for tracks
66  double dr = std::min(abs(particleDRho(d0)), abs(particleDRho(d1)));
67  double zdist = v0DaughterZ0Diff(KS);
68 
69  bool low = p < 0.5 && abs(zdist) < 0.8 && dr > 0.05 && dphi < 0.3;
70  bool mid = p < 1.5 && p > 0.5 && abs(zdist) < 1.8 && dr > 0.03 && dphi < 0.1 && fl > .08;
71  bool high = p > 1.5 && abs(zdist) < 2.4 && dr > 0.02 && dphi < 0.03 && fl > .22;
72 
73  if (low || mid || high) {
74  return 1.0;
75  } else
76  return 0.0;
77  }
78 
79 
80  double goodBelleLambda(const Particle* Lambda)
81  {
82  if (Lambda->getNDaughters() != 2) {
83  B2WARNING("goodBelleLambda is only defined for a particle with two daughters");
84  return 0.;
85  }
86  const Particle* d0 = Lambda->getDaughter(0);
87  const Particle* d1 = Lambda->getDaughter(1);
88  if ((d0->getCharge() == 0) || (d1->getCharge() == 0)) {
89  B2WARNING("goodBelleLambda is only defined for a particle with charged daughters");
90  return 0.;
91  }
92  if (abs(Lambda->getPDGCode()) != Const::Lambda.getPDGCode()) {
93  B2WARNING("goodBelleLambda is being applied to a candidate with PDG " << Lambda->getPDGCode());
94  }
95 
96  if (Lambda->hasExtraInfo("goodLambda"))
97  return Lambda->getExtraInfo("goodLambda");
98 
99  double p = particleP(Lambda);
100  double dr = std::min(abs(particleDRho(d0)), abs(particleDRho(d1)));
101  double zdist = v0DaughterZ0Diff(Lambda);
102  double dphi = acos(cosAngleBetweenMomentumAndVertexVectorInXYPlane(Lambda));
103  // Flight distance of Lambda0 in xy plane
104  double fl = particleDRho(Lambda);
105 
106  // goodBelleLambda == 1 (optimized for proton PID > 0.6)
107  bool high1 = p >= 1.5 && abs(zdist) < 12.9 && dr > 0.008 && dphi < 0.09 && fl > 0.22;
108  bool mid1 = p >= 0.5 && p < 1.5 && abs(zdist) < 9.8 && dr > 0.01 && dphi < 0.18 && fl > 0.16;
109  bool low1 = p < 0.5 && abs(zdist) < 2.4 && dr > 0.027 && dphi < 1.2 && fl > 0.11;
110 
111  // goodBelleLambda == 2 (optimized without PID selection)
112  bool high2 = p >= 1.5 && abs(zdist) < 7.7 && dr > 0.018 && dphi < 0.07 && fl > 0.35;
113  bool mid2 = p >= 0.5 && p < 1.5 && abs(zdist) < 2.1 && dr > 0.033 && dphi < 0.10 && fl > 0.24;
114  bool low2 = p < 0.5 && abs(zdist) < 1.9 && dr > 0.059 && dphi < 0.6 && fl > 0.17;
115 
116  if (low2 || mid2 || high2) {
117  return 2.0;
118  } else if (low1 || mid1 || high1) {
119  return 1.0;
120  } else {
121  return 0.0;
122  }
123  }
124 
125 
126  bool isGoodBelleGamma(int region, double energy)
127  {
128  bool goodGammaRegion1, goodGammaRegion2, goodGammaRegion3;
129  goodGammaRegion1 = region == 1 && energy > 0.100;
130  goodGammaRegion2 = region == 2 && energy > 0.050;
131  goodGammaRegion3 = region == 3 && energy > 0.150;
132 
133  return goodGammaRegion1 || goodGammaRegion2 || goodGammaRegion3;
134  }
135 
136  double goodBelleGamma(const Particle* particle)
137  {
138  double energy = eclClusterE(particle);
139  int region = eclClusterDetectionRegion(particle);
140 
141  return (double) isGoodBelleGamma(region, energy);
142  }
143 
144  BelleTrkExtra* getBelleTrkExtraInfoFromParticle(Particle const* particle)
145  {
146  const Track* track = particle->getTrack();
147  if (!track) {
148  return nullptr;
149  }
150  auto belleTrkExtra = track->getRelatedTo<BelleTrkExtra>();
151  if (!belleTrkExtra) {
152  return nullptr;
153  }
154  return belleTrkExtra;
155  }
156 
157  double BelleFirstCDCHitX(const Particle* particle)
158  {
159  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
160  if (!belleTrkExtra) {
161  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
162  return std::numeric_limits<double>::quiet_NaN();
163  }
164  return belleTrkExtra->getTrackFirstX();
165  }
166 
167  double BelleFirstCDCHitY(const Particle* particle)
168  {
169  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
170  if (!belleTrkExtra) {
171  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
172  return std::numeric_limits<double>::quiet_NaN();
173  }
174  return belleTrkExtra->getTrackFirstY();
175  }
176 
177  double BelleFirstCDCHitZ(const Particle* particle)
178  {
179  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
180  if (!belleTrkExtra) {
181  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
182  return std::numeric_limits<double>::quiet_NaN();
183  }
184  return belleTrkExtra->getTrackFirstZ();
185  }
186 
187  double BelleLastCDCHitX(const Particle* particle)
188  {
189  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
190  if (!belleTrkExtra) {
191  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
192  return std::numeric_limits<double>::quiet_NaN();
193  }
194  return belleTrkExtra->getTrackLastX();
195  }
196 
197  double BelleLastCDCHitY(const Particle* particle)
198  {
199  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
200  if (!belleTrkExtra) {
201  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
202  return std::numeric_limits<double>::quiet_NaN();
203  }
204  return belleTrkExtra->getTrackLastY();
205  }
206 
207  double BelleLastCDCHitZ(const Particle* particle)
208  {
209  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
210  if (!belleTrkExtra) {
211  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
212  return std::numeric_limits<double>::quiet_NaN();
213  }
214  return belleTrkExtra->getTrackLastZ();
215  }
216 
217  double BellePi0InvariantMassSignificance(const Particle* particle)
218  {
219  TMatrixFSym covarianceMatrix(Particle::c_DimMomentum);
220  for (auto daughter : particle->getDaughters()) {
221  covarianceMatrix += daughter->getMomentumErrorMatrix();
222  }
223 
224  TVectorF jacobian(Particle::c_DimMomentum);
225  jacobian[0] = -1.0 * particle->getPx() / particle->getMass();
226  jacobian[1] = -1.0 * particle->getPy() / particle->getMass();
227  jacobian[2] = -1.0 * particle->getPz() / particle->getMass();
228  jacobian[3] = 1.0 * particle->getEnergy() / particle->getMass();
229 
230  double massErrSquared = jacobian * (covarianceMatrix * jacobian);
231 
232  if (massErrSquared < 0.0)
233  return std::numeric_limits<double>::quiet_NaN();
234 
235  double invMass = particleInvariantMassFromDaughters(particle);
236  double nomMass = particle->getPDGMass();
237 
238  return (invMass - nomMass) / sqrt(massErrSquared);
239  }
240 
241  VARIABLE_GROUP("Belle Variables");
242 
243  REGISTER_VARIABLE("goodBelleKshort", goodBelleKshort, R"DOC(
244 [Legacy] GoodKs Returns 1.0 if a :math:`K_{S}^0\to\pi\pi` candidate passes the Belle algorithm:
245 a momentum-binned selection including requirements on impact parameter of, and
246 angle between the daughter pions as well as separation from the vertex and
247 flight distance in the transverse plane.
248 )DOC");
249 
250  REGISTER_VARIABLE("goodBelleLambda", goodBelleLambda, R"DOC(
251 [Legacy] Returns 2.0, 1.0, 0.0 as an indication of goodness of :math:`\Lambda^0` candidates,
252 based on:
253 
254  * The distance of the two daughter tracks at their interception at z axis,
255  * the minimum distance of the daughter tracks and the IP in xy plane,
256  * the difference of the azimuthal angle of the vertex vector and the momentum vector,
257  * and the flight distance of the Lambda0 candidates in xy plane.
258 
259 It reproduces the ``goodLambda()`` function in Belle.
260 
261 ``goodBelleLambda`` selection 1 (selected with: ``goodBelleLambda>0``) should be used with ``atcPIDBelle(4,2) > 0.6``,
262 and ``goodBelleLambda`` selection 2 (``goodBelleLambda>1``) can be used without a proton PID cut.
263 The former cut is looser than the latter.".
264 
265 .. warning:: ``goodBelleLambda`` is not optimized or tested on Belle II data.
266 
267 See Also:
268  * `BN-684`_ Lambda selection at Belle. K F Chen et al.
269  * The ``FindLambda`` class can be found at ``/belle_legacy/findLambda/findLambda.h``
270 
271 .. _BN-684: https://belle.kek.jp/secured/belle_note/gn684/bn684.ps.gz
272 
273 )DOC");
274 
275  REGISTER_VARIABLE("goodBelleGamma", goodBelleGamma, R"DOC(
276 [Legacy] Returns 1.0 if photon candidate passes simple region dependent
277 energy selection for Belle data and MC (50/100/150 MeV).
278 )DOC");
279 
280  REGISTER_VARIABLE("BelleFirstCDCHitX", BelleFirstCDCHitX, R"DOC(
281 [Legacy] Returns x component of starting point of the track near the 1st SVD or CDC hit for SVD1 data (exp. 7 - 27) or the 1st CDC hit for SVD2 data (from exp. 31). (Belle only, originally stored in mdst_trk_fit.)
282 )DOC");
283 
284  REGISTER_VARIABLE("BelleFirstCDCHitY", BelleFirstCDCHitY, R"DOC(
285 [Legacy] Returns y component of starting point of the track near the 1st SVD or CDC hit for SVD1 data (exp. 7 - 27) or the 1st CDC hit for SVD2 data (from exp. 31). (Belle only, originally stored in mdst_trk_fit.)
286 )DOC");
287 
288  REGISTER_VARIABLE("BelleFirstCDCHitZ", BelleFirstCDCHitZ, R"DOC(
289 [Legacy] Returns z component of starting point of the track near the 1st SVD or CDC hit for SVD1 data (exp. 7 - 27) or the 1st CDC hit for SVD2 data (from exp. 31). (Belle only, originally stored in mdst_trk_fit.)
290 )DOC");
291 
292  REGISTER_VARIABLE("BelleLastCDCHitX", BelleLastCDCHitX, R"DOC(
293 [Legacy] Returns x component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
294 )DOC");
295 
296  REGISTER_VARIABLE("BelleLastCDCHitY", BelleLastCDCHitY, R"DOC(
297 [Legacy] Returns y component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
298 )DOC");
299 
300  REGISTER_VARIABLE("BelleLastCDCHitZ", BelleLastCDCHitZ, R"DOC(
301 [Legacy] Returns z component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
302 )DOC");
303 
304  REGISTER_VARIABLE("BellePi0SigM", BellePi0InvariantMassSignificance, R"DOC(
305  [Legacy] Returns the significance of the pi0 mass used in the FEI for B2BII.
306  The significance is calculated as the difference between the reconstructed and the nominal mass divided by the mass uncertainty.
307  Since the pi0's covariance matrix for B2BII is empty, the latter is calculated using the photon daughters' covariance matrices.
308  )DOC");
309 
310  // this is defined in ECLVariables.{h,cc}
311  REGISTER_VARIABLE("clusterBelleQuality", eclClusterDeltaL, R"DOC(
312 [Legacy] Returns ECL cluster's quality indicating a good cluster in GSIM (stored in deltaL of ECL cluster object).
313 Belle analysis typically used clusters with quality == 0 in their :math:`E_{\text{extra ECL}}` (Belle only).
314 )DOC");
315  }
317 }
int getPDGCode() const
PDG code.
Definition: Const.h:354
static const ParticleType Lambda
Lambda particle.
Definition: Const.h:559
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:557
Abstract base class for different kinds of events.