Belle II Software  release-08-01-10
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 // Own header.
10 #include <analysis/variables/BelleVariables.h>
11 
12 // include VariableManager
13 #include <analysis/VariableManager/Manager.h>
14 
15 #include <analysis/dataobjects/Particle.h>
16 #include <analysis/variables/Variables.h>
17 #include <analysis/variables/VertexVariables.h>
18 #include <analysis/variables/ECLVariables.h>
19 #include <analysis/variables/TrackVariables.h>
20 #include <analysis/variables/V0DaughterTrackVariables.h>
21 #include <mdst/dataobjects/Track.h>
22 #include <analysis/variables/VertexVariables.h>
23 
24 #include <framework/logging/Logger.h>
25 #include <framework/gearbox/Const.h>
26 
27 #include <framework/database/DBObjPtr.h>
28 #include <mdst/dbobjects/BeamSpot.h>
29 
30 #include <framework/datastore/StoreArray.h>
31 #include <b2bii/dataobjects/BelleTrkExtra.h>
32 
33 #include <TVectorF.h>
34 
35 #include <limits>
36 
37 namespace Belle2 {
42  namespace Variable {
43  bool goodBelleKshort(const Particle* KS)
44  {
45  // check input
46  if (KS->getNDaughters() != 2) {
47  B2WARNING("goodBelleKshort is only defined for a particle with two daughters");
48  return false;
49  }
50  const Particle* d0 = KS->getDaughter(0);
51  const Particle* d1 = KS->getDaughter(1);
52  if ((d0->getCharge() == 0) || (d1->getCharge() == 0)) {
53  B2WARNING("goodBelleKshort is only defined for a particle with charged daughters");
54  return false;
55  }
56  if (abs(KS->getPDGCode()) != Const::Kshort.getPDGCode())
57  B2WARNING("goodBelleKshort is being applied to a candidate with PDG " << KS->getPDGCode());
58 
59  // If goodKs exists, return the value
60  if (KS->hasExtraInfo("goodKs")) {
61  return bool(KS->getExtraInfo("goodKs"));
62  }
63 
64  // Belle selection
65  double p = particleP(KS);
66  double fl = particleDRho(KS);
67  double dphi = acos(((particleDX(KS) * particlePx(KS)) + (particleDY(KS) * particlePy(KS))) / (fl * sqrt(particlePx(KS) * particlePx(
68  KS) + particlePy(KS) * particlePy(KS))));
69  // particleDRho returns track d0 relative to IP for tracks
70  double dr = std::min(abs(particleDRho(d0)), abs(particleDRho(d1)));
71  double zdist = v0DaughterZ0Diff(KS);
72 
73  bool low = p < 0.5 && abs(zdist) < 0.8 && dr > 0.05 && dphi < 0.3;
74  bool mid = p < 1.5 && p > 0.5 && abs(zdist) < 1.8 && dr > 0.03 && dphi < 0.1 && fl > .08;
75  bool high = p > 1.5 && abs(zdist) < 2.4 && dr > 0.02 && dphi < 0.03 && fl > .22;
76 
77  if (low || mid || high) {
78  return true;
79  } else
80  return false;
81  }
82 
83 
84  double goodBelleLambda(const Particle* Lambda)
85  {
86  if (Lambda->getNDaughters() != 2) {
87  B2WARNING("goodBelleLambda is only defined for a particle with two daughters");
88  return 0.;
89  }
90  const Particle* d0 = Lambda->getDaughter(0);
91  const Particle* d1 = Lambda->getDaughter(1);
92  if ((d0->getCharge() == 0) || (d1->getCharge() == 0)) {
93  B2WARNING("goodBelleLambda is only defined for a particle with charged daughters");
94  return 0.;
95  }
96  if (abs(Lambda->getPDGCode()) != Const::Lambda.getPDGCode()) {
97  B2WARNING("goodBelleLambda is being applied to a candidate with PDG " << Lambda->getPDGCode());
98  }
99 
100  if (Lambda->hasExtraInfo("goodLambda"))
101  return Lambda->getExtraInfo("goodLambda");
102 
103  double p = particleP(Lambda);
104  double dr = std::min(abs(particleDRho(d0)), abs(particleDRho(d1)));
105  double zdist = v0DaughterZ0Diff(Lambda);
106  double dphi = acos(cosAngleBetweenMomentumAndVertexVectorInXYPlane(Lambda));
107  // Flight distance of Lambda0 in xy plane
108  double fl = particleDRho(Lambda);
109 
110  // goodBelleLambda == 1 (optimized for proton PID > 0.6)
111  bool high1 = p >= 1.5 && abs(zdist) < 12.9 && dr > 0.008 && dphi < 0.09 && fl > 0.22;
112  bool mid1 = p >= 0.5 && p < 1.5 && abs(zdist) < 9.8 && dr > 0.01 && dphi < 0.18 && fl > 0.16;
113  bool low1 = p < 0.5 && abs(zdist) < 2.4 && dr > 0.027 && dphi < 1.2 && fl > 0.11;
114 
115  // goodBelleLambda == 2 (optimized without PID selection)
116  bool high2 = p >= 1.5 && abs(zdist) < 7.7 && dr > 0.018 && dphi < 0.07 && fl > 0.35;
117  bool mid2 = p >= 0.5 && p < 1.5 && abs(zdist) < 2.1 && dr > 0.033 && dphi < 0.10 && fl > 0.24;
118  bool low2 = p < 0.5 && abs(zdist) < 1.9 && dr > 0.059 && dphi < 0.6 && fl > 0.17;
119 
120  if (low2 || mid2 || high2) {
121  return 2.0;
122  } else if (low1 || mid1 || high1) {
123  return 1.0;
124  } else {
125  return 0.0;
126  }
127  }
128 
129 
130  bool isGoodBelleGamma(int region, double energy)
131  {
132  bool goodGammaRegion1, goodGammaRegion2, goodGammaRegion3;
133  goodGammaRegion1 = region == 1 && energy > 0.100;
134  goodGammaRegion2 = region == 2 && energy > 0.050;
135  goodGammaRegion3 = region == 3 && energy > 0.150;
136 
137  return goodGammaRegion1 || goodGammaRegion2 || goodGammaRegion3;
138  }
139 
140  bool goodBelleGamma(const Particle* particle)
141  {
142  double energy = eclClusterE(particle);
143  int region = eclClusterDetectionRegion(particle);
144 
145  return isGoodBelleGamma(region, energy);
146  }
147 
148  BelleTrkExtra* getBelleTrkExtraInfoFromParticle(Particle const* particle)
149  {
150  const Track* track = particle->getTrack();
151  if (!track) {
152  return nullptr;
153  }
154  auto belleTrkExtra = track->getRelatedTo<BelleTrkExtra>();
155  if (!belleTrkExtra) {
156  return nullptr;
157  }
158  return belleTrkExtra;
159  }
160 
161  double BelleFirstCDCHitX(const Particle* particle)
162  {
163  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
164  if (!belleTrkExtra) {
165  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
166  return Const::doubleNaN;
167  }
168  return belleTrkExtra->getTrackFirstX();
169  }
170 
171  double BelleFirstCDCHitY(const Particle* particle)
172  {
173  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
174  if (!belleTrkExtra) {
175  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
176  return Const::doubleNaN;
177  }
178  return belleTrkExtra->getTrackFirstY();
179  }
180 
181  double BelleFirstCDCHitZ(const Particle* particle)
182  {
183  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
184  if (!belleTrkExtra) {
185  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
186  return Const::doubleNaN;
187  }
188  return belleTrkExtra->getTrackFirstZ();
189  }
190 
191  double BelleLastCDCHitX(const Particle* particle)
192  {
193  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
194  if (!belleTrkExtra) {
195  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
196  return Const::doubleNaN;
197  }
198  return belleTrkExtra->getTrackLastX();
199  }
200 
201  double BelleLastCDCHitY(const Particle* particle)
202  {
203  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
204  if (!belleTrkExtra) {
205  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
206  return Const::doubleNaN;
207  }
208  return belleTrkExtra->getTrackLastY();
209  }
210 
211  double BelleLastCDCHitZ(const Particle* particle)
212  {
213  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
214  if (!belleTrkExtra) {
215  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
216  return Const::doubleNaN;
217  }
218  return belleTrkExtra->getTrackLastZ();
219  }
220 
221  double BellePi0InvariantMassSignificance(const Particle* particle)
222  {
223  TMatrixFSym covarianceMatrix(Particle::c_DimMomentum);
224  for (auto daughter : particle->getDaughters()) {
225  covarianceMatrix += daughter->getMomentumErrorMatrix();
226  }
227 
228  TVectorF jacobian(Particle::c_DimMomentum);
229  jacobian[0] = -1.0 * particle->getPx() / particle->getMass();
230  jacobian[1] = -1.0 * particle->getPy() / particle->getMass();
231  jacobian[2] = -1.0 * particle->getPz() / particle->getMass();
232  jacobian[3] = 1.0 * particle->getEnergy() / particle->getMass();
233 
234  double massErrSquared = jacobian * (covarianceMatrix * jacobian);
235 
236  if (massErrSquared < 0.0)
237  return Const::doubleNaN;
238 
239  double invMass = particleInvariantMassFromDaughters(particle);
240  double nomMass = particle->getPDGMass();
241 
242  return (invMass - nomMass) / sqrt(massErrSquared);
243  }
244 
245  double BelleTof(const Particle* particle)
246  {
247  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
248  if (!belleTrkExtra) {
249  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
250  return Const::doubleNaN;
251  }
252  return belleTrkExtra->getTof();
253  }
254 
255  double BelleTofQuality(const Particle* particle)
256  {
257  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
258  if (!belleTrkExtra) {
259  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
260  return Const::doubleNaN;
261  }
262  return belleTrkExtra->getTofQuality();
263  }
264 
265  double BelleTofSigma(const Particle* particle)
266  {
267  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
268  if (!belleTrkExtra) {
269  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
270  return Const::doubleNaN;
271  }
272  return belleTrkExtra->getTofSigma();
273  }
274 
275  double BellePathLength(const Particle* particle)
276  {
277  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
278  if (!belleTrkExtra) {
279  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
280  return Const::doubleNaN;
281  }
282  return belleTrkExtra->getPathLength();
283  }
284 
285  double BelledEdx(const Particle* particle)
286  {
287  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
288  if (!belleTrkExtra) {
289  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
290  return Const::doubleNaN;
291  }
292  return belleTrkExtra->getdEdx();
293  }
294 
295  double BelledEdxQuality(const Particle* particle)
296  {
297  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
298  if (!belleTrkExtra) {
299  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
300  return Const::doubleNaN;
301  }
302  return belleTrkExtra->getdEdxQuality();
303  }
304 
305  double BelleACCnPe(const Particle* particle)
306  {
307  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
308  if (!belleTrkExtra) {
309  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
310  return Const::doubleNaN;
311  }
312  return belleTrkExtra->getACCPe();
313  }
314 
315  double BelleACCQuality(const Particle* particle)
316  {
317  auto belleTrkExtra = getBelleTrkExtraInfoFromParticle(particle);
318  if (!belleTrkExtra) {
319  B2WARNING("Cannot find BelleTrkExtra, did you forget to enable BelleTrkExtra during the conversion?");
320  return Const::doubleNaN;
321  }
322  return belleTrkExtra->getACCQuality();
323  }
324 
325 
326 
327  VARIABLE_GROUP("Belle Variables");
328 
329  REGISTER_VARIABLE("goodBelleKshort", goodBelleKshort, R"DOC(
330 [Legacy] GoodKs Returns true if a :math:`K_{S}^0\to\pi\pi` candidate passes the Belle algorithm:
331 a momentum-binned selection including requirements on impact parameter of, and
332 angle between the daughter pions as well as separation from the vertex and
333 flight distance in the transverse plane.
334 
335 .. seealso:: `BELLE2-NOTE-PH-2018-017 <https://docs.belle2.org/record/957>`_
336 )DOC");
337 
338  REGISTER_VARIABLE("goodBelleLambda", goodBelleLambda, R"DOC(
339 [Legacy] Returns 2.0, 1.0, 0.0 as an indication of goodness of :math:`\Lambda^0` candidates,
340 based on:
341 
342 * The distance of the two daughter tracks at their interception at z axis,
343 * the minimum distance of the daughter tracks and the IP in xy plane,
344 * the difference of the azimuthal angle of the vertex vector and the momentum vector,
345 * and the flight distance of the Lambda0 candidates in xy plane.
346 
347 It reproduces the ``goodLambda()`` function in Belle.
348 
349 ``goodBelleLambda`` selection 1 (selected with: ``goodBelleLambda>0``) maximizes the signal significance after applying
350 ``atcPIDBelle(4,2) > 0.6``, while ``goodBelleLambda`` selection 2 (``goodBelleLambda>1``) is tighter and maximizes the signal
351 significance of a :math:`\Lambda^0` sample without any proton PID cut. However, it might still be beneficial to apply a proton PID
352 cut on top of it. Which combination of proton PID cut and ``goodBelleLambda`` selection scenario is ideal, is probably
353 analysis-dependent.
354 
355 .. warning:: ``goodBelleLambda`` is not optimized or tested on Belle II data.
356 
357 See Also:
358  * `BN-684`_ Lambda selection at Belle. K F Chen et al.
359  * The ``FindLambda`` class can be found at ``/belle_legacy/findLambda/findLambda.h``
360 
361 .. _BN-684: https://belle.kek.jp/secured/belle_note/gn684/bn684.ps.gz
362 
363 )DOC");
364 
365  REGISTER_VARIABLE("goodBelleGamma", goodBelleGamma, R"DOC(
366 [Legacy] Returns 1.0 if the photon candidate passes the simple region dependent
367 energy selection for Belle data and MC.
368 
369 .. math::
370 
371  E > 50 \textrm{ MeV; barrel}\\
372  E > 100 \textrm{ MeV; forward endcap}\\
373  E > 150 \textrm{ MeV; backward endcap}
374 )DOC");
375 
376  REGISTER_VARIABLE("BelleFirstCDCHitX", BelleFirstCDCHitX, R"DOC(
377 [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.)
378 
379 )DOC","cm");
380 
381  REGISTER_VARIABLE("BelleFirstCDCHitY", BelleFirstCDCHitY, R"DOC(
382 [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.)
383 
384 )DOC","cm");
385 
386  REGISTER_VARIABLE("BelleFirstCDCHitZ", BelleFirstCDCHitZ, R"DOC(
387 [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.)
388 
389 )DOC","cm");
390 
391  REGISTER_VARIABLE("BelleLastCDCHitX", BelleLastCDCHitX, R"DOC(
392 [Legacy] Returns x component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
393 
394 )DOC","cm");
395 
396  REGISTER_VARIABLE("BelleLastCDCHitY", BelleLastCDCHitY, R"DOC(
397 [Legacy] Returns y component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
398 
399 )DOC","cm");
400 
401  REGISTER_VARIABLE("BelleLastCDCHitZ", BelleLastCDCHitZ, R"DOC(
402 [Legacy] Returns z component of end point of the track near the last CDC hit. (Belle only, originally stored in mdst_trk_fit.)
403 
404 )DOC","cm");
405 
406  REGISTER_VARIABLE("BellePi0SigM", BellePi0InvariantMassSignificance, R"DOC(
407 [Legacy] Returns the significance of the :math:`\pi^0` mass used in the FEI for B2BII.
408 The significance is calculated as the difference between the reconstructed and the nominal mass divided by the mass uncertainty:
409 
410 .. math::
411  \frac{m_{\gamma\gamma} - m_{\pi^0}^\textrm{PDG}}{\sigma_{m_{\gamma\gamma}}}
412 
413 Since the :math:`\pi^0`'s covariance matrix for B2BII is empty, the latter is calculated using the photon daughters' covariance matrices.
414  )DOC");
415 
416  REGISTER_VARIABLE("BelleTof", BelleTof, R"DOC(
417 [Legacy] Returns the time of flight of a track. (Belle only).
418 
419 )DOC", "ns");
420 
421  REGISTER_VARIABLE("BelleTofQuality", BelleTofQuality, R"DOC(
422 [Legacy] Returns the quality flag of the time of flight of a track. Original description from the panther table: 0 if consistency between z of hit by charge Q and corrected times, 1 if zhit from Q NOT consistent with zhit from and correct times. (Belle only).
423 )DOC");
424 
425  REGISTER_VARIABLE("BelleTofSigma", BelleTofSigma, R"DOC(
426 [Legacy] Returns the expected resolution on the time of flight of a track. (Belle only).
427 
428 )DOC", "ns");
429 
430  REGISTER_VARIABLE("BellePathLength", BellePathLength, R"DOC(
431 [Legacy] Returns the track path length. This is defined from the closest point to the z-axis up to TOF counter. (Belle only).
432 
433 )DOC", "cm");
434 
435  REGISTER_VARIABLE("BelledEdx", BelledEdx, R"DOC(
436 [Legacy] Returns the dE/dx measured in the CDC. (Belle only).
437 
438 )DOC", "keV/cm");
439 
440  REGISTER_VARIABLE("BelledEdxQuality", BelledEdxQuality, R"DOC(
441 [Legacy] Returns the quality flag of the dE/dx measured in the CDC. Sadly no information about the code meaning is given in the original panther tables. (Belle only).
442 )DOC");
443 
444  REGISTER_VARIABLE("BelleACCnPe", BelleACCnPe, R"DOC(
445 [Legacy] Returns the number of photo-electrons associated to the track in the ACC. (Belle only).
446 )DOC");
447 
448  REGISTER_VARIABLE("BelleACCQuality", BelleACCQuality, R"DOC(
449 [Legacy] Returns the ACC quality flag. Original definition in the panther tables: if 0 normal, if 1 the track is out of ACC acceptance. (Belle only).
450 )DOC");
451 
452 
453  // this is defined in ECLVariables.{h,cc}
454  REGISTER_VARIABLE("clusterBelleQuality", eclClusterDeltaL, R"DOC(
455 [Legacy] Returns ECL cluster's quality indicating a good cluster in GSIM (stored in deltaL of ECL cluster object).
456 Belle analysis typically used clusters with quality == 0 in their :math:`E_{\text{extra ECL}}` (Belle only).
457 )DOC");
458  }
460 }
int getPDGCode() const
PDG code.
Definition: Const.h:464
static const ParticleType Lambda
Lambda particle.
Definition: Const.h:670
static const ParticleType Kshort
K^0_S particle.
Definition: Const.h:668
static const double doubleNaN
quiet_NaN
Definition: Const.h:694
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.