Belle II Software  release-05-01-25
ECLVariables.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2018 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Torben Ferber *
7  * Alon Hershenhorn *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 // Own include
13 #include <analysis/variables/ECLVariables.h>
14 
15 //framework
16 #include <framework/logging/Logger.h>
17 #include <framework/datastore/StoreArray.h>
18 
19 //analysis
20 #include <analysis/VariableManager/Manager.h>
21 #include <analysis/dataobjects/Particle.h>
22 #include <analysis/dataobjects/ECLEnergyCloseToTrack.h>
23 #include <analysis/dataobjects/ECLTRGInformation.h>
24 #include <analysis/dataobjects/ECLTriggerCell.h>
25 #include <analysis/utility/ReferenceFrame.h>
26 #include <analysis/ClusterUtility/ClusterUtils.h>
27 
28 //MDST
29 #include <mdst/dataobjects/ECLCluster.h>
30 #include <mdst/dataobjects/Track.h>
31 #include <mdst/dataobjects/EventLevelClusteringInfo.h>
32 
33 #include <cmath>
34 #include <stack>
35 
36 namespace Belle2 {
41  namespace Variable {
42 
43  double eclPulseShapeDiscriminationMVA(const Particle* particle)
44  {
45  const ECLCluster* cluster = particle->getECLCluster();
46  if (cluster) {
47  if (eclClusterHasPulseShapeDiscrimination(particle)) {
48  return cluster->getPulseShapeDiscriminationMVA();
49  } else {
50  return -1.0;
51  }
52  }
53  return std::numeric_limits<float>::quiet_NaN();
54  }
55 
56  double eclClusterNumberOfHadronDigits(const Particle* particle)
57  {
58 
59  const ECLCluster* cluster = particle->getECLCluster();
60  if (cluster) {
61  if (eclClusterHasPulseShapeDiscrimination(particle)) {
62  return cluster->getNumberOfHadronDigits();
63  } else
64  return -1.0;
65  }
66  return std::numeric_limits<float>::quiet_NaN();
67  }
68 
69  double eclClusterDetectionRegion(const Particle* particle)
70  {
71 
72  const ECLCluster* cluster = particle->getECLCluster();
73  if (cluster)
74  return cluster->getDetectorRegion();
75 
76  return std::numeric_limits<float>::quiet_NaN();
77  }
78 
79  double eclClusterIsolation(const Particle* particle)
80  {
81 
82  const ECLCluster* cluster = particle->getECLCluster();
83  if (cluster)
84  return cluster->getMinTrkDistance();
85 
86  return std::numeric_limits<float>::quiet_NaN();
87  }
88 
89  double eclClusterConnectedRegionID(const Particle* particle)
90  {
91 
92  const ECLCluster* cluster = particle->getECLCluster();
93  if (cluster)
94  return cluster->getConnectedRegionId();
95 
96  return std::numeric_limits<float>::quiet_NaN();
97  }
98 
99  double eclClusterDeltaL(const Particle* particle)
100  {
101 
102  const ECLCluster* cluster = particle->getECLCluster();
103  if (cluster)
104  return cluster->getDeltaL();
105 
106  return std::numeric_limits<float>::quiet_NaN();
107  }
108 
109 
110  double eclClusterErrorE(const Particle* particle)
111  {
112 
113  const ECLCluster* cluster = particle->getECLCluster();
114  if (cluster) {
115  return cluster->getUncertaintyEnergy();
116  }
117  return std::numeric_limits<float>::quiet_NaN();
118  }
119 
120  double eclClusterUncorrectedE(const Particle* particle)
121  {
122 
123  const ECLCluster* cluster = particle->getECLCluster();
124  if (cluster) {
125  return cluster->getEnergyRaw();
126  }
127  return std::numeric_limits<float>::quiet_NaN();
128  }
129 
130  double eclClusterE(const Particle* particle)
131  {
132  const auto& frame = ReferenceFrame::GetCurrent();
133 
134  const ECLCluster* cluster = particle->getECLCluster();
135  if (cluster) {
136  ClusterUtils clutls;
137  TLorentzVector p4Cluster = clutls.GetCluster4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
138 
139  return frame.getMomentum(p4Cluster).E();
140  }
141  return std::numeric_limits<float>::quiet_NaN();
142  }
143 
144  double eclClusterHighestE(const Particle* particle)
145  {
146 
147  const ECLCluster* cluster = particle->getECLCluster();
148  if (cluster) {
149  return cluster->getEnergyHighestCrystal();
150  }
151  return std::numeric_limits<float>::quiet_NaN();
152  }
153 
154  double eclClusterCellId(const Particle* particle)
155  {
156 
157  const ECLCluster* cluster = particle->getECLCluster();
158  if (cluster) {
159  return cluster->getMaxECellId();
160  }
161  return std::numeric_limits<float>::quiet_NaN();
162  }
163 
164  double eclClusterTiming(const Particle* particle)
165  {
166 
167  const ECLCluster* cluster = particle->getECLCluster();
168  if (cluster) {
169  return cluster->getTime();
170  }
171  return std::numeric_limits<float>::quiet_NaN();
172  }
173 
174  double eclClusterHasFailedTiming(const Particle* particle)
175  {
176  const ECLCluster* cluster = particle->getECLCluster();
177  if (cluster) {
178  return cluster->hasFailedFitTime();
179  }
180  return std::numeric_limits<float>::quiet_NaN();
181  }
182 
183  double eclClusterErrorTiming(const Particle* particle)
184  {
185 
186  const ECLCluster* cluster = particle->getECLCluster();
187  if (cluster) {
188  return cluster->getDeltaTime99();
189  }
190  return std::numeric_limits<float>::quiet_NaN();
191  }
192 
193  double eclClusterHasFailedErrorTiming(const Particle* particle)
194  {
195  const ECLCluster* cluster = particle->getECLCluster();
196  if (cluster) {
197  return cluster->hasFailedTimeResolution();
198  }
199  return std::numeric_limits<float>::quiet_NaN();
200  }
201 
202  double eclClusterTheta(const Particle* particle)
203  {
204  const auto& frame = ReferenceFrame::GetCurrent();
205 
206  const ECLCluster* cluster = particle->getECLCluster();
207  if (cluster) {
208  ClusterUtils clutls;
209  TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
210 
211  return frame.getMomentum(p4Cluster).Theta();
212  }
213  return std::numeric_limits<float>::quiet_NaN();
214  }
215 
216  double eclClusterErrorTheta(const Particle* particle)
217  {
218 
219  const ECLCluster* cluster = particle->getECLCluster();
220  if (cluster) {
221  return cluster->getUncertaintyTheta();
222  }
223  return std::numeric_limits<float>::quiet_NaN();
224  }
225 
226  double eclClusterErrorPhi(const Particle* particle)
227  {
228 
229  const ECLCluster* cluster = particle->getECLCluster();
230  if (cluster) {
231  return cluster->getUncertaintyPhi();
232  }
233  return std::numeric_limits<float>::quiet_NaN();
234  }
235 
236  double eclClusterPhi(const Particle* particle)
237  {
238  const auto& frame = ReferenceFrame::GetCurrent();
239 
240  const ECLCluster* cluster = particle->getECLCluster();
241  if (cluster) {
242  ClusterUtils clutls;
243  TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, particle->getECLClusterEHypothesisBit());
244 
245  return frame.getMomentum(p4Cluster).Phi();
246  }
247  return std::numeric_limits<float>::quiet_NaN();
248  }
249 
250  double eclClusterR(const Particle* particle)
251  {
252 
253  const ECLCluster* cluster = particle->getECLCluster();
254  if (cluster) {
255  return cluster->getR();
256  }
257  return std::numeric_limits<float>::quiet_NaN();
258  }
259 
260  double eclClusterE1E9(const Particle* particle)
261  {
262 
263  const ECLCluster* cluster = particle->getECLCluster();
264  if (cluster) {
265  return cluster->getE1oE9();
266  }
267  return std::numeric_limits<float>::quiet_NaN();
268  }
269 
270  double eclClusterE9E21(const Particle* particle)
271  {
272 
273  const ECLCluster* cluster = particle->getECLCluster();
274  if (cluster) {
275  return cluster->getE9oE21();
276  }
277  return std::numeric_limits<float>::quiet_NaN();
278  }
279 
280  double eclClusterAbsZernikeMoment40(const Particle* particle)
281  {
282 
283  const ECLCluster* cluster = particle->getECLCluster();
284  if (cluster) {
285  return cluster->getAbsZernike40();
286  }
287  return std::numeric_limits<float>::quiet_NaN();
288  }
289 
290  double eclClusterAbsZernikeMoment51(const Particle* particle)
291  {
292 
293  const ECLCluster* cluster = particle->getECLCluster();
294  if (cluster) {
295  return cluster->getAbsZernike51();
296  }
297  return std::numeric_limits<float>::quiet_NaN();
298  }
299 
300  double eclClusterZernikeMVA(const Particle* particle)
301  {
302 
303  const ECLCluster* cluster = particle->getECLCluster();
304  if (cluster) {
305  return cluster->getZernikeMVA();
306  }
307  return std::numeric_limits<float>::quiet_NaN();
308  }
309 
310  double eclClusterSecondMoment(const Particle* particle)
311  {
312 
313  const ECLCluster* cluster = particle->getECLCluster();
314  if (cluster) {
315  return cluster->getSecondMoment();
316  }
317  return std::numeric_limits<float>::quiet_NaN();
318  }
319 
320  double eclClusterLAT(const Particle* particle)
321  {
322 
323  const ECLCluster* cluster = particle->getECLCluster();
324  if (cluster) {
325  return cluster->getLAT();
326  }
327  return std::numeric_limits<float>::quiet_NaN();
328  }
329 
330  double eclClusterNHits(const Particle* particle)
331  {
332 
333  const ECLCluster* cluster = particle->getECLCluster();
334  if (cluster) {
335  return cluster->getNumberOfCrystals();
336  }
337  return std::numeric_limits<float>::quiet_NaN();
338  }
339 
340  double eclClusterTrackMatched(const Particle* particle)
341  {
342 
343  const ECLCluster* cluster = particle->getECLCluster();
344  if (cluster) {
345  const Track* track = cluster->getRelatedFrom<Track>();
346 
347  if (track)
348  return 1.0;
349  else
350  return 0.0;
351  }
352  return std::numeric_limits<float>::quiet_NaN();
353  }
354 
355  double nECLClusterTrackMatches(const Particle* particle)
356  {
357  // if no ECL cluster then nan
358  const ECLCluster* cluster = particle->getECLCluster();
359  if (!cluster)
360  return std::numeric_limits<double>::quiet_NaN();
361 
362  // one or more tracks may be matched to charged particles
363  size_t out = cluster->getRelationsFrom<Track>().size();
364  return double(out);
365  }
366 
367  double eclClusterConnectedRegionId(const Particle* particle)
368  {
369  const ECLCluster* cluster = particle->getECLCluster();
370  if (cluster) {
371  return cluster->getConnectedRegionId();
372  }
373  return std::numeric_limits<float>::quiet_NaN();
374  }
375 
376  double eclClusterId(const Particle* particle)
377  {
378  const ECLCluster* cluster = particle->getECLCluster();
379  if (cluster) {
380  return cluster->getClusterId();
381  }
382  return std::numeric_limits<float>::quiet_NaN();
383  }
384 
385  double eclClusterHasNPhotonsHypothesis(const Particle* particle)
386  {
387  const ECLCluster* cluster = particle->getECLCluster();
388  if (cluster) {
389  return cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons);
390  }
391  return std::numeric_limits<float>::quiet_NaN();
392  }
393 
394  double eclClusterHasNeutralHadronHypothesis(const Particle* particle)
395  {
396  const ECLCluster* cluster = particle->getECLCluster();
397  if (cluster) {
398  return cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_neutralHadron);
399  }
400  return std::numeric_limits<float>::quiet_NaN();
401  }
402 
403  double eclClusterHasPulseShapeDiscrimination(const Particle* particle)
404  {
405  const ECLCluster* cluster = particle->getECLCluster();
406  if (cluster) {
407  return cluster->hasPulseShapeDiscrimination();
408  }
409  return std::numeric_limits<float>::quiet_NaN();
410  }
411 
412  double eclClusterTrigger(const Particle* particle)
413  {
414  const ECLCluster* cluster = particle->getECLCluster();
415  if (cluster) {
416  const bool matcher = cluster->hasTriggerClusterMatching();
417 
418  if (matcher) {
419  return cluster->isTriggerCluster();
420  } else {
421  B2WARNING("Particle has an associated ECLCluster but the ECLTriggerClusterMatcher module has not been run!");
422  return -1.;
423  }
424  }
425  return std::numeric_limits<float>::quiet_NaN();
426  }
427 
428  double eclExtTheta(const Particle* particle)
429  {
430 
431  const Track* track = particle->getTrack();
432  if (track) {
433 
434  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
435 
436  if (eclinfo) {
437  return eclinfo->getExtTheta();
438  } else {
439  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
440  return std::numeric_limits<float>::quiet_NaN();
441  }
442  }
443 
444  return std::numeric_limits<float>::quiet_NaN();
445  }
446 
447  double eclExtPhi(const Particle* particle)
448  {
449 
450  const Track* track = particle->getTrack();
451  if (track) {
452 
453  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
454 
455  if (eclinfo) {
456  return eclinfo->getExtPhi();
457  } else {
458  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
459  return std::numeric_limits<float>::quiet_NaN();
460  }
461  }
462 
463  return std::numeric_limits<float>::quiet_NaN();
464  }
465 
466  double eclExtPhiId(const Particle* particle)
467  {
468  const Track* track = particle->getTrack();
469  if (track) {
470 
471  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
472 
473  if (eclinfo) {
474  return eclinfo->getExtPhiId();
475  } else {
476  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
477  return std::numeric_limits<float>::quiet_NaN();
478  }
479  }
480 
481  return std::numeric_limits<float>::quiet_NaN();
482  }
483 
484  double eclEnergy3FWDBarrel(const Particle* particle)
485  {
486 
487  const Track* track = particle->getTrack();
488  if (track) {
489 
490  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
491 
492  if (eclinfo) {
493  return eclinfo->getEnergy3FWDBarrel();
494  } else {
495  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
496  return std::numeric_limits<float>::quiet_NaN();
497  }
498  }
499 
500  return std::numeric_limits<float>::quiet_NaN();
501  }
502 
503  double eclEnergy3FWDEndcap(const Particle* particle)
504  {
505 
506  const Track* track = particle->getTrack();
507  if (track) {
508 
509  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
510 
511  if (eclinfo) {
512  return eclinfo->getEnergy3FWDEndcap();
513  } else {
514  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
515  return std::numeric_limits<float>::quiet_NaN();
516  }
517  }
518 
519  return std::numeric_limits<float>::quiet_NaN();
520  }
521 
522  double eclEnergy3BWDEndcap(const Particle* particle)
523  {
524  const Track* track = particle->getTrack();
525  if (track) {
526 
527  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
528 
529  if (eclinfo) {
530  return eclinfo->getEnergy3BWDEndcap();
531  } else {
532  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
533  return std::numeric_limits<float>::quiet_NaN();
534  }
535  }
536 
537  return std::numeric_limits<float>::quiet_NaN();
538  }
539 
540  double eclEnergy3BWDBarrel(const Particle* particle)
541  {
542 
543  const Track* track = particle->getTrack();
544  if (track) {
545 
546  auto* eclinfo = track->getRelatedTo<ECLEnergyCloseToTrack>();
547 
548  if (eclinfo) {
549  return eclinfo->getEnergy3BWDBarrel();
550  } else {
551  B2WARNING("Relation to ECLEnergyCloseToTrack not found, did you forget to run ECLTrackCalDigitMatchModule?");
552  return std::numeric_limits<float>::quiet_NaN();
553  }
554  }
555 
556  return std::numeric_limits<float>::quiet_NaN();
557  }
558 
559  double weightedAverageECLTime(const Particle* particle)
560  {
561  int nDaughters = particle->getNDaughters();
562  if (nDaughters < 1) {
563  B2WARNING("The provided particle has no daughters!");
564  return std::numeric_limits<float>::quiet_NaN();
565  }
566 
567  double numer = 0, denom = 0;
568  int numberOfClusterDaughters = 0;
569 
570  auto weightedECLTimeAverage = [&numer, &denom, &numberOfClusterDaughters](const Particle * p) {
571  const ECLCluster* cluster = p->getECLCluster();
572  if (cluster and not cluster->hasFailedFitTime()) {
573  numberOfClusterDaughters ++;
574 
575  double time = cluster->getTime();
576  B2DEBUG(10, "time[" << numberOfClusterDaughters << "] = " << time);
577  double deltatime = cluster->getDeltaTime99();
578  B2DEBUG(10, "deltatime[" << numberOfClusterDaughters << "] = " << deltatime);
579  numer += time / pow(deltatime, 2);
580  B2DEBUG(11, "numer[" << numberOfClusterDaughters << "] = " << numer);
581  denom += 1 / pow(deltatime, 2);
582  B2DEBUG(11, "denom[" << numberOfClusterDaughters << "] = " << denom);
583  }
584  return false;
585  };
586 
587  particle->forEachDaughter(weightedECLTimeAverage, true, true);
588 
589  if (numberOfClusterDaughters < 1) {
590  B2WARNING("There are no clusters or cluster matches amongst the daughters of the provided particle!");
591  return std::numeric_limits<float>::quiet_NaN();
592  }
593 
594  if (denom == 0) {
595  B2WARNING("The denominator of the weighted mean is zero!");
596  return std::numeric_limits<float>::quiet_NaN();
597  } else {
598  B2DEBUG(10, "numer/denom = " << numer / denom);
599  return numer / denom;
600  }
601  }
602 
603  double maxWeightedDistanceFromAverageECLTime(const Particle* particle)
604  {
605  int nDaughters = particle->getNDaughters();
606  if (nDaughters < 1) {
607  B2WARNING("The provided particle has no daughters!");
608  return std::numeric_limits<float>::quiet_NaN();
609  }
610 
611  double maxTimeDiff = -DBL_MAX;
612  int numberOfClusterDaughters = 0;
613 
614  double averageECLTime = weightedAverageECLTime(particle);
615 
616  auto maxTimeDifference = [&maxTimeDiff, &numberOfClusterDaughters, &averageECLTime](const Particle * p) {
617 
618  const ECLCluster* cluster = p->getECLCluster();
619  if (cluster) {
620  numberOfClusterDaughters ++;
621 
622  double time = cluster->getTime();
623  B2DEBUG(10, "time[" << numberOfClusterDaughters << "] = " << time);
624  double deltatime = cluster->getDeltaTime99();
625  B2DEBUG(10, "deltatime[" << numberOfClusterDaughters << "] = " << deltatime);
626  double maxTimeDiff_temp = fabs((time - averageECLTime) / deltatime);
627  B2DEBUG(11, "maxTimeDiff_temp[" << numberOfClusterDaughters << "] = " << maxTimeDiff_temp);
628  if (maxTimeDiff_temp > maxTimeDiff)
629  maxTimeDiff = maxTimeDiff_temp;
630  B2DEBUG(11, "maxTimeDiff[" << numberOfClusterDaughters << "] = " << maxTimeDiff);
631  }
632  return false;
633  };
634 
635  particle->forEachDaughter(maxTimeDifference, true, true);
636 
637  if (numberOfClusterDaughters < 1) {
638  B2WARNING("There are no clusters or cluster matches amongst the daughters of the provided particle!");
639  return std::numeric_limits<float>::quiet_NaN();
640  }
641 
642  if (maxTimeDiff < 0) {
643  B2WARNING("The max time difference is negative!");
644  return std::numeric_limits<float>::quiet_NaN();
645  } else {
646  B2DEBUG(10, "maxTimeDiff = " << maxTimeDiff);
647  return maxTimeDiff;
648  }
649  }
650 
651  double eclClusterMdstIndex(const Particle* particle)
652  {
653  const ECLCluster* cluster = particle->getECLCluster();
654  if (cluster) {
655  return cluster->getArrayIndex();
656  } else return std::numeric_limits<double>::quiet_NaN();
657 
658  return std::numeric_limits<double>::quiet_NaN();
659  }
660 
661 
662  /*************************************************************
663  * Event-based ECL clustering information
664  */
665  double nECLOutOfTimeCrystalsFWDEndcap(const Particle*)
666  {
667  StoreObjPtr<EventLevelClusteringInfo> elci;
668  if (!elci) return std::numeric_limits<double>::quiet_NaN();
669  return (double)elci->getNECLCalDigitsOutOfTimeFWD();
670  }
671 
672  double nECLOutOfTimeCrystalsBarrel(const Particle*)
673  {
674  StoreObjPtr<EventLevelClusteringInfo> elci;
675  if (!elci) return std::numeric_limits<double>::quiet_NaN();
676  return (double)elci->getNECLCalDigitsOutOfTimeBarrel();
677  }
678 
679  double nECLOutOfTimeCrystalsBWDEndcap(const Particle*)
680  {
681  StoreObjPtr<EventLevelClusteringInfo> elci;
682  if (!elci) return std::numeric_limits<double>::quiet_NaN();
683  return (double)elci->getNECLCalDigitsOutOfTimeBWD();
684  }
685 
686  double nECLOutOfTimeCrystals(const Particle*)
687  {
688  StoreObjPtr<EventLevelClusteringInfo> elci;
689  if (!elci) return std::numeric_limits<double>::quiet_NaN();
690  return (double)elci->getNECLCalDigitsOutOfTime();
691  }
692 
693  double nRejectedECLShowersFWDEndcap(const Particle*)
694  {
695  StoreObjPtr<EventLevelClusteringInfo> elci;
696  if (!elci) return std::numeric_limits<double>::quiet_NaN();
697  return (double)elci->getNECLShowersRejectedFWD();
698  }
699 
700  double nRejectedECLShowersBarrel(const Particle*)
701  {
702  StoreObjPtr<EventLevelClusteringInfo> elci;
703  if (!elci) return std::numeric_limits<double>::quiet_NaN();
704  return (double)elci->getNECLShowersRejectedBarrel();
705  }
706 
707  double nRejectedECLShowersBWDEndcap(const Particle*)
708  {
709  StoreObjPtr<EventLevelClusteringInfo> elci;
710  if (!elci) return std::numeric_limits<double>::quiet_NaN();
711  return (double)elci->getNECLShowersRejectedBWD();
712  }
713 
714  double nRejectedECLShowers(const Particle*)
715  {
716  StoreObjPtr<EventLevelClusteringInfo> elci;
717  if (!elci) return std::numeric_limits<double>::quiet_NaN();
718  return (double) elci->getNECLShowersRejected();
719  }
720 
721  double eclClusterEoP(const Particle* part)
722  {
723  double E = eclClusterE(part);
724  if (part->hasExtraInfo("bremsCorrectedPhotonEnergy")) {
725  E += part->getExtraInfo("bremsCorrectedPhotonEnergy");
726  }
727  const double p = part->getMomentumMagnitude();
728  if (0 == p) { return std::numeric_limits<float>::quiet_NaN();}
729  return E / p;
730  }
731 
732  double getEnergyTC(const Particle*, const std::vector<double>& vars)
733  {
734  if (vars.size() != 1) {
735  B2FATAL("Need exactly one parameters (tcid).");
736  }
737 
738  StoreObjPtr<ECLTRGInformation> tce;
739  const int tcid = int(std::lround(vars[0]));
740 
741  if (!tce) return std::numeric_limits<double>::quiet_NaN();
742  return tce->getEnergyTC(tcid);
743  }
744 
745  double getTimingTC(const Particle*, const std::vector<double>& vars)
746  {
747  if (vars.size() != 1) {
748  B2FATAL("Need exactly one parameters (tcid).");
749  }
750 
751  StoreObjPtr<ECLTRGInformation> tce;
752  const int tcid = int(std::lround(vars[0]));
753 
754  if (!tce) return std::numeric_limits<double>::quiet_NaN();
755  return tce->getTimingTC(tcid);
756  }
757 
758  double eclHitWindowTC(const Particle*, const std::vector<double>& vars)
759  {
760  if (vars.size() != 1) {
761  B2FATAL("Need exactly one parameters (tcid).");
762  }
763 
764  StoreObjPtr<ECLTRGInformation> tce;
765  const int tcid = int(std::lround(vars[0]));
766 
767  if (!tce) return std::numeric_limits<double>::quiet_NaN();
768  return tce->getHitWinTC(tcid);
769  }
770 
771  double getEvtTimingTC(const Particle*)
772  {
773  StoreObjPtr<ECLTRGInformation> tce;
774  if (!tce) return std::numeric_limits<double>::quiet_NaN();
775  return tce->getEvtTiming();
776  }
777 
778  double getMaximumTCId(const Particle*)
779  {
780  StoreObjPtr<ECLTRGInformation> tce;
781  if (!tce) return std::numeric_limits<double>::quiet_NaN();
782  return tce->getMaximumTCId();
783  }
784 
785 
786  double getNumberOfTCs(const Particle*, const std::vector<double>& vars)
787  {
788  if (vars.size() != 3) {
789  B2FATAL("Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
790  }
791 
792  StoreArray<ECLTriggerCell> ecltcs;
793  const int fadccut = int(std::lround(vars[0]));
794 
795  if (!ecltcs) return std::numeric_limits<double>::quiet_NaN();
796  if (fadccut == 0) return ecltcs.getEntries();
797  else {
798  int minTheta = int(std::lround(vars[1]));
799  int maxTheta = int(std::lround(vars[2]));
800 
801  unsigned nTCs = 0;
802  for (const auto& tc : ecltcs) {
803  if (tc.getFADC() >= fadccut and
804  tc.getThetaId() >= minTheta and
805  tc.getThetaId() <= maxTheta) nTCs++;
806  }
807  return nTCs;
808  }
809  return 0.0;
810  }
811 
812  double getEnergyTCECLCalDigit(const Particle*, const std::vector<double>& vars)
813  {
814  if (vars.size() != 1) {
815  B2FATAL("Need exactly one parameter (tcid).");
816  }
817 
818  StoreObjPtr<ECLTRGInformation> tce;
819  const int tcid = int(std::lround(vars[0]));
820 
821  if (!tce) return std::numeric_limits<double>::quiet_NaN();
822  return tce->getEnergyTCECLCalDigit(tcid);
823  }
824 
825  double getTimingTCECLCalDigit(const Particle*, const std::vector<double>& vars)
826  {
827  if (vars.size() != 1) {
828  B2FATAL("Need exactly one parameter (tcid).");
829  }
830 
831  StoreObjPtr<ECLTRGInformation> tce;
832  const int tcid = int(std::lround(vars[0]));
833 
834  if (!tce) return std::numeric_limits<double>::quiet_NaN();
835  return tce->getTimingTCECLCalDigit(tcid);
836  }
837 
838  double eclEnergySumTC(const Particle*, const std::vector<double>& vars)
839  {
840  if (vars.size() != 3) {
841  B2FATAL("Need exactly three parameters (fadccut, minthetaid, maxthetaid).");
842  }
843 
844  StoreObjPtr<ECLTRGInformation> tce;
845  if (!tce) return std::numeric_limits<double>::quiet_NaN();
846 
847  const int fadccut = int(std::lround(vars[0]));
848  const int minTheta = int(std::lround(vars[1]));
849  const int maxTheta = int(std::lround(vars[2]));
850 
851  if (maxTheta < minTheta) {
852  B2WARNING("minTheta i (vars[1]) must be equal or less than maxTheta j (vars[2]).");
853  return std::numeric_limits<double>::quiet_NaN();
854  }
855 
856  double energySum = 0.;
857  for (unsigned idx = 1; idx <= 576; idx++) {
858  if (tce->getThetaIdTC(idx) >= minTheta and tce->getThetaIdTC(idx) <= maxTheta and tce->getEnergyTC(idx) >= fadccut) {
859  energySum += tce->getEnergyTC(idx);
860  }
861  }
862 
863  return energySum;
864  }
865 
866  double eclEnergySumTCECLCalDigit(const Particle*, const std::vector<double>& vars)
867  {
868  if (vars.size() != 3) {
869  B2FATAL("Need exactly three parameters (minthetaid, maxthetaid, option).");
870  }
871 
872  StoreObjPtr<ECLTRGInformation> tce;
873  if (!tce) return std::numeric_limits<double>::quiet_NaN();
874 
875  int minTheta = int(std::lround(vars[0]));
876  int maxTheta = int(std::lround(vars[1]));
877  int option = int(std::lround(vars[2]));
878  double par = vars[3];
879 
880  if (maxTheta < minTheta) {
881  B2WARNING("minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
882  return std::numeric_limits<double>::quiet_NaN();
883  }
884  if (option < 0 or option > 2) {
885  B2WARNING("Third parameters k (vars[2]) must be >=0 and <=2.");
886  return std::numeric_limits<double>::quiet_NaN();
887  }
888 
889  double energySum = 0.;
890  for (unsigned idx = 1; idx <= 576; idx++) {
891  if (tce->getThetaIdTC(idx) >= minTheta and
892  tce->getThetaIdTC(idx) <= maxTheta) {
893 
894  if (option == 0) {
895  energySum += tce->getEnergyTCECLCalDigit(idx);
896  } else if (option == 1 and tce->getEnergyTC(idx)) {
897  energySum += tce->getEnergyTCECLCalDigit(idx);
898  } else if (option == 2 and tce->getEnergyTCECLCalDigit(idx) > par) { // TCECLCalDigits > par
899  energySum += tce->getEnergyTCECLCalDigit(idx);
900  }
901  }
902  }
903 
904  return energySum;
905  }
906 
907  double eclEnergySumTCECLCalDigitInECLCluster(const Particle*)
908  {
909  StoreObjPtr<ECLTRGInformation> tce;
910  if (!tce) return std::numeric_limits<double>::quiet_NaN();
911  return tce->getSumEnergyTCECLCalDigitInECLCluster();
912  }
913 
914  double eclEnergySumECLCalDigitInECLCluster(const Particle*)
915  {
916  StoreObjPtr<ECLTRGInformation> tce;
917  if (!tce) return std::numeric_limits<double>::quiet_NaN();
918  return tce->getSumEnergyECLCalDigitInECLCluster();
919  }
920 
921  double eclEnergySumTCECLCalDigitInECLClusterThreshold(const Particle*)
922  {
923  StoreObjPtr<ECLTRGInformation> tce;
924  if (!tce) return std::numeric_limits<double>::quiet_NaN();
925  return tce->getClusterEnergyThreshold();
926  }
927 
928  double eclNumberOfTCsForCluster(const Particle* particle, const std::vector<double>& vars)
929  {
930  if (vars.size() != 4) {
931  B2FATAL("Need exactly two parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
932  }
933 
934  // if we did not run the ECLTRGInformation module, return NaN
935  StoreArray<ECLTriggerCell> ecltc;
936  if (!ecltc) return std::numeric_limits<double>::quiet_NaN();
937 
938  // if theta range makes no sense, return NaN
939  const int minTheta = int(std::lround(vars[0]));
940  const int maxTheta = int(std::lround(vars[1]));
941  if (maxTheta < minTheta) {
942  B2WARNING("minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
943  return std::numeric_limits<double>::quiet_NaN();
944  }
945  // if hitwin range makes no sense, return NaN
946  const int minHitWin = int(std::lround(vars[2]));
947  const int maxHitWin = int(std::lround(vars[3]));
948  if (maxHitWin < minHitWin) {
949  B2WARNING("minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
950  return std::numeric_limits<double>::quiet_NaN();
951  }
952 
953  double result = 0.;
954  const ECLCluster* cluster = particle->getECLCluster();
955 
956  // if everything else is fine, but we dont have a cluster, return 0
957  if (cluster) {
958  auto relationsTCs = cluster->getRelationsWith<ECLTriggerCell>();
959  for (unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
960  const auto tc = relationsTCs.object(idxTC);
961  if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
962  and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += 1.0;
963  }
964  }
965  return result;
966  }
967 
968  double eclTCFADCForCluster(const Particle* particle, const std::vector<double>& vars)
969  {
970  if (vars.size() != 4) {
971  B2FATAL("Need exactly four parameters (minthetaid, maxthetaid, minhitwindow, maxhitwindow).");
972  }
973 
974  // if we did not run the ECLTRGInformation module, return NaN
975  StoreArray<ECLTriggerCell> ecltc;
976  if (!ecltc) return std::numeric_limits<double>::quiet_NaN();
977 
978  // if theta range makes no sense, return NaN
979  const int minTheta = int(std::lround(vars[0]));
980  const int maxTheta = int(std::lround(vars[1]));
981  if (maxTheta < minTheta) {
982  B2WARNING("minTheta i (vars[0]) must be equal or less than maxTheta j (vars[1]).");
983  return std::numeric_limits<double>::quiet_NaN();
984  }
985 
986  // if hitwin range makes no sense, return NaN
987  const int minHitWin = int(std::lround(vars[2]));
988  const int maxHitWin = int(std::lround(vars[3]));
989  if (maxHitWin < minHitWin) {
990  B2WARNING("minHitWin k (vars[2]) must be equal or less than maxHitWin l (vars[3]).");
991  return std::numeric_limits<double>::quiet_NaN();
992  }
993 
994  double result = 0.;
995  const ECLCluster* cluster = particle->getECLCluster();
996 
997  // if everything else is fine, but we dont have a cluster, return 0
998  if (cluster) {
999  auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
1000  for (unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
1001  const auto tc = relationsTCs.object(idxTC);
1002  if (tc->getThetaId() >= minTheta and tc->getThetaId() <= maxTheta
1003  and tc->getHitWin() >= minHitWin and tc->getHitWin() <= maxHitWin) result += tc->getFADC();
1004  }
1005  }
1006  return result;
1007  }
1008 
1009  double eclTCIsMaximumForCluster(const Particle* particle)
1010  {
1011 
1012  // if we did not run the ECLTRGInformation module, return NaN
1013  StoreArray<ECLTriggerCell> ecltc;
1014  if (!ecltc) return std::numeric_limits<double>::quiet_NaN();
1015 
1016  double result = 0.;
1017  const ECLCluster* cluster = particle->getECLCluster();
1018 
1019  // if everything else is fine, but we dont have a cluster, return 0
1020  if (cluster) {
1021  auto relationsTCs = cluster->getRelationsTo<ECLTriggerCell>();
1022  for (unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
1023  const auto tc = relationsTCs.object(idxTC);
1024  if (tc->isHighestFADC()) result = 1.0;
1025  }
1026  }
1027  return result;
1028  }
1029 
1030  double eclClusterOnlyInvariantMass(const Particle* part)
1031  {
1032  int nDaughters = part->getNDaughters();
1033  TLorentzVector sum;
1034 
1035  if (nDaughters < 1) {
1036  return part->getMass();
1037  } else {
1038  int nClusterDaughters = 0;
1039  std::stack<const Particle*> stacked;
1040  stacked.push(part);
1041  while (!stacked.empty()) {
1042  const Particle* current = stacked.top();
1043  stacked.pop();
1044 
1045  const ECLCluster* cluster = current->getECLCluster();
1046  if (cluster) {
1047  const ECLCluster::EHypothesisBit clusterBit = current->getECLClusterEHypothesisBit();
1048  nClusterDaughters ++;
1049  ClusterUtils clutls;
1050  TLorentzVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterBit);
1051  sum += p4Cluster;
1052  } else {
1053  const std::vector<Particle*> daughters = current->getDaughters();
1054  nDaughters = current->getNDaughters();
1055  for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
1056  stacked.push(daughters[iDaughter]);
1057  }
1058  }
1059  }
1060 
1061  if (nClusterDaughters < 1) {
1062  B2WARNING("There are no clusters amongst the daughters of the provided particle!");
1063  return std::numeric_limits<double>::quiet_NaN();
1064  }
1065  B2DEBUG(10, "Number of daughters with cluster associated = " << nClusterDaughters);
1066  return sum.M();
1067  }
1068  }
1069 
1070 
1071  VARIABLE_GROUP("ECL Cluster related");
1072  REGISTER_VARIABLE("clusterEoP", eclClusterEoP, R"DOC(
1073 Returns ratio of uncorrelated energy E over momentum p, a convenience
1074 alias for (clusterE / p).
1075 )DOC");
1076  REGISTER_VARIABLE("clusterReg", eclClusterDetectionRegion, R"DOC(
1077 Returns an integer code for the ECL region of a cluster.
1078 
1079  - 1: forward, 2: barrel, 3: backward,
1080  - 11: between FWD and barrel, 13: between BWD and barrel,
1081  - 0: otherwise
1082 )DOC");
1083  REGISTER_VARIABLE("clusterDeltaLTemp", eclClusterDeltaL, R"DOC(
1084 | Returns DeltaL for the shower shape.
1085 | A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1086  different orientations in space. A shower direction can be constructed by calculating the weighted
1087  average of these orientations using the corresponding energy depositions as weights. The intersection
1088  (more precisely the point of closest approach) of the vector with this direction originating from the
1089  cluster center and an extrapolated track can be used as reference for the calculation of the shower
1090  depth. It is defined as the distance between this intersection and the cluster center.
1091 
1092 .. warning::
1093  This distance is calculated on the reconstructed level and is temporarily
1094  included to the ECL cluster MDST data format for studying purposes. If it is found
1095  that it is not crucial for physics analysis then this variable will be removed
1096  in future releases.
1097  Therefore, keep in mind that this variable might be removed in the future!
1098 
1099 .. note::
1100  | Please read `this <importantNoteECL>` first.
1101  | Lower limit: :math:`-250.0`
1102  | Upper limit: :math:`250.0`
1103  | Precision: :math:`10` bit
1104 )DOC");
1105  REGISTER_VARIABLE("minC2TDist", eclClusterIsolation, R"DOC(
1106 Returns distance between ECL cluster and nearest track hitting the ECL.
1107 
1108 A cluster comprises the energy depositions of several crystals. All these crystals have slightly
1109 different orientations in space. A shower direction can be constructed by calculating the weighted
1110 average of these orientations using the corresponding energy depositions as weights. The intersection
1111 (more precisely the point of closest approach) of the vector with this direction originating from the
1112 cluster center and an extrapolated track can be used as reference for the calculation of the track depth.
1113 It is defined as the distance between this intersection and the track hit position on the front face of the ECL.
1114 
1115 .. note::
1116  This distance is calculated on the reconstructed level.
1117 
1118 .. note::
1119  | Please read `this <importantNoteECL>` first.
1120  | Lower limit: :math:`0.0`
1121  | Upper limit: :math:`250.0`
1122  | Precision: :math:`10` bit
1123 )DOC");
1124  REGISTER_VARIABLE("clusterE", eclClusterE, R"DOC(
1125 Returns ECL cluster's energy corrected for leakage and background.
1126 
1127 The raw photon energy is given by the weighted sum of all ECL crystal energies within the ECL cluster.
1128 The weights per crystals are :math:`\leq 1` after cluster energy splitting in the case of overlapping
1129 clusters. The number of crystals that are included in the sum depends on a initial energy estimation
1130 and local beam background levels at the highest energy crystal position. It is optimized to minimize
1131 the core width (resolution) of true photons. Photon energy distributions always show a low energy tail
1132 due to unavoidable longitudinal and transverse leakage that can be further modified by the clustering
1133 algorithm and beam backgrounds.The peak position of the photon energy distributions are corrected to
1134 match the true photon energy in MC:
1135 
1136  - Leakage correction: Using large MC samples of mono-energetic single photons, a correction factor
1137  :math:`f` as function of reconstructed detector position, reconstructed photon energy and beam backgrounds
1138  is determined via :math:`f = \frac{\text{peak_reconstructed}}{\text{energy_true}}`.
1139 
1140  - Cluster energy calibration (data only): To reach the target precision of :math:`< 1.8\%` energy
1141  resolution for high energetic photons, the remaining difference between MC and data must be calibrated
1142  using kinematically fit muon pairs. This calibration is only applied to data and not to MC and will
1143  take time to develop.
1144 
1145 It is important to note that after perfect leakage correction and cluster energy calibration,
1146 the :math:`\pi^{0}` mass peak will be shifted slightly to smaller values than the PDG average
1147 due to the low energy tails of photons. The :math:`\pi^{0}` mass peak must not be corrected
1148 to the PDG value by adjusting the reconstructed photon energies. Selection criteria based on
1149 the mass for :math:`\pi^{0}` candidates must be based on the biased value. Most analysis
1150 will used mass constrained :math:`\pi^{0}` s anyhow.
1151 
1152 .. warning::
1153  We only store clusters with :math:`E > 20\,` MeV.
1154 
1155 .. note::
1156  | Please read `this <importantNoteECL>` first.
1157  | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1158  | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1159  | Precision: :math:`18` bit
1160  | This value can be changed to a different reference frame with :b2:var:`useCMSFrame`.
1161 )DOC");
1162  REGISTER_VARIABLE("clusterErrorE", eclClusterErrorE, R"DOC(
1163 Returns ECL cluster's uncertainty on energy
1164 (from background level and energy dependent tabulation).
1165 )DOC");
1166  REGISTER_VARIABLE("clusterErrorPhi", eclClusterErrorPhi, R"DOC(
1167 Returns ECL cluster's uncertainty on :math:`\phi`
1168 (from background level and energy dependent tabulation).
1169 )DOC");
1170  REGISTER_VARIABLE("clusterErrorTheta", eclClusterErrorTheta, R"DOC(
1171 Returns ECL cluster's uncertainty on :math:`\theta`
1172 (from background level and energy dependent tabulation).
1173 )DOC");
1174 
1175  REGISTER_VARIABLE("clusterR", eclClusterR, R"DOC(
1176 Returns ECL cluster's centroid distance from :math:`(0,0,0)`.
1177 )DOC");
1178  REGISTER_VARIABLE("clusterPhi", eclClusterPhi, R"DOC(
1179 Returns ECL cluster's azimuthal angle :math:`\phi`
1180 (this is not generally equal to a photon azimuthal angle).
1181 
1182 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1183  cluster centroid position in the ECL.
1184 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1185  after cluster energy splitting in the case of overlapping clusters.
1186 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1187  the crystal centers. Cluster centroids are generally biased towards the centers of the
1188  highest energetic crystal. This effect is larger for low energetic photons.
1189 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1190 
1191 .. note::
1192  Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1193 
1194 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1195 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1196 as function of true photon energy, true photon direction and beam background level.
1197 
1198 .. warning::
1199  Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1200  IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1201  from :math:`(0,0,0)`) for particle kinematics.
1202 
1203 .. note::
1204  | Please read `this <importantNoteECL>` first.
1205  | Lower limit: :math:`-\pi`
1206  | Upper limit: :math:`\pi`
1207  | Precision: :math:`16` bit
1208 )DOC");
1209  REGISTER_VARIABLE("clusterConnectedRegionID", eclClusterConnectedRegionID, R"DOC(
1210 Returns ECL cluster's connected region ID.
1211 )DOC");
1212  REGISTER_VARIABLE("clusterTheta", eclClusterTheta, R"DOC(
1213 Returns ECL cluster's polar angle :math:`\theta`
1214 (this is not generally equal to a photon polar angle).
1215 
1216 | The direction of a cluster is given by the connecting line of :math:`\,(0,0,0)\,` and
1217  cluster centroid position in the ECL.
1218 | The cluster centroid position is calculated using up to 21 crystals (5x5 excluding corners)
1219  after cluster energy splitting in the case of overlapping clusters.
1220 | The centroid position is the logarithmically weighted average of all crystals evaluated at
1221  the crystal centers. Cluster centroids are generally biased towards the centers of the
1222  highest energetic crystal. This effect is larger for low energetic photons.
1223 | Beam backgrounds slightly decrease the position resolution, mainly for low energetic photons.
1224 
1225 .. note::
1226  Radius of a cluster is almost constant in the barrel and should not be used directly in any selection.
1227 
1228 Unlike for charged tracks, the uncertainty (covariance) of the photon directions is not determined
1229 based on individual cluster properties but taken from on MC-based parametrizations of the resolution
1230 as function of true photon energy, true photon direction and beam background level.
1231 
1232 .. warning::
1233  Users must use the actual particle direction (done automatically in the modularAnalysis using the average
1234  IP position (can be changed if needed)) and not the ECL Cluster direction (position in the ECL measured
1235  from :math:`(0,0,0)`) for particle kinematics.
1236 
1237 .. note::
1238  | Please read `this <importantNoteECL>` first.
1239  | Lower limit: :math:`0.0`
1240  | Upper limit: :math:`\pi`
1241  | Precision: :math:`16` bit
1242 )DOC");
1243  REGISTER_VARIABLE("clusterTiming", eclClusterTiming, R"DOC(
1244 Returns the time of the ECL cluster. It is calculated as the Photon timing minus the Event t0.
1245 Photon timing is given by the fitted time of the recorded waveform of the highest energy crystal in the
1246 cluster. After all calibrations and corrections (including Time-Of-Flight), photons from the interaction
1247 point (IP) should have a Photon timing that corresponds to the Event t0, :math:`t_{0}`. The Event t0 is the
1248 time of the event and may be measured by a different sub-detector (see Event t0 documentation). For an ECL
1249 cluster produced at the interation point in time with the event, the cluster time should be consistent with zero
1250 within the uncertainties. Special values are returned if the fit for the Photon timing fails (see
1251 documentation for `clusterHasFailedTiming`). (For MC, the calibrations and corrections are not fully simulated).
1252 
1253 .. note::
1254  | Please read `this <importantNoteECL>` first.
1255  | Lower limit: :math:`-1000.0`
1256  | Upper limit: :math:`1000.0`
1257  | Precision: :math:`12` bit
1258 )DOC");
1259  REGISTER_VARIABLE("clusterHasFailedTiming", eclClusterHasFailedTiming, R"DOC(
1260 Status bit for if the ECL cluster's timing fit failed. Photon timing is given by the fitted time
1261 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1262 this variable tells the user if that has happened.
1263 )DOC");
1264  REGISTER_VARIABLE("clusterErrorTiming", eclClusterErrorTiming, R"DOC(
1265 Returns ECL cluster's timing uncertainty that contains :math:`99\%` of true photons (dt99).
1266 
1267 The photon timing uncertainty is currently determined using MC. The resulting parametrization depends on
1268 the true energy deposition in the highest energetic crystal and the local beam background level in that crystal.
1269 The resulting timing distribution is non-Gaussian and for each photon the value dt99 is stored,
1270 where :math:`|\text{timing}| / \text{dt99} < 1` is designed to give a :math:`99\%`
1271 timing efficiency for true photons from the IP.
1272 The resulting efficiency is approximately flat in energy and independent of beam background levels.
1273 
1274 Very large values of dt99 are an indication of failed waveform fits in the ECL.
1275 We remove such clusters in most physics photon lists.
1276 
1277 .. note::
1278  | Please read `this <importantNoteECL>` first.
1279  | Lower limit: :math:`0.0`
1280  | Upper limit: :math:`1000.0`
1281  | Precision: :math:`12` bit
1282 
1283 .. warning::
1284  In real data there will be a sizeable number of high energetic Bhabha events
1285  (from previous or later bunch collisions) that can easily be rejected by timing cuts.
1286  However, these events create large ECL clusters that can overlap with other ECL clusters
1287  and it is not clear that a simple rejection is the correction strategy.
1288 )DOC");
1289  REGISTER_VARIABLE("clusterHasFailedErrorTiming", eclClusterHasFailedErrorTiming, R"DOC(
1290 Status bit for if the ECL cluster's timing uncertainty calculation failed. Photon timing is given by the fitted time
1291 of the recorded waveform of the highest energetic crystal in a cluster; however, that fit can fail and so
1292 this variable tells the user if that has happened.
1293 )DOC");
1294  REGISTER_VARIABLE("clusterHighestE", eclClusterHighestE, R"DOC(
1295 Returns energy of the highest energetic crystal in the ECL cluster after reweighting.
1296 
1297 .. warning::
1298  This variable must be used carefully since it can bias shower selection
1299  towards photons that hit crystals in the center and hence have a large energy
1300  deposition in the highest energy crystal.
1301 
1302 .. note::
1303  | Please read `this <importantNoteECL>` first.
1304  | Lower limit: :math:`-5` (:math:`e^{-5} = 0.00674\,` GeV)
1305  | Upper limit: :math:`3.0` (:math:`e^3 = 20.08553\,` GeV)
1306  | Precision: :math:`18` bit
1307 )DOC");
1308  REGISTER_VARIABLE("clusterCellID", eclClusterCellId,
1309  "Returns cellId of the crystal with highest energy in the ECLCluster.");
1310  REGISTER_VARIABLE("clusterE1E9", eclClusterE1E9, R"DOC(
1311 Returns ratio of energies of the central crystal, E1, and 3x3 crystals, E9, around the central crystal.
1312 Since :math:`E1 \leq E9`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1313 and smaller values for hadrons.
1314 
1315 .. note::
1316  | Please read `this <importantNoteECL>` first.
1317  | Lower limit: :math:`0.0`
1318  | Upper limit: :math:`1.0`
1319  | Precision: :math:`10` bit
1320 )DOC");
1321  REGISTER_VARIABLE("clusterE9E25", eclClusterE9E25, R"DOC(
1322 Deprecated - kept for backwards compatibility - returns clusterE9E21.
1323 )DOC");
1324  REGISTER_VARIABLE("clusterE9E21", eclClusterE9E21, R"DOC(
1325 Returns ratio of energies in inner 3x3 crystals, E9, and 5x5 crystals around the central crystal without corners.
1326 Since :math:`E9 \leq E21`, this ratio is :math:`\leq 1` and tends towards larger values for photons
1327 and smaller values for hadrons.
1328 
1329 .. note::
1330  | Please read `this <importantNoteECL>` first.
1331  | Lower limit: :math:`0.0`
1332  | Upper limit: :math:`1.0`
1333  | Precision: :math:`10` bit
1334 )DOC");
1335  REGISTER_VARIABLE("clusterAbsZernikeMoment40", eclClusterAbsZernikeMoment40, R"DOC(
1336 Returns absolute value of Zernike moment 40 (:math:`|Z_{40}|`). (shower shape variable).
1337 
1338 .. note::
1339  | Please read `this <importantNoteECL>` first.
1340  | Lower limit: :math:`0.0`
1341  | Upper limit: :math:`1.7`
1342  | Precision: :math:`10` bit
1343 )DOC");
1344  REGISTER_VARIABLE("clusterAbsZernikeMoment51", eclClusterAbsZernikeMoment51, R"DOC(
1345 Returns absolute value of Zernike moment 51 (:math:`|Z_{51}|`). (shower shape variable).
1346 
1347 .. note::
1348  | Please read `this <importantNoteECL>` first.
1349  | Lower limit: :math:`0.0`
1350  | Upper limit: :math:`1.2`
1351  | Precision: :math:`10` bit
1352 )DOC");
1353  REGISTER_VARIABLE("clusterZernikeMVA", eclClusterZernikeMVA, R"DOC(
1354 Returns output of a MVA using eleven Zernike moments of the cluster. Zernike moments are calculated per
1355 shower in a plane perpendicular to the shower direction via
1356 
1357 .. math::
1358  |Z_{nm}| = \frac{n+1}{\pi} \frac{1}{\sum_{i} w_{i} E_{i}} \left|\sum_{i} R_{nm}(\rho_{i}) e^{-im\alpha_{i}} w_{i} E_{i} \right|
1359 
1360 where n, m are the integers, :math:`i` runs over the crystals in the shower,
1361 :math:`E_{i}` is the energy of the i-th crystal in the shower,
1362 :math:`R_{nm}` is a polynomial of degree :math:`n`,
1363 :math:`\rho_{i}` is the radial distance of the :math:`i`-th crystal in the perpendicular plane,
1364 and :math:`\alpha_{i}` is the polar angle of the :math:`i`-th crystal in the perpendicular plane.
1365 As a crystal can be related to more than one shower, :math:`w_{i}` is the fraction of the
1366 energy of the :math:`i`-th crystal associated with the shower.
1367 
1368 More details about the implementation can be found in `BELLE2-NOTE-TE-2017-001 <https://docs.belle2.org/record/454?ln=en>`_ .
1369 
1370 More details about Zernike polynomials can be found in `Wikipedia <https://en.wikipedia.org/wiki/Zernike_polynomials>`_ .
1371 
1372 | For cluster with hypothesisId==N1: raw MVA output.
1373 | For cluster with hypothesisId==N2: 1 - prod{clusterZernikeMVA}, where the product is on all N1 showers
1374  belonging to the same connected region (shower shape variable).
1375 
1376 .. note::
1377  | Please read `this <importantNoteECL>` first.
1378  | Lower limit: :math:`0.0`
1379  | Upper limit: :math:`1.0`
1380  | Precision: :math:`10` bit
1381 )DOC");
1382  REGISTER_VARIABLE("clusterSecondMoment", eclClusterSecondMoment, R"DOC(
1383 Returns second moment :math:`S`. It is defined as:
1384 
1385 .. math::
1386  S = \frac{\sum_{i=0}^{n} w_{i} E_{i} r^2_{i}}{\sum_{i=0}^{n} w_{i} E_{i}}
1387 
1388 where :math:`E_{i} = (E_0, E_1, ...)` are the single crystal energies sorted by energy, :math:`w_{i}` is
1389 the crystal weight, and :math:`r_{i}` is the distance of the :math:`i`-th digit to the shower center projected
1390 to a plane perpendicular to the shower axis.
1391 
1392 .. note::
1393  | Please read `this <importantNoteECL>` first.
1394  | Lower limit: :math:`0.0`
1395  | Upper limit: :math:`40.0`
1396  | Precision: :math:`10` bit
1397 )DOC");
1398  REGISTER_VARIABLE("clusterLAT", eclClusterLAT, R"DOC(
1399 Returns lateral energy distribution (shower variable). It is defined as following:
1400 
1401 .. math::
1402  S = \frac{\sum_{i=2}^{n} w_{i} E_{i} r^2_{i}}{(w_{0} E_{0} + w_{1} E_{1}) r^2_{0} + \sum_{i=2}^{n} w_{i} E_{i} r^2_{i}}
1403 
1404 where :math:`E_{i} = (E_{0}, E_{1}, ...)` are the single crystal energies sorted by energy
1405 (:math:`E_{0}` is the highest energy and :math:`E_{1}` the second highest), :math:`w_{i}`
1406 is the crystal weight, :math:`r_{i}` is the distance of the :math:`i`-th digit to the
1407 shower center projected to a plane perpendicular to the shower axis,
1408 and :math:`r_{0} \approx 5\,cm` is the distance between two crystals.
1409 
1410 clusterLAT peaks around 0.3 for radially symmetrical electromagnetic showers and is larger
1411 for hadronic events, and electrons with a close-by radiative or Bremsstrahlung photon.
1412 
1413 .. note::
1414  | Please read `this <importantNoteECL>` first.
1415  | Lower limit: :math:`0.0`
1416  | Upper limit: :math:`1.0`
1417  | Precision: :math:`10` bit
1418 )DOC");
1419  REGISTER_VARIABLE("clusterNHits", eclClusterNHits, R"DOC(
1420 Returns sum of weights :math:`w_{i}` (:math:`w_{i} \leq 1`) of all crystals in an ECL cluster.
1421 For non-overlapping clusters this is equal to the number of crystals in the cluster.
1422 In case of energy splitting among nearby clusters, this can be a non-integer value.
1423 
1424 .. note::
1425  | Please read `this <importantNoteECL>` first.
1426  | Lower limit: :math:`0.0`
1427  | Upper limit: :math:`200.0`
1428  | Precision: :math:`10` bit
1429  | If fractional weights are not of interest, this value should be cast to the nearest integer.
1430 )DOC");
1431  REGISTER_VARIABLE("clusterTrackMatch", eclClusterTrackMatched, R"DOC(
1432 Returns 1.0 if at least one reconstructed charged track is matched to the ECL cluster.
1433 
1434 Every reconstructed charged track is extrapolated into the ECL.
1435 Every ECL crystal that is crossed by the track extrapolation is marked.
1436 Each ECL cluster that contains any marked crystal is matched to the track.
1437 Multiple tracks can be matched to one cluster and multiple clusters can be matched to one track.
1438 It is conceptually correct to have two tracks matched to the same cluster.
1439 )DOC");
1440  REGISTER_VARIABLE("nECLClusterTrackMatches", nECLClusterTrackMatches, R"DOC(
1441 Returns number of charged tracks matched to this cluster.
1442 
1443 .. note::
1444  Sometimes (perfectly correctly) two tracks are extrapolated into the same cluster.
1445 
1446  - For charged particles, this should return at least 1 (but sometimes 2 or more).
1447  - For neutrals, this should always return 0.
1448  - Returns NaN if there is no cluster.
1449 )DOC");
1450  REGISTER_VARIABLE("clusterHasPulseShapeDiscrimination", eclClusterHasPulseShapeDiscrimination, R"DOC(
1451 Status bit to indicate if cluster has digits with waveforms that passed energy and :math:`\chi^2`
1452 thresholds for computing PSD variables.
1453 )DOC");
1454  REGISTER_VARIABLE("clusterPulseShapeDiscriminationMVA", eclPulseShapeDiscriminationMVA, R"DOC(
1455 Returns MVA classifier that uses pulse shape discrimination to identify electromagnetic vs hadronic showers.
1456 
1457  - 1 for electromagnetic showers
1458  - 0 for hadronic showers
1459 )DOC");
1460  REGISTER_VARIABLE("clusterNumberOfHadronDigits", eclClusterNumberOfHadronDigits, R"DOC(
1461 Returns ECL cluster's number of hadron digits in cluster (pulse shape discrimination variable).
1462 Weighted sum of digits in cluster with significant scintillation emission (:math:`> 3\,` MeV)
1463 in the hadronic scintillation component.
1464 Computed only using cluster digits with energy :math:`> 50\,` MeV and good offline waveform fit :math:`\chi^2`.
1465 
1466 .. note::
1467  | Please read `this <importantNoteECL>` first.
1468  | Lower limit: :math:`0.0`
1469  | Upper limit: :math:`255.0`
1470  | Precision: :math:`18` bit
1471 )DOC");
1472  REGISTER_VARIABLE("clusterClusterID", eclClusterId, R"DOC(
1473 Returns ECL cluster ID of this ECL cluster within the connected region (CR) to which it belongs to.
1474 )DOC");
1475  REGISTER_VARIABLE("clusterHasNPhotons", eclClusterHasNPhotonsHypothesis, R"DOC(
1476 Returns 1.0 if cluster has the 'N photons' hypothesis (historically called 'N1'),
1477 0.0 if not, and NaN if no cluster is associated to the particle.
1478 )DOC");
1479  REGISTER_VARIABLE("clusterHasNeutralHadron", eclClusterHasNeutralHadronHypothesis, R"DOC(
1480 Returns 1.0 if the cluster has the 'neutral hadrons' hypothesis (historically called 'N2'),
1481 0.0 if not, and NaN if no cluster is associated to the particle.
1482 )DOC");
1483  REGISTER_VARIABLE("eclExtTheta", eclExtTheta, R"DOC(
1484 Returns extrapolated :math:`\theta`.
1485 )DOC");
1486  REGISTER_VARIABLE("eclExtPhi", eclExtPhi, R"DOC(
1487 Returns extrapolated :math:`\phi`.
1488 )DOC");
1489  REGISTER_VARIABLE("eclExtPhiId", eclExtPhiId, R"DOC(
1490 Returns extrapolated :math:`\phi` ID.
1491 )DOC");
1492  REGISTER_VARIABLE("weightedAverageECLTime", weightedAverageECLTime, R"DOC(
1493 Returns ECL weighted average time of all clusters (neutrals) and matched clusters (charged) of daughters
1494 (of any generation) of the provided particle.
1495 )DOC");
1496  REGISTER_VARIABLE("maxWeightedDistanceFromAverageECLTime", maxWeightedDistanceFromAverageECLTime, R"DOC(
1497 Returns maximum weighted distance between time of the cluster of a photon and the ECL average time, amongst
1498 the clusters (neutrals) and matched clusters (charged) of daughters (of all generations) of the provided particle.
1499 )DOC");
1500  REGISTER_VARIABLE("clusterMdstIndex", eclClusterMdstIndex, R"DOC(
1501 StoreArray index(0 - based) of the MDST ECLCluster (useful for track-based particles matched to a cluster).
1502 )DOC");
1503 
1504  REGISTER_VARIABLE("nECLOutOfTimeCrystals", nECLOutOfTimeCrystals, R"DOC(
1505 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time.
1506 )DOC");
1507 
1508  REGISTER_VARIABLE("nECLOutOfTimeCrystalsFWDEndcap", nECLOutOfTimeCrystalsFWDEndcap, R"DOC(
1509 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the forward endcap.
1510 )DOC");
1511 
1512  REGISTER_VARIABLE("nECLOutOfTimeCrystalsBarrel", nECLOutOfTimeCrystalsBarrel, R"DOC(
1513 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the barrel.
1514 )DOC");
1515 
1516  REGISTER_VARIABLE("nECLOutOfTimeCrystalsBWDEndcap", nECLOutOfTimeCrystalsBWDEndcap, R"DOC(
1517 [Eventbased] Returns the number of crystals (ECLCalDigits) that are out of time in the backward endcap.
1518 )DOC");
1519 
1520  REGISTER_VARIABLE("nRejectedECLShowers", nRejectedECLShowers, R"DOC(
1521 [Eventbased] Returns the number of showers in the ECL that do not become clusters.
1522 )DOC");
1523 
1524  REGISTER_VARIABLE("nRejectedECLShowersFWDEndcap", nRejectedECLShowersFWDEndcap, R"DOC(
1525 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the forward endcap.
1526 )DOC");
1527 
1528  REGISTER_VARIABLE("nRejectedECLShowersBarrel", nRejectedECLShowersBarrel, R"DOC(
1529 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the barrel.
1530 )DOC");
1531 
1532  REGISTER_VARIABLE("nRejectedECLShowersBWDEndcap", nRejectedECLShowersBWDEndcap, R"DOC(
1533 [Eventbased] Returns the number of showers in the ECL that do not become clusters, from the backward endcap.
1534 )DOC");
1535 
1536  REGISTER_VARIABLE("eclClusterOnlyInvariantMass", eclClusterOnlyInvariantMass, R"DOC(
1537 [Expert] The invariant mass calculated from all ECLCluster daughters (i.e. photons) and
1538 cluster-matched tracks using the cluster 4-momenta.
1539 
1540 Used for ECL-based dark sector physics and debugging track-cluster matching.
1541 )DOC");
1542 
1543 
1544  // These variables require cDST inputs and the eclTrackCalDigitMatch module run first
1545  VARIABLE_GROUP("ECL calibration");
1546 
1547  REGISTER_VARIABLE("clusterUncorrE", eclClusterUncorrectedE, R"DOC(
1548 [Expert] [Calibration] Returns ECL cluster's uncorrected energy. That is, before leakage corrections.
1549 This variable should only be used for study of the ECL. Please see :b2:var:`clusterE`.
1550 )DOC");
1551 
1552  REGISTER_VARIABLE("eclEnergy3FWDBarrel", eclEnergy3FWDBarrel, R"DOC(
1553 [Calibration] Returns energy sum of three crystals in forward barrel.
1554 )DOC");
1555 
1556  REGISTER_VARIABLE("eclEnergy3FWDEndcap", eclEnergy3FWDEndcap, R"DOC(
1557 [Calibration] Returns energy sum of three crystals in forward endcap.
1558 )DOC");
1559 
1560  REGISTER_VARIABLE("eclEnergy3BWDBarrel", eclEnergy3BWDBarrel, R"DOC(
1561 [Calibration] Returns energy sum of three crystals in backward barrel.
1562 )DOC");
1563 
1564  REGISTER_VARIABLE("eclEnergy3BWDEndcap", eclEnergy3BWDEndcap, R"DOC(
1565 [Calibration] Returns energy sum of three crystals in backward endcap.
1566 )DOC");
1567 
1568  // These variables require cDST inputs and the eclTRGInformation module run first
1569  VARIABLE_GROUP("ECL trigger calibration");
1570  REGISTER_VARIABLE("clusterNumberOfTCs(i, j, k, l)", eclNumberOfTCsForCluster, R"DOC(
1571 [Calibration] Returns the number of TCs for this ECL cluster for a given TC theta ID range
1572 :math:`(i, j)` and hit window :math:`(k, l)`.
1573 )DOC");
1574  REGISTER_VARIABLE("clusterTCFADC(i, j, k, l)", eclTCFADCForCluster, R"DOC(
1575 [Calibration] Returns the total FADC sum related to this ECL cluster for a given TC theta ID
1576 range :math:`(i, j)` and hit window :math:`(k, l)`.
1577 )DOC");
1578  REGISTER_VARIABLE("clusterTCIsMaximum", eclTCIsMaximumForCluster, R"DOC(
1579 [Calibration] Returns True if cluster is related to maximum TC.
1580 )DOC");
1581  REGISTER_VARIABLE("clusterTrigger", eclClusterTrigger, R"DOC(
1582 [Calibration] Returns 1.0 if ECL cluster is matched to a trigger cluster (requires to run eclTriggerClusterMatcher
1583 (which requires TRGECLClusters in the input file)) and 0 otherwise. Returns -1 if the matching code was not run.
1584 NOT FOR PHASE2 DATA!
1585 )DOC");
1586  REGISTER_VARIABLE("eclEnergyTC(i)", getEnergyTC, R"DOC(
1587 [Eventbased][Calibration] Returns the energy (in FADC counts) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1588 )DOC");
1589  REGISTER_VARIABLE("eclEnergyTCECLCalDigit(i)", getEnergyTCECLCalDigit, R"DOC(
1590 [Eventbased][Calibration] Returns the energy (in GeV) for the :math:`i`-th trigger cell (TC)
1591 based on ECLCalDigits, 1 based (1..576).
1592 )DOC");
1593  REGISTER_VARIABLE("eclTimingTC(i)", getTimingTC, R"DOC(
1594 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1595 )DOC");
1596  REGISTER_VARIABLE("eclHitWindowTC(i)", eclHitWindowTC, R"DOC(
1597 [Eventbased][Calibration] Returns the hit window for the :math:`i`-th trigger cell (TC), 1 based (1..576).
1598 )DOC");
1599  REGISTER_VARIABLE("eclEventTimingTC", getEvtTimingTC, R"DOC(
1600 [Eventbased][Calibration] Returns the ECL TC event time (in ns).
1601 )DOC");
1602  REGISTER_VARIABLE("eclMaximumTCId", getMaximumTCId, R"DOC(
1603 [Eventbased][Calibration] Returns the TC ID with maximum FADC value.
1604 )DOC");
1605 
1606 
1607  REGISTER_VARIABLE("eclTimingTCECLCalDigit(i)", getTimingTCECLCalDigit, R"DOC(
1608 [Eventbased][Calibration] Returns the time (in ns) for the :math:`i`-th trigger cell (TC) based
1609 on ECLCalDigits, 1 based (1..576)
1610 )DOC");
1611 
1612  REGISTER_VARIABLE("eclNumberOfTCs(i, j, k)", getNumberOfTCs, R"DOC(
1613 [Eventbased][Calibration] Returns the number of TCs above threshold (i=FADC counts) for this event
1614 for a given theta range (j-k)
1615 )DOC");
1616  REGISTER_VARIABLE("eclEnergySumTC(i, j)", eclEnergySumTC, R"DOC(
1617 [Eventbased][Calibration] Returns energy sum (in FADC counts) of all TC cells between two
1618 theta ids i<=thetaid<=j, 1 based (1..17)
1619 )DOC");
1620  REGISTER_VARIABLE("eclEnergySumTCECLCalDigit(i, j, k, l)", eclEnergySumTCECLCalDigit, R"DOC(
1621 [Eventbased][Calibration] Returns energy sum (in GeV) of all TC cells between two theta ids i<=thetaid<=j,
1622 1 based (1..17). k is the sum option: 0 (all), 1 (those with actual TC entries), 2 (sum of ECLCalDigit energy
1623 in this TC above threshold). l is the threshold parameter for the option k 2.
1624 )DOC");
1625  REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLCluster", eclEnergySumTCECLCalDigitInECLCluster, R"DOC(
1626 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits if TC is above threshold
1627 that are part of an ECLCluster above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
1628 )DOC");
1629  REGISTER_VARIABLE("eclEnergySumECLCalDigitInECLCluster", eclEnergySumECLCalDigitInECLCluster, R"DOC(
1630 [Eventbased][Calibration] Returns energy sum (in GeV) of all ECLCalDigits that are part of an ECL cluster
1631 above eclEnergySumTCECLCalDigitInECLClusterThreshold within TC thetaid 2-15.
1632 )DOC");
1633  REGISTER_VARIABLE("eclEnergySumTCECLCalDigitInECLClusterThreshold", eclEnergySumTCECLCalDigitInECLClusterThreshold, R"DOC(
1634 [Eventbased][Calibration] Returns threshold used to calculate eclEnergySumTCECLCalDigitInECLCluster.
1635 )DOC");
1636 
1637  }
1639 }
Belle2::ECLCluster::EHypothesisBit
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
Definition: ECLCluster.h:43
Belle2::ECLCluster::EHypothesisBit::c_nPhotons
@ c_nPhotons
CR is split into n photons (N1)
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::ECLCluster::EHypothesisBit::c_neutralHadron
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
Belle2::ReferenceFrame::GetCurrent
static const ReferenceFrame & GetCurrent()
Get current rest frame.
Definition: ReferenceFrame.cc:28