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>
32 using 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());
103 const auto* geo = TOP::TOPGeometryPar::Instance()->getGeometry();
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();
140 const auto* geo = TOP::TOPGeometryPar::Instance()->getGeometry();
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();
177 const auto* geo = TOP::TOPGeometryPar::Instance()->getGeometry();
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();
206 const auto* geo = TOP::TOPGeometryPar::Instance()->getGeometry();
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 getTOPPhotonCount(
const Particle* particle)
448 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
449 return topLikelihood ? topLikelihood->getNphot() : std::numeric_limits<double>::quiet_NaN();
452 double expectedPhotonCount(
const Particle* particle,
int pdg)
454 const auto* topLikelihood = getTOPLikelihood(particle);
455 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
457 pdg = pdg != 0 ? pdg : particle->getPDGCode();
458 const auto& chargedStable = Const::chargedStableSet.find(abs(pdg));
459 if (chargedStable == Const::invalidParticle)
return std::numeric_limits<double>::quiet_NaN();
461 return topLikelihood->getEstPhot(chargedStable);
464 double getExpectedPhotonCount(
const Particle* particle)
466 return TOPVariable::expectedPhotonCount(particle, 0);
469 double getExpectedPhotonCountExpert(
const Particle* particle,
const vector<double>& vars)
471 if (vars.size() != 1) {
472 B2FATAL(
"Need exactly one parameter (pdg id).");
474 return TOPVariable::expectedPhotonCount(particle,
static_cast<int>(vars[0]));
477 double getEstimatedBkgCount(
const Particle* particle)
479 const auto* topLikelihood = TOPVariable::getTOPLikelihood(particle);
480 return topLikelihood ? topLikelihood->getEstBkg() : std::numeric_limits<double>::quiet_NaN();
483 double getElectronLogL(
const Particle* particle)
485 const auto* topLikelihood = getTOPLikelihood(particle);
486 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
487 return topLikelihood->getLogL_e();
490 double getMuonLogL(
const Particle* particle)
492 const auto* topLikelihood = getTOPLikelihood(particle);
493 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
494 return topLikelihood->getLogL_mu();
497 double getPionLogL(
const Particle* particle)
499 const auto* topLikelihood = getTOPLikelihood(particle);
500 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
501 return topLikelihood->getLogL_pi();
504 double getKaonLogL(
const Particle* particle)
506 const auto* topLikelihood = getTOPLikelihood(particle);
507 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
508 return topLikelihood->getLogL_K();
511 double getProtonLogL(
const Particle* particle)
513 const auto* topLikelihood = getTOPLikelihood(particle);
514 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
515 return topLikelihood->getLogL_p();
518 double getDeuteronLogL(
const Particle* particle)
520 const auto* topLikelihood = getTOPLikelihood(particle);
521 if (not topLikelihood)
return std::numeric_limits<double>::quiet_NaN();
522 return topLikelihood->getLogL(Const::deuteron);
527 double getLogLScanMass(
const Particle* particle)
529 auto* scanRes = getTOPLikelihoodScanResult(particle);
530 return scanRes ? scanRes->getMostLikelyMass() : std::numeric_limits<double>::quiet_NaN();
533 double getLogLScanMassUpperInterval(
const Particle* particle)
535 auto* scanRes = getTOPLikelihoodScanResult(particle);
536 return scanRes ? scanRes->getMostLikelyMassIntervalUp() : std::numeric_limits<double>::quiet_NaN();
539 double getLogLScanMassLowerInterval(
const Particle* particle)
541 auto* scanRes = getTOPLikelihoodScanResult(particle);
542 return scanRes ? scanRes->getMostLikelyMassIntervalLow() : std::numeric_limits<double>::quiet_NaN();
545 double getLogLScanThreshold(
const Particle* particle)
547 auto* scanRes = getTOPLikelihoodScanResult(particle);
548 return scanRes ? scanRes->getThreshold() : std::numeric_limits<double>::quiet_NaN();
551 double getLogLScanExpectedSignalPhotons(
const Particle* particle)
553 auto* scanRes = getTOPLikelihoodScanResult(particle);
554 return scanRes ? scanRes->getMostLikelySignalPhotonCount() : std::numeric_limits<double>::quiet_NaN();
559 double isTOPRecBunchReconstructed([[maybe_unused]]
const Particle* particle)
561 StoreObjPtr<TOPRecBunch> recBunch;
562 if (not recBunch.isValid())
return 0;
563 return recBunch->isReconstructed();
566 double TOPRecBunchNumber([[maybe_unused]]
const Particle* particle)
568 StoreObjPtr<TOPRecBunch> recBunch;
569 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
570 if (not recBunch->isReconstructed())
return std::numeric_limits<double>::quiet_NaN();
571 return recBunch->getBunchNo();
574 double TOPRecBucketNumber([[maybe_unused]]
const Particle* particle)
576 StoreObjPtr<TOPRecBunch> recBunch;
577 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
578 auto bucket = recBunch->getBucketNumber();
579 if (bucket == TOPRecBunch::c_Unknown)
return std::numeric_limits<double>::quiet_NaN();
583 double isTOPRecBunchFilled([[maybe_unused]]
const Particle* particle)
585 StoreObjPtr<TOPRecBunch> recBunch;
586 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
587 return recBunch->getBucketFillStatus();
590 double isTOPRecBunchNumberEQsim([[maybe_unused]]
const Particle* particle)
592 StoreObjPtr<TOPRecBunch> recBunch;
593 if (not recBunch.isValid())
return 0;
594 if (not recBunch->isReconstructed())
return 0;
595 if (not recBunch->isSimulated())
return 0;
596 return (recBunch->getBunchNo() == recBunch->getMCBunchNo());
599 double TOPRecBunchCurrentOffset([[maybe_unused]]
const Particle* particle)
601 StoreObjPtr<TOPRecBunch> recBunch;
602 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
603 if (not recBunch->isReconstructed())
return std::numeric_limits<double>::quiet_NaN();
604 return recBunch->getCurrentOffset();
607 double TOPRecBunchTrackCount([[maybe_unused]]
const Particle* particle)
609 StoreObjPtr<TOPRecBunch> recBunch;
610 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
611 return recBunch->getNumTracks();
614 double TOPRecBunchUsedTrackCount([[maybe_unused]]
const Particle* particle)
616 StoreObjPtr<TOPRecBunch> recBunch;
617 if (not recBunch.isValid())
return std::numeric_limits<double>::quiet_NaN();
618 return recBunch->getUsedTracks();
623 double TOPRawPhotonsInSlot([[maybe_unused]]
const Particle* particle,
const vector<double>& vars)
625 if (vars.size() != 1) { B2FATAL(
"Need exactly one parameter (slot id).");}
626 StoreArray<TOPDigit> topDigits;
627 int slotID =
static_cast<int>(vars[0]);
629 for (
const auto& t : topDigits) {
630 if (t.getModuleID() != slotID)
continue;
636 double TOPGoodPhotonsInSlot([[maybe_unused]]
const Particle* particle,
const vector<double>& vars)
638 if (vars.size() != 1) { B2FATAL(
"Need exactly one parameter (slot id).");}
639 StoreArray<TOPDigit> topDigits;
640 int slotID =
static_cast<int>(vars[0]);
642 for (
const auto& t : topDigits) {
643 if (t.getModuleID() != slotID)
continue;
644 if (t.getHitQuality() != TOPDigit::c_Good)
continue;
650 double TOPTracksInSlot(
const Particle* particle)
652 int slotID = getSlotID(particle);
653 if (slotID == 0)
return std::numeric_limits<double>::quiet_NaN();
655 StoreArray<Track> tracks;
657 for (
const auto& t : tracks) {
658 const auto* tl = t.getRelated<TOPLikelihood>();
659 if (not tl)
continue;
660 const auto* te = tl->getRelated<ExtHit>();
661 if (not te)
continue;
662 if (te->getCopyID() != slotID)
continue;
671 VARIABLE_GROUP(
"TOP Variables (cdst needed)");
672 REGISTER_VARIABLE(
"topSlotID", TOPVariable::topSlotID,
673 "slot ID of the particle");
674 REGISTER_VARIABLE(
"topSlotIDMCMatch", TOPVariable::topSlotIDMCMatch,
675 "slot ID of the matched MC particle");
677 REGISTER_VARIABLE(
"topLocalX", TOPVariable::getTOPLocalX,
678 "x coordinate of the particle entry point to TOP in the local frame");
679 REGISTER_VARIABLE(
"topLocalY", TOPVariable::getTOPLocalY,
680 "y coordinate of the particle entry point to TOP in the local frame");
681 REGISTER_VARIABLE(
"topLocalZ", TOPVariable::getTOPLocalZ,
682 "z coordinate of the particle entry point to TOP in the local frame");
683 REGISTER_VARIABLE(
"topLocalXMCMatch", TOPVariable::getTOPLocalXMCMatch,
684 "x coordinate of the matched MC particle entry point to TOP in the local frame");
685 REGISTER_VARIABLE(
"topLocalYMCMatch", TOPVariable::getTOPLocalYMCMatch,
686 "y coordinate of the matched MC particle entry point to TOP in the local frame");
687 REGISTER_VARIABLE(
"topLocalZMCMatch", TOPVariable::getTOPLocalZMCMatch,
688 "z coordinate of the matched MC particle entry point to TOP in the local frame");
689 REGISTER_VARIABLE(
"topLocalPhi", TOPVariable::getTOPLocalPhi,
690 "momentum azimuthal angle of the particle at entry point to TOP in the local frame");
691 REGISTER_VARIABLE(
"topLocalTheta", TOPVariable::getTOPLocalTheta,
692 "momentum polar angle of the particle at entry point to the TOP in the local frame");
693 REGISTER_VARIABLE(
"topLocalPhiMCMatch", TOPVariable::getTOPLocalPhiMCMatch,
694 "momentum azimuthal angle of the matched MC particle at entry point to TOP in the local frame");
695 REGISTER_VARIABLE(
"topLocalThetaMCMatch", TOPVariable::getTOPLocalThetaMCMatch,
696 "momentum polar angle of the matched MC particle at entry point to TOP in the local frame");
697 REGISTER_VARIABLE(
"topTOF", TOPVariable::getTOF,
698 "time-of-flight of the particle from the origin to TOP");
699 REGISTER_VARIABLE(
"topTOFMCMatch", TOPVariable::getTOFMCMatch,
700 "time-of-flight of the matched MC particle from the origin to TOP");
701 REGISTER_VARIABLE(
"topTOFExpert(pdg)", TOPVariable::getTOFExpert,
702 "time-of-flight from the origin to TOP for a given PDG code");
704 REGISTER_VARIABLE(
"extrapTrackToTOPimpactZ", TOPVariable::extrapTrackToTOPz,
705 "z coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
706 REGISTER_VARIABLE(
"extrapTrackToTOPimpactTheta", TOPVariable::extrapTrackToTOPtheta,
707 "theta coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
708 REGISTER_VARIABLE(
"extrapTrackToTOPimpactPhi", TOPVariable::extrapTrackToTOPphi,
709 "phi coordinate of the track extrapolated to R = 120 cm using helix from TrackFitResult");
711 REGISTER_VARIABLE(
"topDigitCount", TOPVariable::topDigitCount,
712 "number of good digits in the same module as particle");
713 REGISTER_VARIABLE(
"topDigitCountSignal", TOPVariable::topSignalDigitCount,
714 "number of good, background-subtracted digits in interval [0, 50 ns] of the same module as particle");
715 REGISTER_VARIABLE(
"topDigitCountBkg", TOPVariable::topBackgroundDigitCount,
716 "number of good digits in interval [-50 ns, 0] of the same module as particle");
717 REGISTER_VARIABLE(
"topDigitCountRaw", TOPVariable::topRawDigitCount,
718 "number of all digits (regardless of hit quality) in the same module as particle");
719 REGISTER_VARIABLE(
"topDigitCountInterval(tmin, tmax)", TOPVariable::countTOPHitsInInterval,
720 "number of good digits in a given time interval of the same module as particle");
721 REGISTER_VARIABLE(
"topDigitCountIntervalRaw(tmin, tmax)", TOPVariable::countRawTOPHitsInInterval,
722 "number of all digits (regardless of hit quality) in a given time interval of the same module as particle");
723 REGISTER_VARIABLE(
"topDigitCountMCMatch", TOPVariable::topDigitCountMCMatch,
724 "number of good digits associated with the matched MC particle and in the same module as particle");
725 REGISTER_VARIABLE(
"topDigitCountIntervalMCMatch(tmin, tmax)", TOPVariable::countTOPHitsInIntervalMCMatch,
726 "number of good digits associated with the matched MC particle in a given time interval and in the same module as particle");
728 REGISTER_VARIABLE(
"topLogLFlag", TOPVariable::getFlag,
729 "reconstruction flag: 1 if log likelihoods available, 0 otherwise");
730 REGISTER_VARIABLE(
"topLogLPhotonCount", TOPVariable::getTOPPhotonCount,
731 "number of photons used for log likelihood calculation");
732 REGISTER_VARIABLE(
"topLogLExpectedPhotonCount", TOPVariable::getExpectedPhotonCount,
733 "expected number of photons (including bkg) for this particle");
734 REGISTER_VARIABLE(
"topLogLExpectedPhotonCountExpert(pdg)", TOPVariable::getExpectedPhotonCountExpert,
735 "expected number of photons (including bkg) for a given PDG code");
736 REGISTER_VARIABLE(
"topLogLEstimatedBkgCount", TOPVariable::getEstimatedBkgCount,
737 "estimated number of background photons");
738 REGISTER_VARIABLE(
"topLogLElectron", TOPVariable::getElectronLogL,
739 "electron log likelihood");
740 REGISTER_VARIABLE(
"topLogLMuon", TOPVariable::getMuonLogL,
741 "muon log likelihood");
742 REGISTER_VARIABLE(
"topLogLPion", TOPVariable::getPionLogL,
743 "pion log likelihood");
744 REGISTER_VARIABLE(
"topLogLKaon", TOPVariable::getKaonLogL,
745 "kaon log likelihood");
746 REGISTER_VARIABLE(
"topLogLProton", TOPVariable::getProtonLogL,
747 "proton log likelihood");
748 REGISTER_VARIABLE(
"topLogLDeuteron", TOPVariable::getDeuteronLogL,
749 "deuteron log likelihood");
751 REGISTER_VARIABLE(
"logLScanMass", TOPVariable::getLogLScanMass,
752 "mass at the logL maximum from the LL scan. Requires TOPLLScanner in the processing path.");
753 REGISTER_VARIABLE(
"logLScanMassUpperInterval", TOPVariable::getLogLScanMassUpperInterval,
754 "Upper edge of the mass interval determined by the LL scan. Requires TOPLLScanner in the processing path.");
755 REGISTER_VARIABLE(
"logLScanMassLowerInterval", TOPVariable::getLogLScanMassLowerInterval,
756 "Lower edge of the mass interval determined by the LL scan. Requires TOPLLScanner in the processing path.");
757 REGISTER_VARIABLE(
"logLScanThreshold", TOPVariable::getLogLScanThreshold,
758 "Cherenkov threshold determind by the LL scan. Requires TOPLLScanner in the processing path.");
759 REGISTER_VARIABLE(
"logLScanExpectedSignalPhotons", TOPVariable::getLogLScanExpectedSignalPhotons,
760 "Expected signal photon yield at the LL maximum. Requires TOPLLScanner in the processing path.");
762 REGISTER_VARIABLE(
"topBunchIsReconstructed", TOPVariable::isTOPRecBunchReconstructed,
763 "reconstruction flag: 1 if reconstructed, 0 otherwise");
764 REGISTER_VARIABLE(
"topBunchIsFilled", TOPVariable::isTOPRecBunchFilled,
765 "bunch fill status: 0 empty, 1 filled, -1 unknown");
766 REGISTER_VARIABLE(
"topBunchNumber", TOPVariable::TOPRecBunchNumber,
767 "reconstructed bunch number relative to L1 trigger");
768 REGISTER_VARIABLE(
"topBucketNumber", TOPVariable::TOPRecBucketNumber,
769 "reconstructed bucket number within the ring");
770 REGISTER_VARIABLE(
"topBunchMCMatch", TOPVariable::isTOPRecBunchNumberEQsim,
771 "MC matching status: 1 if reconstructed bunch equal to simulated bunch, 0 otherwise");
772 REGISTER_VARIABLE(
"topBunchOffset", TOPVariable::TOPRecBunchCurrentOffset,
773 "current offset to the reconstructed bunch crossing time");
774 REGISTER_VARIABLE(
"topBunchTrackCount", TOPVariable::TOPRecBunchTrackCount,
775 "number of tracks selected for the bunch reconstruction");
776 REGISTER_VARIABLE(
"topBunchUsedTrackCount", TOPVariable::TOPRecBunchUsedTrackCount,
777 "number of tracks actually used in the bunch reconstruction");
779 REGISTER_VARIABLE(
"topRawPhotonsInSlot(id)", TOPVariable::TOPRawPhotonsInSlot,
780 "number of all photons in the given slot id");
781 REGISTER_VARIABLE(
"topGoodPhotonsInSlot(id)", TOPVariable::TOPGoodPhotonsInSlot,
782 "number of good photons in the given slot id");
783 REGISTER_VARIABLE(
"topTracksInSlot", TOPVariable::TOPTracksInSlot,
784 "number of tracks in the same slot as particle");
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.