Belle II Software  light-2205-abys
TrackVariables.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 includes
10 #include <analysis/variables/TrackVariables.h>
11 
12 // include VariableManager
13 #include <analysis/VariableManager/Manager.h>
14 
15 #include <analysis/dataobjects/Particle.h>
16 
17 // framework - DataStore
18 #include <framework/datastore/StoreObjPtr.h>
19 #include <framework/dataobjects/Helix.h>
20 
21 // dataobjects from the MDST
22 #include <mdst/dataobjects/Track.h>
23 #include <mdst/dataobjects/MCParticle.h>
24 #include <mdst/dataobjects/TrackFitResult.h>
25 #include <mdst/dataobjects/EventLevelTrackingInfo.h>
26 #include <mdst/dataobjects/HitPatternVXD.h>
27 #include <mdst/dataobjects/ECLCluster.h>
28 
29 // framework aux
30 #include <framework/logging/Logger.h>
31 
32 #include <cmath>
33 
34 namespace Belle2 {
39  namespace Variable {
40 
41  static const double realNaN = std::numeric_limits<double>::quiet_NaN();
42  static const B2Vector3D vecNaN(realNaN, realNaN, realNaN);
43 
44  double trackNHits(const Particle* part, const Const::EDetector& det)
45  {
46  auto trackFit = part->getTrackFitResult();
47  if (!trackFit) return realNaN;
48 
49  // Before release-05 (MC13 + proc 11 and older) the hit patterns of TrackFitResults for V0s from the V0Finder were set to 0.
50  // Then, we have to take the detour via the related track to access the number of track hits.
51  if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
52  trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
53  }
54  if (det == Const::EDetector::CDC) {
55  return trackFit->getHitPatternCDC().getNHits();
56  } else if (det == Const::EDetector::SVD) {
57  return trackFit->getHitPatternVXD().getNSVDHits();
58  } else if (det == Const::EDetector::PXD) {
59  return trackFit->getHitPatternVXD().getNPXDHits();
60  } else {
61  return realNaN;
62  }
63  }
64 
65  double trackNCDCHits(const Particle* part)
66  {
67  return trackNHits(part, Const::EDetector::CDC);
68  }
69 
70  double trackNSVDHits(const Particle* part)
71  {
72  return trackNHits(part, Const::EDetector::SVD);
73  }
74 
75  double trackNPXDHits(const Particle* part)
76  {
77  return trackNHits(part, Const::EDetector::PXD);
78  }
79 
80  double trackNVXDHits(const Particle* part)
81  {
82  return trackNPXDHits(part) + trackNSVDHits(part);
83  }
84 
85  double trackNDF(const Particle* part)
86  {
87  auto trackFit = part->getTrackFitResult();
88  if (!trackFit) return realNaN;
89  return trackFit->getNDF();
90  }
91 
92  double trackChi2(const Particle* part)
93  {
94  auto trackFit = part->getTrackFitResult();
95  if (!trackFit) return realNaN;
96  return trackFit->getChi2();
97  }
98 
99  double trackFirstSVDLayer(const Particle* part)
100  {
101  auto trackFit = part->getTrackFitResult();
102  if (!trackFit) return realNaN;
103  // Before release-05 (MC13 + proc 11 and older) the hit patterns of TrackFitResults for V0s from the V0Finder were set to 0.
104  // Then, we have to take the detour via the related track to access the real pattern and get the first SVD layer if available.
105  if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
106  trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
107  }
108  return trackFit->getHitPatternVXD().getFirstSVDLayer();
109  }
110 
111  double trackFirstPXDLayer(const Particle* part)
112  {
113  auto trackFit = part->getTrackFitResult();
114  if (!trackFit) return realNaN;
115  // Before release-05 (MC13 + proc 11 and older) the hit patterns of TrackFitResults for V0s from the V0Finder were set to 0.
116  // Then, we have to take the detour via the related track to access the real pattern and get the first PXD layer if available.
117  if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
118  trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
119  }
120  return trackFit->getHitPatternVXD().getFirstPXDLayer(HitPatternVXD::PXDMode::normal);
121  }
122 
123  double trackFirstCDCLayer(const Particle* part)
124  {
125  auto trackFit = part->getTrackFitResult();
126  if (!trackFit) return realNaN;
127  // Before release-05 (MC13 + proc 11 and older) the hit patterns of TrackFitResults for V0s from the V0Finder were set to 0.
128  // Then, we have to take the detour via the related track to access the real pattern and get the first CDC layer if available.
129  if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
130  trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
131  }
132  return trackFit->getHitPatternCDC().getFirstLayer();
133  }
134 
135  double trackLastCDCLayer(const Particle* part)
136  {
137  auto trackFit = part->getTrackFitResult();
138  if (!trackFit) return realNaN;
139  // Before release-05 (MC13 + proc 11 and older) the hit patterns of TrackFitResults for V0s from the V0Finder were set to 0.
140  // Then, we have to take the detour via the related track to access the real pattern and get the last CDC layer if available.
141  if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
142  trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
143  }
144  return trackFit->getHitPatternCDC().getLastLayer();
145  }
146 
147  double trackD0(const Particle* part)
148  {
149  auto trackFit = part->getTrackFitResult();
150  if (!trackFit) return realNaN;
151  return trackFit->getD0();
152  }
153 
154  double trackPhi0(const Particle* part)
155  {
156  auto trackFit = part->getTrackFitResult();
157  if (!trackFit) return realNaN;
158  return trackFit->getPhi0();
159  }
160 
161  double trackOmega(const Particle* part)
162  {
163  auto trackFit = part->getTrackFitResult();
164  if (!trackFit) return realNaN;
165  return trackFit->getOmega();
166  }
167 
168  double trackZ0(const Particle* part)
169  {
170  auto trackFit = part->getTrackFitResult();
171  if (!trackFit) return realNaN;
172  return trackFit->getZ0();
173  }
174 
175  double trackTanLambda(const Particle* part)
176  {
177  auto trackFit = part->getTrackFitResult();
178  if (!trackFit) return realNaN;
179  return trackFit->getTanLambda();
180  }
181 
182  double trackD0Error(const Particle* part)
183  {
184  auto trackFit = part->getTrackFitResult();
185  if (!trackFit) return realNaN;
186 
187  double errorSquared = trackFit->getCovariance5()[0][0];
188  if (errorSquared <= 0) return realNaN;
189  return sqrt(errorSquared);
190  }
191 
192  double trackPhi0Error(const Particle* part)
193  {
194  auto trackFit = part->getTrackFitResult();
195  if (!trackFit) return realNaN;
196 
197  double errorSquared = trackFit->getCovariance5()[1][1];
198  if (errorSquared <= 0) return realNaN;
199  return sqrt(errorSquared);
200  }
201 
202  double trackOmegaError(const Particle* part)
203  {
204  auto trackFit = part->getTrackFitResult();
205  if (!trackFit) return realNaN;
206 
207  double errorSquared = trackFit->getCovariance5()[2][2];
208  if (errorSquared <= 0) return realNaN;
209  return sqrt(errorSquared);
210  }
211 
212  double trackZ0Error(const Particle* part)
213  {
214  auto trackFit = part->getTrackFitResult();
215  if (!trackFit) return realNaN;
216 
217  double errorSquared = trackFit->getCovariance5()[3][3];
218  if (errorSquared <= 0) return realNaN;
219  return sqrt(errorSquared);
220  }
221 
222  double trackTanLambdaError(const Particle* part)
223  {
224  auto trackFit = part->getTrackFitResult();
225  if (!trackFit) return realNaN;
226 
227  double errorSquared = trackFit->getCovariance5()[4][4];
228  if (errorSquared <= 0) return realNaN;
229  return sqrt(errorSquared);
230  }
231 
232  double trackFitCovariance(const Particle* particle, const std::vector<double>& indices)
233  {
234  if (indices.size() != 2) {
235  B2FATAL("Exactly two indices must be provided to the variable trackFitCovariance!");
236  }
237  if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
238  B2FATAL("The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
239  }
240  auto trackFit = particle->getTrackFitResult();
241  if (!trackFit) return realNaN;
242  return trackFit->getCovariance5()[indices[0]][indices[1]];
243  }
244 
245  double trackPValue(const Particle* part)
246  {
247  auto trackFit = part->getTrackFitResult();
248  if (!trackFit) return realNaN;
249  return trackFit->getPValue();
250  }
251 
252  double trackFitHypothesisPDG(const Particle* part)
253  {
254  auto trackFit = part->getTrackFitResult();
255  if (!trackFit) return realNaN;
256  return trackFit->getParticleType().getPDGCode();
257  }
258 
259  double trackNECLClusters(const Particle* part)
260  {
261  const Track* track = part->getTrack();
262  if (!track) return realNaN;
263 
264  // count the number of nPhotons hypothesis ecl clusters
265  int count = 0;
266  for (const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
267  if (cluster.hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons))
268  ++count;
269  return count;
270  }
271 
272  // used in trackHelixExtTheta and trackHelixExtPhi
273  B2Vector3D getPositionOnHelix(const Particle* part, const std::vector<double>& pars)
274  {
275  const auto nParams = pars.size();
276  if (nParams != 3 && nParams != 4) {
277  B2FATAL("Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required.");
278  }
279 
280  const double r = pars[0];
281  const double zfwd = pars[1];
282  const double zbwd = pars[2];
283  const auto useHighestProbMass = (nParams == 4) ? bool(pars[3]) : false;
284 
285  const Track* track = part->getTrack();
286 
287  if (!track) return vecNaN;
288 
289  auto highestProbMass = (useHighestProbMass) ? part->getMostLikelyTrackFitResult().first : Const::ChargedStable(std::abs(
290  part->getPDGCode()));
291 
292  const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
293 
294  // get helix and parameters
295  const double z0 = trackFit->getZ0();
296  const double tanlambda = trackFit->getTanLambda();
297  const Helix h = trackFit->getHelix();
298 
299  // extrapolate to radius
300  const double arcLength = h.getArcLength2DAtCylindricalR(r);
301  const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
302 
303  // extrapolate to FWD z
304  const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
305 
306  // extrapolate to BWD z
307  const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
308 
309  // pick smallest arclength
310  const double l = std::min({lHelixRadius, lFWD, lBWD});
311 
312  return h.getPositionAtArcLength2D(l);
313  }
314 
315  // returns extrapolated theta position based on helix parameters
316  double trackHelixExtTheta(const Particle* part, const std::vector<double>& pars)
317  {
318  const auto nParams = pars.size();
319  if (nParams != 3 && nParams != 4) {
320  B2FATAL("Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
321  }
322  B2Vector3D position = getPositionOnHelix(part, pars);
323  if (position == vecNaN) return realNaN;
324  return position.Theta();
325  }
326 
327  // returns extrapolated phi position based on helix parameters
328  double trackHelixExtPhi(const Particle* part, const std::vector<double>& pars)
329  {
330  const auto nParams = pars.size();
331  if (nParams != 3 && nParams != 4) {
332  B2FATAL("Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
333  }
334  B2Vector3D position = getPositionOnHelix(part, pars);
335  if (position == vecNaN) return realNaN;
336  return position.Phi();
337  }
338 
339 
340  /***************************************************
341  * Event level tracking quantities
342  */
343 
344  // The number of CDC hits in the event not assigned to any track
345  double nExtraCDCHits(const Particle*)
346  {
347  StoreObjPtr<EventLevelTrackingInfo> elti;
348  if (!elti) return realNaN;
349  return elti->getNCDCHitsNotAssigned();
350  }
351 
352  // The number of CDC hits in the event not assigned to any track nor very
353  // likely beam background (i.e. hits that survive a cleanup selection)
354  double nExtraCDCHitsPostCleaning(const Particle*)
355  {
356  StoreObjPtr<EventLevelTrackingInfo> elti;
357  if (!elti) return realNaN;
358  return elti->getNCDCHitsNotAssignedPostCleaning();
359  }
360 
361  // Check for the presence of a non-assigned hit in the specified CDC layer
362  double hasExtraCDCHitsInLayer(const Particle*, const std::vector<double>& layer)
363  {
364  StoreObjPtr<EventLevelTrackingInfo> elti;
365  if (!elti) return realNaN;
366  int ilayer = std::lround(layer[0]);
367  return elti->hasCDCLayer(ilayer);
368  }
369 
370  // Check for the presence of a non-assigned hit in the specified CDC SuperLayer
371  double hasExtraCDCHitsInSuperLayer(const Particle*, const std::vector<double>& layer)
372  {
373  StoreObjPtr<EventLevelTrackingInfo> elti;
374  if (!elti) return realNaN;
375  int ilayer = std::lround(layer[0]);
376  return elti->hasCDCSLayer(ilayer);
377  }
378 
379  // The number of segments that couldn't be assigned to any track
380  double nExtraCDCSegments(const Particle*)
381  {
382  StoreObjPtr<EventLevelTrackingInfo> elti;
383  if (!elti) return realNaN;
384  return elti->getNCDCSegments();
385  }
386 
387  // The number of VXD hits not assigned to any track in the specified layer
388  double nExtraVXDHitsInLayer(const Particle*, const std::vector<double>& layer)
389  {
390  StoreObjPtr<EventLevelTrackingInfo> elti;
391  if (!elti) return realNaN;
392  int ilayer = std::lround(layer[0]);
393  return elti->getNVXDClustersInLayer(ilayer);
394  }
395 
396  // The number of VXD hits not assigned to any track
397  double nExtraVXDHits(const Particle*)
398  {
399  StoreObjPtr<EventLevelTrackingInfo> elti;
400  if (!elti) return realNaN;
401  double out = 0.0;
402  for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
403  out += elti->getNVXDClustersInLayer(ilayer);
404  return out;
405  }
406 
407  // time of first SVD sample relative to event T0
408  double svdFirstSampleTime(const Particle*)
409  {
410  StoreObjPtr<EventLevelTrackingInfo> elti;
411  if (!elti) return realNaN;
412  return elti->getSVDFirstSampleTime();
413  }
414 
415  // A flag set by the tracking if there is reason to assume there was a track
416  // in the event missed by the tracking or the track finding was (partly) aborted
417  // for this event. Further information about this can be obtained from the flagBlock
418  // of the EventLevelTrackingInfo object.
419  double trackFindingFailureFlag(const Particle*)
420  {
421  StoreObjPtr<EventLevelTrackingInfo> elti;
422  if (!elti) return realNaN;
423  return elti->hasAnErrorFlag();
424  }
425 
426  double getHelixParameterPullAtIndex(const Particle* particle, const int index)
427  {
428  if (!particle) return realNaN;
429 
430  const MCParticle* mcparticle = particle->getMCParticle();
431  if (!mcparticle) return realNaN;
432 
433  const Belle2::TrackFitResult* trackfit = particle->getTrackFitResult();
434  if (!trackfit) return realNaN;
435 
436  const Belle2::UncertainHelix measHelix = trackfit->getUncertainHelix();
437  const TMatrixDSym measCovariance = measHelix.getCovariance();
438  const B2Vector3D mcProdVertex = mcparticle->getVertex();
439  const B2Vector3D mcMomentum = mcparticle->getMomentum();
440 
441  const double BzAtProdVertex = Belle2::BFieldManager::getFieldInTesla(mcProdVertex).Z();
442  const double mcParticleCharge = mcparticle->getCharge();
443  const Belle2::Helix mcHelix = Belle2::Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
444 
445  const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
446  const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
447  const std::vector<double> measErrSquare = {measCovariance[0][0], measCovariance[1][1], measCovariance[2][2], measCovariance[3][3], measCovariance[4][4]};
448 
449  return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measErrSquare.at(index));
450  }
451 
452  double getHelixD0Pull(const Particle* part)
453  {
454  return getHelixParameterPullAtIndex(part, 0);
455  }
456 
457  double getHelixPhi0Pull(const Particle* part)
458  {
459  return getHelixParameterPullAtIndex(part, 1);
460  }
461 
462  double getHelixOmegaPull(const Particle* part)
463  {
464  return getHelixParameterPullAtIndex(part, 2);
465  }
466 
467  double getHelixZ0Pull(const Particle* part)
468  {
469  return getHelixParameterPullAtIndex(part, 3);
470  }
471  double getHelixTanLambdaPull(const Particle* part)
472  {
473  return getHelixParameterPullAtIndex(part, 4);
474  }
475 
476 
477  VARIABLE_GROUP("Tracking");
478  REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R"DOC(
479 The pull of the tracking parameter :math:`d_0` for the reconstructed
480 pattern-recognition track, with respect to the MC track. That is:
481 
482 .. math::
483 
484  \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
485 
486 .. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
487 
488 Returns NaN if no MC particle is related or if called on something other than a
489 track-based particle.
490  )DOC");
491  REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R"DOC(
492 The pull of the tracking parameter :math:`\phi_0` for the reconstructed
493 pattern-recognition track, with respect to the MC track. That is:
494 
495 .. math::
496 
497  \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
498 
499 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
500 
501 Returns NaN if no MC particle is related or if called on something other than a
502 track-based particle.
503  )DOC");
504  REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R"DOC(
505 The pull of the tracking parameter :math:`\omega` for the reconstructed
506 pattern-recognition track, with respect to the MC track. That is:
507 
508 .. math::
509 
510  \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
511 
512 .. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
513 
514 Returns NaN if no MC particle is related or if called on something other than a
515 track-based particle.
516  )DOC");
517  REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R"DOC(
518 The pull of the tracking parameter :math:`z_0` for the reconstructed
519 pattern-recognition track, with respect to the MC track. That is:
520 
521 .. math::
522 
523  \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
524 
525 .. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
526 
527 Returns NaN if no MC particle is related or if called on something other than a
528 track-based particle.
529  )DOC");
530  REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R"DOC(
531 The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
532 pattern-recognition track, with respect to the MC track. That is:
533 
534 .. math::
535 
536  \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
537 
538 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
539 
540 Returns NaN if no MC particle is related or if called on something other than a
541 track-based particle.
542  )DOC");
543  REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
544  "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
545  REGISTER_VARIABLE("nSVDHits", trackNSVDHits,
546  "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
547  REGISTER_VARIABLE("nPXDHits", trackNPXDHits,
548  "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
549  REGISTER_VARIABLE("nVXDHits", trackNVXDHits,
550  "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
551  REGISTER_VARIABLE("ndf", trackNDF, R"DOC(
552 Returns the number of degrees of freedom of the track fit.
553 
554 .. note::
555 
556  Note that this is not simply the number of hits -5 due to outlier hit
557  rejection.
558 
559 Returns NaN if called for something other than a track-based particle, or for
560 mdst files processed with basf2 versions older than ``release-05-01``.
561  )DOC");
562  REGISTER_VARIABLE("chi2", trackChi2, R"DOC(
563 Returns the :math:`\chi^2` of the track fit. This is actually computed based on
564 :b2:var:`pValue` and :b2:var:`ndf`.
565 
566 .. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
567 
568 Returns NaN if called for something other than a track-based particle, or for
569 mdst files processed with basf2 versions older than ``release-05-01``.
570  )DOC");
571  REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
572  "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
573  REGISTER_VARIABLE("firstPXDLayer", trackFirstPXDLayer,
574  "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
575  REGISTER_VARIABLE("firstCDCLayer", trackFirstCDCLayer,
576  "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
577  REGISTER_VARIABLE("lastCDCLayer", trackLastCDCLayer,
578  "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
579  REGISTER_VARIABLE("d0", trackD0, R"DOC(
580 Returns the tracking parameter :math:`d_0`, the signed distance to the
581 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
582 
583 .. note::
584 
585  Tracking parameters are with respect to the origin (0,0,0). For the
586  POCA with respect to the measured beam interaction point, see
587  :b2:var:`dr` (you probably want this unless you're doing a tracking
588  study or some debugging).
589 
590 Returns NaN if called for something other than a track-based particle.
591  )DOC", "cm");
592  REGISTER_VARIABLE("phi0", trackPhi0, R"DOC(
593 Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
594 momentum in the :math:`r-\phi` plane.
595 
596 Returns NaN if called for something other than a track-based particle.
597  )DOC", "rad");
598  REGISTER_VARIABLE("omega", trackOmega, R"DOC(
599 Returns the tracking parameter :math:`\omega`, the curvature of the track.
600 
601 Returns NaN if called for something other than a track-based particle.
602  )DOC", ":math:`\\text{cm}^{-1}`");
603  REGISTER_VARIABLE("z0", trackZ0, R"DOC(
604 Returns the tracking parameter :math:`z_0`, the z-coordinate of the
605 point-of-closest-approach (POCA).
606 
607 .. note::
608 
609  Tracking parameters are with respect to the origin (0,0,0). For the
610  POCA with respect to the measured beam interaction point, see
611  :b2:var:`dz` (you probably want this unless you're doing a tracking
612  study or some debugging).
613 
614 Returns NaN if called for something other than a track-based particle.
615  )DOC", "cm");
616  REGISTER_VARIABLE("tanLambda", trackTanLambda, R"DOC(
617 Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
618 
619 Returns NaN if called for something other than a track-based particle.
620  )DOC");
621  REGISTER_VARIABLE("d0Err", trackD0Error, R"DOC(
622 Returns the uncertainty on :math:`d_0`, the signed distance to the
623 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
624 
625 .. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
626 
627 Returns NaN if called for something other than a track-based particle.
628  )DOC", "cm");
629  REGISTER_VARIABLE("phi0Err", trackPhi0Error, R"DOC(
630 Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
631 in the :math:`r-\phi` plane.
632 
633 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
634 
635 Returns NaN if called for something other than a track-based particle.
636  )DOC", "rad");
637  REGISTER_VARIABLE("omegaErr", trackOmegaError, R"DOC(
638 Returns the uncertainty on :math:`\omega`, the curvature of the track.
639 
640 .. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
641 
642 Returns NaN if called for something other than a track-based particle.
643  )DOC", ":math:`\\text{cm}^{-1}`");
644  REGISTER_VARIABLE("z0Err", trackZ0Error, R"DOC(
645 Returns the uncertainty on :math:`z_0`, the z-coordinate of the
646 point-of-closest-approach (POCA).
647 
648 .. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
649 
650 Returns NaN if called for something other than a track-based particle."
651  )DOC", "cm");
652  REGISTER_VARIABLE("tanLambdaErr", trackTanLambdaError, R"DOC(
653 Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
654 :math:`r-z` plane.
655 
656 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
657 
658 Returns NaN if called for something other than a track-based particle.
659  )DOC");
660  REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R"DOC(
661  The track fit covariance matrix element corresponding to the two indices is returned.
662  This is the association between integers and parameters:
663 
664  * 0: :math:`d_0`
665  * 1: :math:`\phi_0`
666  * 2: :math:`\omega`
667  * 3: :math:`z_0`
668  * 4: :math:`\tan\lambda`
669 
670  .. note::
671 
672  The covariance is returned. This means that the return value can be negative.
673  Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
674  when selecting the diagonal entries.
675 
676  )DOC");
677  REGISTER_VARIABLE("pValue", trackPValue, R"DOC(
678 The :math:`\chi^2` probability of the **track** fit.
679 
680 .. note::
681 
682  This is the p-value of the track-fit. It does not get updated after
683  vertex fitting or kinematic fitting, and is meaningless for composite
684  particles.
685 
686  See :b2:var:`chiProb` (you probably want this for high-level analysis).
687 
688 Returns NaN if called for something other than a track-based particle.
689  )DOC");
690  REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R"DOC(
691 Returns the PDG code of the track hypothesis actually used for the fit.
692 Returns NaN if called for something other than a track-based particle.
693  )DOC");
694  REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R"DOC(
695 Returns a count of the number of ECLClusters matched to the track. This is
696 always 0 or 1 with newer versions of ECL reconstruction.
697 
698 .. note::
699 
700  For high-level analysis it is recommended to require the presence of a
701  matched ECL cluster along with a minimum energy requirement. A
702  track-based particle will have a clusterE if it is matched (NaN if
703  there is no cluster match for the track.
704 
705  .. code-block:: python
706 
707  import modularAnalysis as ma
708  # minimum energy of 200 MeV
709  ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
710 
711  # these two are equivalent
712  ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
713  ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
714 
715 Returns NaN if called for something other than a track-based particle.
716  )DOC");
717  REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
718  "Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.",
719  "rad");
720  REGISTER_VARIABLE("helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
721  "Returns phi of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.",
722  "rad");
723 
724  REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R"DOC(
725 [Eventbased] The number of CDC hits in the event not assigned to any track.
726 
727 Returns NaN if there is no event-level tracking information available.
728  )DOC");
729  REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R"DOC(
730 [Eventbased] Returns a count of the number of CDC hits in the event not assigned
731 to any track nor very likely beam background (i.e. hits that survive a cleanup
732 selection).
733 
734 Returns NaN if there is no event-level tracking information available.
735  )DOC");
736  REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R"DOC(
737 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
738 0 otherwise.
739 
740 Returns NaN if there is no event-level tracking information available.
741  )DOC");
742  REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R"DOC(
743 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
744 SuperLayer, 0 otherwise.
745 
746 Returns NaN if there is no event-level tracking information available.
747  )DOC");
748  REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R"DOC(
749 [Eventbased] Returns the number of CDC segments not assigned to any track.
750 
751 Returns NaN if there is no event-level tracking information available.
752  )DOC");
753  // TODO: once the Tracking group fill the dataobject these can be
754  // uncommented - at the moment they are not filled, so leave out
755  //REGISTER_VARIABLE("nExtraVXDHitsInLayer(i)", nExtraVXDHitsInLayer,
756  //"[Eventbased] The number VXD hits not assigned in the specified VXD layer");
757  //REGISTER_VARIABLE("nExtraVXDHits", nExtraVXDHits, "[Eventbased] The number of VXD hits not assigned to any track");
758  //REGISTER_VARIABLE("svdFirstSampleTime", svdFirstSampleTime, "[Eventbased] The time of first SVD sample relatvie to event T0");
759  REGISTER_VARIABLE("trackFindingFailureFlag", trackFindingFailureFlag, R"DOC(
760 [Eventbased] Returns a flag set by the tracking if there is reason to assume
761 there was a track in the event missed by the tracking, or the track finding was
762 (partly) aborted for this event.
763 
764 Returns NaN if there is no event-level tracking information available.
765  )DOC");
766  }
768 }
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:429
static B2Vector3D getFieldInTesla(const B2Vector3D &pos)
return the magnetic field at a given position in Tesla.
Definition: BFieldManager.h:70
EDetector
Enum for identifying the detector components (detector and subdetector).
Definition: Const.h:42
@ c_nPhotons
CR is split into n photons (N1)
This class represents an ideal helix in perigee parameterization.
Definition: Helix.h:59
double getOmega() const
Getter for omega, which is a signed curvature measure of the track.
Definition: Helix.h:387
double getD0() const
Getter for d0, which is the signed distance to the perigee in the r-phi plane.
Definition: Helix.h:372
double getTanLambda() const
Getter for tan lambda, which is the z over two dimensional arc length slope of the track.
Definition: Helix.h:393
double getZ0() const
Getter for z0, which is the z coordinate of the perigee.
Definition: Helix.h:390
double getPhi0() const
Getter for phi0, which is the azimuth angle of the transverse momentum at the perigee.
Definition: Helix.h:378
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
Definition: Particle.cc:934
Values of the result of a track fit with a given particle hypothesis.
UncertainHelix getUncertainHelix() const
Conversion to framework Uncertain Helix (i.e., with covariance).
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
const TMatrixDSym & getCovariance() const
Getter for covariance matrix of perigee parameters in matrix form.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:502
Abstract base class for different kinds of events.
Definition: ClusterUtils.h:23