8#include <top/variables/TOPDigitVariables.h>
11#include <framework/gearbox/Const.h>
12#include <framework/datastore/StoreObjPtr.h>
13#include <framework/datastore/StoreArray.h>
16#include <tracking/dataobjects/ExtHit.h>
17#include <mdst/dataobjects/Track.h>
18#include <analysis/dataobjects/Particle.h>
19#include <top/dataobjects/TOPDigit.h>
20#include <top/geometry/TOPGeometryPar.h>
21#include <top/dataobjects/TOPLikelihood.h>
22#include <top/dataobjects/TOPRecBunch.h>
23#include <top/dataobjects/TOPLikelihoodScanResult.h>
25#include <top/dataobjects/TOPBarHit.h>
26#include <mdst/dataobjects/MCParticle.h>
27#include <framework/dataobjects/MCInitialParticles.h>
32using namespace ROOT::Math;
40 namespace TOPVariable {
44 const TOPLikelihood* getTOPLikelihood(
const Particle* particle)
46 if (not particle)
return nullptr;
47 const auto* track = particle->getTrack();
48 return track ? track->getRelated<TOPLikelihood>() :
nullptr;
51 const ExtHit* getExtHit(
const Particle* particle)
53 const auto* topLikelihood = getTOPLikelihood(particle);
54 return topLikelihood ? topLikelihood->getRelated<ExtHit>() :
nullptr;
57 const TOPBarHit* getBarHit(
const Particle* particle)
59 const auto* topLikelihood = getTOPLikelihood(particle);
60 return topLikelihood ? topLikelihood->getRelated<TOPBarHit>() :
nullptr;
63 const TOPLikelihoodScanResult* getTOPLikelihoodScanResult(
const Particle* particle)
65 if (not particle)
return nullptr;
66 const auto* track = particle->getTrack();
67 if (not track)
return nullptr;
68 auto scanRes = track->getRelated<TOPLikelihoodScanResult>();
70 B2WARNING(
"No TOPLikelihoodScanResult object found. Are you sure you added TOPLLScanner to the path?");
76 int getSlotID(
const Particle* particle)
78 const auto* extHit = getExtHit(particle);
79 return extHit ? extHit->getCopyID() : 0;
85 double topSlotID(
const Particle* particle)
87 const auto* extHit = getExtHit(particle);
88 return extHit ? extHit->getCopyID() : std::numeric_limits<double>::quiet_NaN();
91 double topSlotIDMCMatch(
const Particle* particle)
93 const auto* barHit = getBarHit(particle);
94 return barHit ? barHit->getModuleID() : std::numeric_limits<double>::quiet_NaN();
97 bool getLocalPosition(
const Particle* particle, XYZPoint& result)
99 const auto* extHit = getExtHit(particle);
100 if (not extHit)
return false;
101 int slotID = extHit->getCopyID();
102 const auto& position =
static_cast<XYZPoint
>(extHit->getPosition());
104 if (not geo or not geo->isModuleIDValid(slotID))
return false;
105 const auto& module = geo->getModule(slotID);
106 result = module.pointToLocal(position);
110 double getTOPLocalX(
const Particle* particle)
113 bool ok = TOPVariable::getLocalPosition(particle, position);
114 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
118 double getTOPLocalY(
const Particle* particle)
121 bool ok = TOPVariable::getLocalPosition(particle, position);
122 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
126 double getTOPLocalZ(
const Particle* particle)
129 bool ok = TOPVariable::getLocalPosition(particle, position);
130 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
134 bool getLocalPositionMCMatch(
const Particle* particle, XYZPoint& result)
136 const auto* barHit = getBarHit(particle);
137 if (not barHit)
return false;
138 int slotID = barHit->getModuleID();
139 const auto& position = barHit->getPosition();
141 if (not geo or not geo->isModuleIDValid(slotID))
return false;
142 const auto& module = geo->getModule(slotID);
143 result = module.pointToLocal(position);
147 double getTOPLocalXMCMatch(
const Particle* particle)
150 bool ok = TOPVariable::getLocalPositionMCMatch(particle, position);
151 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
155 double getTOPLocalYMCMatch(
const Particle* particle)
158 bool ok = TOPVariable::getLocalPositionMCMatch(particle, position);
159 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
163 double getTOPLocalZMCMatch(
const Particle* particle)
166 bool ok = TOPVariable::getLocalPositionMCMatch(particle, position);
167 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
171 bool getLocalMomentum(
const Particle* particle, XYZVector& result)
173 const auto* extHit = getExtHit(particle);
174 if (not extHit)
return false;
175 int slotID = extHit->getCopyID();
176 const auto& momentum = extHit->getMomentum();
178 if ((not geo) or (not geo->isModuleIDValid(slotID)))
return false;
179 const auto& module = geo->getModule(slotID);
180 result = module.momentumToLocal(momentum);
184 double getTOPLocalPhi(
const Particle* particle)
187 bool ok = TOPVariable::getLocalMomentum(particle, momentum);
188 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
189 return momentum.Phi();
192 double getTOPLocalTheta(
const Particle* particle)
195 bool ok = TOPVariable::getLocalMomentum(particle, momentum);
196 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
197 return momentum.Theta();
200 bool getLocalMomentumMCMatch(
const Particle* particle, XYZVector& result)
202 const auto* barHit = getBarHit(particle);
203 if (not barHit)
return false;
204 int slotID = barHit->getModuleID();
205 const auto& momentum = barHit->getMomentum();
207 if ((not geo) or (not geo->isModuleIDValid(slotID)))
return false;
208 const auto& module = geo->getModule(slotID);
209 result = module.momentumToLocal(momentum);
213 double getTOPLocalPhiMCMatch(
const Particle* particle)
216 bool ok = TOPVariable::getLocalMomentumMCMatch(particle, momentum);
217 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
218 return momentum.Phi();
221 double getTOPLocalThetaMCMatch(
const Particle* particle)
224 bool ok = TOPVariable::getLocalMomentumMCMatch(particle, momentum);
225 if (not ok)
return std::numeric_limits<double>::quiet_NaN();
226 return momentum.Theta();
229 double computeTOF(
const Particle* particle,
int pdg)
231 const auto* extHit = getExtHit(particle);
232 if (not extHit)
return std::numeric_limits<double>::quiet_NaN();
233 auto extPDGCode = abs(extHit->getPdgCode());
234 double pmom = particle->getMomentumMagnitude();
235 double massExtHit = Const::ChargedStable(extPDGCode).getMass();
236 double betaExtHit = pmom /
sqrt(pmom * pmom + massExtHit * massExtHit);
237 double mass = pdg == 0 ? particle->getMass() : Const::ChargedStable(abs(pdg)).getMass();
238 double beta = pmom /
sqrt(pmom * pmom + mass * mass);
239 return extHit->getTOF() * betaExtHit / beta;
242 double getTOF(
const Particle* particle)
244 return computeTOF(particle, 0);
247 double getTOFMCMatch(
const Particle* particle)
249 const auto* barHit = getBarHit(particle);
250 if (not barHit)
return std::numeric_limits<double>::quiet_NaN();
251 StoreObjPtr<MCInitialParticles> mcInitialParticles;
252 double trueEventT0 = 0;
253 if (mcInitialParticles.isValid()) trueEventT0 = mcInitialParticles->getTime();
254 return barHit->getTime() - trueEventT0;
257 double getTOFExpert(
const Particle* particle,
const vector<double>& vars)
259 if (vars.size() != 1) {
260 B2FATAL(
"topTOFExpert(pdg): Need exactly one parameter (PDG code).");
262 int pdg =
static_cast<int>(vars[0]);
263 return computeTOF(particle, pdg);
268 double extrapTrackToTOPz(
const Particle* particle)
270 auto trk = particle->getTrack();
271 if (not trk)
return std::numeric_limits<double>::quiet_NaN();
272 auto trkfit = trk->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(particle->getPDGCode())));
273 if (not trkfit)
return std::numeric_limits<double>::quiet_NaN();
274 auto helix = trkfit->getHelix();
275 double arcLength = helix.getArcLength2DAtCylindricalR(120);
276 const auto& result = helix.getPositionAtArcLength2D(arcLength);
280 double extrapTrackToTOPtheta(
const Particle* particle)
282 auto trk = particle->getTrack();
283 if (not trk)
return std::numeric_limits<double>::quiet_NaN();
284 auto trkfit = trk->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(particle->getPDGCode())));
285 if (not trkfit)
return std::numeric_limits<double>::quiet_NaN();
286 auto helix = trkfit->getHelix();
287 double arcLength = helix.getArcLength2DAtCylindricalR(120);
288 const auto& result = helix.getPositionAtArcLength2D(arcLength);
289 return result.Theta();
292 double extrapTrackToTOPphi(
const Particle* particle)
294 auto trk = particle->getTrack();
295 if (not trk)
return std::numeric_limits<double>::quiet_NaN();
296 auto trkfit = trk->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(particle->getPDGCode())));
297 if (not trkfit)
return std::numeric_limits<double>::quiet_NaN();
298 auto helix = trkfit->getHelix();
299 double arcLength = helix.getArcLength2DAtCylindricalR(120);
300 const auto& result = helix.getPositionAtArcLength2D(arcLength);
306 double countHits(
const Particle* particle,
double tmin,
double tmax,
bool clean)
308 int slotID = getSlotID(particle);
309 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
311 StoreArray<TOPDigit> digits;
313 for (
const auto& digit : digits) {
314 if (digit.getModuleID() != slotID)
continue;
316 if (clean and digit.getHitQuality() != TOPDigit::c_Good)
continue;
317 if (digit.getTime() < tmin or digit.getTime() > tmax)
continue;
323 double topDigitCount(
const Particle* particle)
325 int slotID = getSlotID(particle);
326 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
328 StoreArray<TOPDigit> topDigits;
330 for (
const auto& t : topDigits) {
331 if (t.getModuleID() != slotID)
continue;
332 if (t.getHitQuality() != TOPDigit::c_Good)
continue;
338 double topDigitCountMCMatch(
const Particle* particle)
340 int slotID = getSlotID(particle);
341 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
343 auto* trk = particle->getTrack();
344 if (not trk)
return std::numeric_limits<double>::quiet_NaN();
346 auto* mcParticle = trk->getRelated<MCParticle>();
347 if (not mcParticle)
return std::numeric_limits<double>::quiet_NaN();
349 auto digits = mcParticle->getRelationsWith<TOPDigit>();
351 for (
const auto& digit : digits) {
352 if (digit.getModuleID() != slotID)
continue;
353 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
359 double topSignalDigitCount(
const Particle* particle)
361 int slotID = getSlotID(particle);
362 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
364 StoreArray<TOPDigit> digits;
366 for (
const auto& digit : digits) {
367 if (digit.getModuleID() != slotID)
continue;
368 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
369 if (abs(digit.getTime()) > 50)
continue;
370 if (digit.getTime() > 0) count++;
376 double topBackgroundDigitCount(
const Particle* particle)
378 return TOPVariable::countHits(particle, -50, 0,
true);
381 double topRawDigitCount(
const Particle* particle)
383 int slotID = getSlotID(particle);
384 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
386 StoreArray<TOPDigit> topDigits;
388 for (
const auto& t : topDigits) {
389 if (t.getModuleID() != slotID)
continue;
395 double countTOPHitsInInterval(
const Particle* particle,
const vector<double>& vars)
397 if (vars.size() != 2) {
398 B2FATAL(
"countTOPHitsInInterval(tmin, tmax): Need exactly two parameters (tmin, tmax)");
400 return TOPVariable::countHits(particle, vars[0], vars[1],
true);
403 double countRawTOPHitsInInterval(
const Particle* particle,
const vector<double>& vars)
405 if (vars.size() != 2) {
406 B2FATAL(
"countRawTOPHitsInInterval(tmin, tmax): Need exactly two parameters (tmin, tmax)");
408 return TOPVariable::countHits(particle, vars[0], vars[1],
false);
411 double countTOPHitsInIntervalMCMatch(
const Particle* particle,
const std::vector<double>& vars)
413 if (vars.size() != 2) {
414 B2FATAL(
"countTOPHitsInIntervalMCMatch(tmin, tmax): Need exactly two parameters (tmin, tmax)");
416 int slotID = getSlotID(particle);
417 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
419 auto* trk = particle->getTrack();
420 if (not trk)
return std::numeric_limits<double>::quiet_NaN();
422 auto* mcParticle = trk->getRelated<MCParticle>();
423 if (not mcParticle)
return std::numeric_limits<double>::quiet_NaN();
425 auto digits = mcParticle->getRelationsWith<TOPDigit>();
427 for (
const auto& digit : digits) {
428 if (digit.getModuleID() != slotID)
continue;
429 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
430 if (digit.getTime() < vars[0] or digit.getTime() > vars[1])
continue;
439 double getFlag(
const Particle* particle)
441 const auto* topLikelihood = getTOPLikelihood(particle);
442 if (not topLikelihood)
return 0;
443 return (topLikelihood->getFlag() == 1);
446 double getModuleID(
const Particle* particle)
448 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
449 return topLikelihood ? topLikelihood->getModuleID() : std::numeric_limits<double>::quiet_NaN();
452 double getEmissionX(
const Particle* particle)
454 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
455 return topLikelihood ? topLikelihood->getX() : std::numeric_limits<double>::quiet_NaN();
458 double getEmissionZ(
const Particle* particle)
460 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
461 return topLikelihood ? topLikelihood->getZ() : std::numeric_limits<double>::quiet_NaN();
464 double getTOPPhotonCount(
const Particle* particle)
466 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
467 return topLikelihood ? topLikelihood->getNphot() : std::numeric_limits<double>::quiet_NaN();
470 double expectedPhotonCount(
const Particle* particle,
int pdg)
472 const auto* topLikelihood = getTOPLikelihood(particle);
473 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
475 pdg = pdg != 0 ? pdg : particle->getPDGCode();
479 return topLikelihood->getEstPhot(chargedStable);
482 double getExpectedPhotonCount(
const Particle* particle)
484 return TOPVariable::expectedPhotonCount(particle, 0);
487 double getExpectedPhotonCountExpert(
const Particle* particle,
const vector<double>& vars)
489 if (vars.size() != 1) {
490 B2FATAL(
"Need exactly one parameter (pdg id).");
492 return TOPVariable::expectedPhotonCount(particle,
static_cast<int>(vars[0]));
495 double effectiveSignalYield(
const Particle* particle,
int pdg)
497 const auto* topLikelihood = getTOPLikelihood(particle);
498 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
500 pdg = pdg != 0 ? pdg : particle->getPDGCode();
504 return topLikelihood->getEffectiveSignalYield(chargedStable);
507 double getEffectiveSignalYield(
const Particle* particle)
509 return TOPVariable::effectiveSignalYield(particle, 0);
512 double getEffectiveSignalYieldExpert(
const Particle* particle,
const vector<double>& vars)
514 if (vars.size() != 1) {
515 B2FATAL(
"Need exactly one parameter (pdg id).");
517 return TOPVariable::effectiveSignalYield(particle,
static_cast<int>(vars[0]));
520 double getEstimatedBkgCount(
const Particle* particle)
522 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
523 return topLikelihood ? topLikelihood->getEstBkg() : std::numeric_limits<double>::quiet_NaN();
526 double getElectronLogL(
const Particle* particle)
528 const auto* topLikelihood = getTOPLikelihood(particle);
529 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
530 return topLikelihood->getLogL_e();
533 double getMuonLogL(
const Particle* particle)
535 const auto* topLikelihood = getTOPLikelihood(particle);
536 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
537 return topLikelihood->getLogL_mu();
540 double getPionLogL(
const Particle* particle)
542 const auto* topLikelihood = getTOPLikelihood(particle);
543 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
544 return topLikelihood->getLogL_pi();
547 double getKaonLogL(
const Particle* particle)
549 const auto* topLikelihood = getTOPLikelihood(particle);
550 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
551 return topLikelihood->getLogL_K();
554 double getProtonLogL(
const Particle* particle)
556 const auto* topLikelihood = getTOPLikelihood(particle);
557 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
558 return topLikelihood->getLogL_p();
561 double getDeuteronLogL(
const Particle* particle)
563 const auto* topLikelihood = getTOPLikelihood(particle);
564 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
570 double getLogLScanMass(
const Particle* particle)
572 auto* scanRes = getTOPLikelihoodScanResult(particle);
573 return scanRes ? scanRes->getMostLikelyMass() : std::numeric_limits<double>::quiet_NaN();
576 double getLogLScanMassUpperInterval(
const Particle* particle)
578 auto* scanRes = getTOPLikelihoodScanResult(particle);
579 return scanRes ? scanRes->getMostLikelyMassIntervalUp() : std::numeric_limits<double>::quiet_NaN();
582 double getLogLScanMassLowerInterval(
const Particle* particle)
584 auto* scanRes = getTOPLikelihoodScanResult(particle);
585 return scanRes ? scanRes->getMostLikelyMassIntervalLow() : std::numeric_limits<double>::quiet_NaN();
588 double getLogLScanThreshold(
const Particle* particle)
590 auto* scanRes = getTOPLikelihoodScanResult(particle);
591 return scanRes ? scanRes->getThreshold() : std::numeric_limits<double>::quiet_NaN();
594 double getLogLScanExpectedSignalPhotons(
const Particle* particle)
596 auto* scanRes = getTOPLikelihoodScanResult(particle);
597 return scanRes ? scanRes->getMostLikelySignalPhotonCount() : std::numeric_limits<double>::quiet_NaN();
602 double isTOPRecBunchReconstructed([[maybe_unused]]
const Particle* particle)
604 StoreObjPtr<TOPRecBunch> recBunch;
605 if (not recBunch.isValid())
return 0;
606 return recBunch->isReconstructed();
609 double TOPRecBunchNumber([[maybe_unused]]
const Particle* particle)
611 StoreObjPtr<TOPRecBunch> recBunch;
612 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
613 if (not recBunch->isReconstructed())
return std::numeric_limits<double>::quiet_NaN();
614 return recBunch->getBunchNo();
617 double TOPRecBucketNumber([[maybe_unused]]
const Particle* particle)
619 StoreObjPtr<TOPRecBunch> recBunch;
620 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
621 auto bucket = recBunch->getBucketNumber();
626 double isTOPRecBunchFilled([[maybe_unused]]
const Particle* particle)
628 StoreObjPtr<TOPRecBunch> recBunch;
629 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
630 return recBunch->getBucketFillStatus();
633 double isTOPRecBunchNumberEQsim([[maybe_unused]]
const Particle* particle)
635 StoreObjPtr<TOPRecBunch> recBunch;
636 if (not recBunch.isValid())
return 0;
637 if (not recBunch->isReconstructed())
return 0;
638 if (not recBunch->isSimulated())
return 0;
639 return (recBunch->getBunchNo() == recBunch->getMCBunchNo());
642 double TOPRecBunchCurrentOffset([[maybe_unused]]
const Particle* particle)
644 StoreObjPtr<TOPRecBunch> recBunch;
645 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
646 if (not recBunch->isReconstructed())
return std::numeric_limits<double>::quiet_NaN();
647 return recBunch->getCurrentOffset();
650 double TOPRecBunchTrackCount([[maybe_unused]]
const Particle* particle)
652 StoreObjPtr<TOPRecBunch> recBunch;
653 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
654 return recBunch->getNumTracks();
657 double TOPRecBunchUsedTrackCount([[maybe_unused]]
const Particle* particle)
659 StoreObjPtr<TOPRecBunch> recBunch;
660 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
661 return recBunch->getUsedTracks();
666 double TOPRawPhotonsInSlot([[maybe_unused]]
const Particle* particle,
const vector<double>& vars)
668 if (vars.size() != 1) { B2FATAL(
"Need exactly one parameter (slot id).");}
669 StoreArray<TOPDigit> topDigits;
670 int slotID =
static_cast<int>(vars[0]);
672 for (
const auto& t : topDigits) {
673 if (t.getModuleID() != slotID)
continue;
679 double TOPGoodPhotonsInSlot([[maybe_unused]]
const Particle* particle,
const vector<double>& vars)
681 if (vars.size() != 1) { B2FATAL(
"Need exactly one parameter (slot id).");}
682 StoreArray<TOPDigit> topDigits;
683 int slotID =
static_cast<int>(vars[0]);
685 for (
const auto& t : topDigits) {
686 if (t.getModuleID() != slotID)
continue;
687 if (t.getHitQuality() != TOPDigit::c_Good)
continue;
693 double TOPTracksInSlot(
const Particle* particle)
695 int slotID = getSlotID(particle);
696 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
698 StoreArray<Track> tracks;
700 for (
const auto& t : tracks) {
701 const auto* tl = t.getRelated<TOPLikelihood>();
702 if (not tl)
continue;
703 const auto* te = tl->getRelated<ExtHit>();
704 if (not te)
continue;
705 if (te->getCopyID() != slotID)
continue;
714 VARIABLE_GROUP(
"TOP Variables (cdst needed)");
715 REGISTER_VARIABLE(
"topSlotID", TOPVariable::topSlotID,
716 "slot ID of the particle");
717 REGISTER_VARIABLE(
"topSlotIDMCMatch", TOPVariable::topSlotIDMCMatch,
718 "slot ID of the matched MC particle");
720 REGISTER_VARIABLE(
"topLocalX", TOPVariable::getTOPLocalX,
721 "x coordinate of the particle entry point to TOP in the local frame");
722 REGISTER_VARIABLE(
"topLocalY", TOPVariable::getTOPLocalY,
723 "y coordinate of the particle entry point to TOP in the local frame");
724 REGISTER_VARIABLE(
"topLocalZ", TOPVariable::getTOPLocalZ,
725 "z coordinate of the particle entry point to TOP in the local frame");
726 REGISTER_VARIABLE(
"topLocalXMCMatch", TOPVariable::getTOPLocalXMCMatch,
727 "x coordinate of the matched MC particle entry point to TOP in the local frame");
728 REGISTER_VARIABLE(
"topLocalYMCMatch", TOPVariable::getTOPLocalYMCMatch,
729 "y coordinate of the matched MC particle entry point to TOP in the local frame");
730 REGISTER_VARIABLE(
"topLocalZMCMatch", TOPVariable::getTOPLocalZMCMatch,
731 "z coordinate of the matched MC particle entry point to TOP in the local frame");
732 REGISTER_VARIABLE(
"topLocalPhi", TOPVariable::getTOPLocalPhi,
733 "momentum azimuthal angle of the particle at entry point to TOP in the local frame");
734 REGISTER_VARIABLE(
"topLocalTheta", TOPVariable::getTOPLocalTheta,
735 "momentum polar angle of the particle at entry point to the TOP in the local frame");
736 REGISTER_VARIABLE(
"topLocalPhiMCMatch", TOPVariable::getTOPLocalPhiMCMatch,
737 "momentum azimuthal angle of the matched MC particle at entry point to TOP in the local frame");
738 REGISTER_VARIABLE(
"topLocalThetaMCMatch", TOPVariable::getTOPLocalThetaMCMatch,
739 "momentum polar angle of the matched MC particle at entry point to TOP in the local frame");
740 REGISTER_VARIABLE(
"topTOF", TOPVariable::getTOF,
741 "time-of-flight of the particle from the origin to TOP");
742 REGISTER_VARIABLE(
"topTOFMCMatch", TOPVariable::getTOFMCMatch,
743 "time-of-flight of the matched MC particle from the origin to TOP");
744 REGISTER_VARIABLE(
"topTOFExpert(pdg)", TOPVariable::getTOFExpert,
745 "time-of-flight from the origin to TOP for a given PDG code");
747 REGISTER_VARIABLE(
"extrapTrackToTOPimpactZ", TOPVariable::extrapTrackToTOPz,
748 "z coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
749 REGISTER_VARIABLE(
"extrapTrackToTOPimpactTheta", TOPVariable::extrapTrackToTOPtheta,
750 "theta coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
751 REGISTER_VARIABLE(
"extrapTrackToTOPimpactPhi", TOPVariable::extrapTrackToTOPphi,
752 "phi coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
754 REGISTER_VARIABLE(
"topDigitCount", TOPVariable::topDigitCount,
755 "number of good digits in the same module as particle");
756 REGISTER_VARIABLE(
"topDigitCountSignal", TOPVariable::topSignalDigitCount,
757 "number of good, background-subtracted digits in interval [0, 50 ns] of the same module as particle");
758 REGISTER_VARIABLE(
"topDigitCountBkg", TOPVariable::topBackgroundDigitCount,
759 "number of good digits in interval [-50 ns, 0] of the same module as particle");
760 REGISTER_VARIABLE(
"topDigitCountRaw", TOPVariable::topRawDigitCount,
761 "number of all digits (regardless of hit quality) in the same module as particle");
762 REGISTER_VARIABLE(
"topDigitCountInterval(tmin, tmax)", TOPVariable::countTOPHitsInInterval,
763 "number of good digits in a given time interval of the same module as particle");
764 REGISTER_VARIABLE(
"topDigitCountIntervalRaw(tmin, tmax)", TOPVariable::countRawTOPHitsInInterval,
765 "number of all digits (regardless of hit quality) in a given time interval of the same module as particle");
766 REGISTER_VARIABLE(
"topDigitCountMCMatch", TOPVariable::topDigitCountMCMatch,
767 "number of good digits associated with the matched MC particle and in the same module as particle");
768 REGISTER_VARIABLE(
"topDigitCountIntervalMCMatch(tmin, tmax)", TOPVariable::countTOPHitsInIntervalMCMatch,
769 "number of good digits associated with the matched MC particle in a given time interval and in the same module as particle");
771 REGISTER_VARIABLE(
"topLogLFlag", TOPVariable::getFlag,
772 "reconstruction flag: 1 if log likelihoods available, 0 otherwise");
773 REGISTER_VARIABLE(
"topLogLSlotID", TOPVariable::getModuleID,
774 "slot ID of the particle (from TOPLikelihoods)");
775 REGISTER_VARIABLE(
"topLogLEmiX", TOPVariable::getEmissionX,
776 "photon emission point assumed in PDF construction: coordinate x in local frame");
777 REGISTER_VARIABLE(
"topLogLEmiZ", TOPVariable::getEmissionZ,
778 "photon emission point assumed in PDF construction: coordinate z in local frame");
779 REGISTER_VARIABLE(
"topLogLPhotonCount", TOPVariable::getTOPPhotonCount,
780 "number of photons used for log likelihood calculation");
781 REGISTER_VARIABLE(
"topLogLExpectedPhotonCount", TOPVariable::getExpectedPhotonCount,
782 "expected number of photons (including bkg) for this particle");
783 REGISTER_VARIABLE(
"topLogLExpectedPhotonCountExpert(pdg)", TOPVariable::getExpectedPhotonCountExpert,
784 "expected number of photons (including bkg) for a given PDG code");
785 REGISTER_VARIABLE(
"topLogLEstimatedBkgCount", TOPVariable::getEstimatedBkgCount,
786 "estimated number of background photons");
787 REGISTER_VARIABLE(
"topLogLSignalYield", TOPVariable::getEffectiveSignalYield,
788 "effective number of signal photons for this particle (sum of sPlot weights)");
789 REGISTER_VARIABLE(
"topLogLSignalYieldExpert(pdg)", TOPVariable::getEffectiveSignalYieldExpert,
790 "effective number of signal photons for a given PDG code (sum of sPlot weights)");
791 REGISTER_VARIABLE(
"topLogLElectron", TOPVariable::getElectronLogL,
792 "electron log likelihood");
793 REGISTER_VARIABLE(
"topLogLMuon", TOPVariable::getMuonLogL,
794 "muon log likelihood");
795 REGISTER_VARIABLE(
"topLogLPion", TOPVariable::getPionLogL,
796 "pion log likelihood");
797 REGISTER_VARIABLE(
"topLogLKaon", TOPVariable::getKaonLogL,
798 "kaon log likelihood");
799 REGISTER_VARIABLE(
"topLogLProton", TOPVariable::getProtonLogL,
800 "proton log likelihood");
801 REGISTER_VARIABLE(
"topLogLDeuteron", TOPVariable::getDeuteronLogL,
802 "deuteron log likelihood");
804 REGISTER_VARIABLE(
"logLScanMass", TOPVariable::getLogLScanMass,
805 "mass at the logL maximum from the LL scan. Requires TOPLLScanner in the processing path.");
806 REGISTER_VARIABLE(
"logLScanMassUpperInterval", TOPVariable::getLogLScanMassUpperInterval,
807 "Upper edge of the mass interval determined by the LL scan. Requires TOPLLScanner in the processing path.");
808 REGISTER_VARIABLE(
"logLScanMassLowerInterval", TOPVariable::getLogLScanMassLowerInterval,
809 "Lower edge of the mass interval determined by the LL scan. Requires TOPLLScanner in the processing path.");
810 REGISTER_VARIABLE(
"logLScanThreshold", TOPVariable::getLogLScanThreshold,
811 "Cherenkov threshold determind by the LL scan. Requires TOPLLScanner in the processing path.");
812 REGISTER_VARIABLE(
"logLScanExpectedSignalPhotons", TOPVariable::getLogLScanExpectedSignalPhotons,
813 "Expected signal photon yield at the LL maximum. Requires TOPLLScanner in the processing path.");
815 REGISTER_VARIABLE(
"topBunchIsReconstructed", TOPVariable::isTOPRecBunchReconstructed,
816 "reconstruction flag: 1 if reconstructed, 0 otherwise");
817 REGISTER_VARIABLE(
"topBunchIsFilled", TOPVariable::isTOPRecBunchFilled,
818 "bunch fill status: 0 empty, 1 filled, -1 unknown");
819 REGISTER_VARIABLE(
"topBunchNumber", TOPVariable::TOPRecBunchNumber,
820 "reconstructed bunch number relative to L1 trigger");
821 REGISTER_VARIABLE(
"topBucketNumber", TOPVariable::TOPRecBucketNumber,
822 "reconstructed bucket number within the ring");
823 REGISTER_VARIABLE(
"topBunchMCMatch", TOPVariable::isTOPRecBunchNumberEQsim,
824 "MC matching status: 1 if reconstructed bunch equal to simulated bunch, 0 otherwise");
825 REGISTER_VARIABLE(
"topBunchOffset", TOPVariable::TOPRecBunchCurrentOffset,
826 "current offset to the reconstructed bunch crossing time");
827 REGISTER_VARIABLE(
"topBunchTrackCount", TOPVariable::TOPRecBunchTrackCount,
828 "number of tracks selected for the bunch reconstruction");
829 REGISTER_VARIABLE(
"topBunchUsedTrackCount", TOPVariable::TOPRecBunchUsedTrackCount,
830 "number of tracks actually used in the bunch reconstruction");
832 REGISTER_VARIABLE(
"topRawPhotonsInSlot(id)", TOPVariable::TOPRawPhotonsInSlot,
833 "number of all photons in the given slot id");
834 REGISTER_VARIABLE(
"topGoodPhotonsInSlot(id)", TOPVariable::TOPGoodPhotonsInSlot,
835 "number of good photons in the given slot id");
836 REGISTER_VARIABLE(
"topTracksInSlot", TOPVariable::TOPTracksInSlot,
837 "number of tracks in the same slot as particle");
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
static const ParticleSet chargedStableSet
set of charged stable particles
static const ParticleType invalidParticle
Invalid particle, used internally.
static const ChargedStable deuteron
deuteron particle
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.