9#include <hlt/softwaretrigger/calculations/SkimSampleCalculator.h>
11#include <hlt/softwaretrigger/calculations/utilities.h>
13#include <analysis/utility/PCmsLabTransform.h>
14#include <analysis/utility/ReferenceFrame.h>
16#include <analysis/ClusterUtility/ClusterUtils.h>
17#include <analysis/ContinuumSuppression/FoxWolfram.h>
18#include <analysis/dataobjects/Particle.h>
20#include <analysis/variables/AcceptanceVariables.h>
21#include <analysis/variables/BelleVariables.h>
22#include <analysis/variables/ECLVariables.h>
23#include <analysis/variables/FlightInfoVariables.h>
25#include <framework/geometry/B2Vector3.h>
27#include <mdst/dataobjects/HitPatternCDC.h>
28#include <mdst/dataobjects/KLMCluster.h>
29#include <mdst/dataobjects/PIDLikelihood.h>
30#include <mdst/dataobjects/SoftwareTriggerResult.h>
31#include <mdst/dataobjects/Track.h>
32#include <mdst/dataobjects/TrackFitResult.h>
34#include <cdc/dataobjects/CDCDedxTrack.h>
37#include <TDatabasePDG.h>
40using namespace SoftwareTrigger;
43 m_pionParticles(
"pi+:skim"), m_gammaParticles(
"gamma:skim"), m_pionHadParticles(
"pi+:hadb"), m_pionTauParticles(
"pi+:tau"),
44 m_KsParticles(
"K_S0:merged"), m_LambdaParticles(
"Lambda0:merged"), m_DstParticles(
"D*+:d0pi"), m_offIpParticles(
"pi+:offip"),
45 m_filterL1TrgNN(
"software_trigger_cut&filter&L1_trigger_nn_info"),
46 m_BpParticles(
"B+:BtoCharmForHLT"), m_BzParticles(
"B0:BtoCharmForHLT")
71 getRho(gammaWithMaximumRho));
74 getRho(trackWithMaximumRho));
77 const double& rhoOfECLClusterWithSecondMaximumRho = getRhoOfECLClusterWithMaximumRhoBelow(
m_pionParticles,
79 rhoOfECLClusterWithMaximumRho);
81 const double& rhoOfTrackWithMaximumRho = getRho(trackWithMaximumRho);
82 const double& rhoOfTrackWithSecondMaximumRho = getRho(trackWithSecondMaximumRho);
83 const double& rhoOfGammaWithMaximumRho = getRho(gammaWithMaximumRho);
84 const double& rhoOfGammaWithSecondMaximumRho = getRho(gammaWithSecondMaximumRho);
88 calculationResult[
"EC1CMSLE"] = rhoOfECLClusterWithMaximumRho;
91 calculationResult[
"EC2CMSLE"] = rhoOfECLClusterWithSecondMaximumRho;
94 calculationResult[
"EC12CMSLE"] = rhoOfECLClusterWithMaximumRho + rhoOfECLClusterWithSecondMaximumRho;
106 calculationResult[
"P1CMSBhabhaLE"] = rhoOfTrackWithMaximumRho;
109 calculationResult[
"P1OEbeamCMSBhabhaLE"] = rhoOfTrackWithMaximumRho / BeamEnergyCMS();
112 calculationResult[
"P2CMSBhabhaLE"] = rhoOfTrackWithSecondMaximumRho;
115 calculationResult[
"P2OEbeamCMSBhabhaLE"] = rhoOfTrackWithSecondMaximumRho / BeamEnergyCMS();
118 calculationResult[
"P12CMSBhabhaLE"] = rhoOfTrackWithMaximumRho + rhoOfTrackWithSecondMaximumRho;
121 calculationResult[
"G1CMSBhabhaLE"] = rhoOfGammaWithMaximumRho;
123 calculationResult[
"G1OEbeamCMSBhabhaLE"] = rhoOfGammaWithMaximumRho / BeamEnergyCMS();
126 calculationResult[
"G2CMSBhabhaLE"] = rhoOfGammaWithSecondMaximumRho;
128 calculationResult[
"G2OEbeamCMSBhabhaLE"] = rhoOfGammaWithSecondMaximumRho / BeamEnergyCMS();
131 calculationResult[
"G12CMSBhabhaLE"] = rhoOfGammaWithMaximumRho + rhoOfGammaWithSecondMaximumRho;
133 calculationResult[
"G12OEbeamCMSBhabhaLE"] =
134 (rhoOfGammaWithMaximumRho + rhoOfGammaWithSecondMaximumRho) / BeamEnergyCMS();
139 if (gammaWithMaximumRho) {
140 calculationResult[
"ENeutralLE"] = getRho(gammaWithMaximumRho);
142 calculationResult[
"ENeutralLE"] = -1;
148 return particle.getECLCluster() != nullptr;
150 calculationResult[
"nECLMatchTracksLE"] = numberOfTracksWithECLMatch;
153 double neclClusters = -1.;
154 double eneclClusters = 0.;
158 double EsumGamma = 0.;
160 const unsigned int numberOfECLClusters = std::count_if(eclClusters.
begin(), eclClusters.
end(),
162 return (eclcluster.hasHypothesis(
163 ECLCluster::EHypothesisBit::c_nPhotons)
164 and eclcluster.getEnergy(
165 ECLCluster::EHypothesisBit::c_nPhotons) > 0.1);
167 neclClusters = numberOfECLClusters;
169 for (
int ncl = 0; ncl < eclClusters.
getEntries(); ncl++) {
173 if (!eclClusters[ncl]->getRelatedFrom<Track>()) {
176 EsumGamma += V4Gamma_CMS.E();
177 PzGamma += V4Gamma_CMS.Pz();
182 calculationResult[
"nECLClustersLE"] = neclClusters;
184 int nb2bcc_PhiHigh = 0;
185 int nb2bcc_PhiLow = 0;
188 for (
int i = 0; i < eclClusters.
getEntries() - 1; i++) {
192 double Eg1 = V4g1.E();
193 for (
int j = i + 1; j < eclClusters.
getEntries(); j++) {
197 double Eg2 = V4g2.E();
202 double deltphi = fabs(V3g1.
DeltaPhi(V3g2) * TMath::RadToDeg());
203 double Tsum = Thetag1 + Thetag2;
204 if (deltphi > 170. && (Eg1 > 0.25 && Eg2 > 0.25)) nb2bcc_PhiHigh++;
205 if (deltphi > 170. && (Eg1 < 0.25 || Eg2 < 0.25)) nb2bcc_PhiLow++;
206 if (deltphi > 160. && (Tsum > 160. && Tsum < 200.)) nb2bcc_3D++;
210 calculationResult[
"nB2BCCPhiHighLE"] = nb2bcc_PhiHigh;
211 calculationResult[
"nB2BCCPhiLowLE"] = nb2bcc_PhiLow;
212 calculationResult[
"nB2BCC3DLE"] = nb2bcc_3D;
216 double angleGTLE = -10.;
217 if (gammaWithMaximumRho) {
219 if (trackWithMaximumRho) {
221 const double theta1 = V3g1.
Angle(V3p1);
222 if (angleGTLE < theta1) angleGTLE = theta1;
224 if (trackWithSecondMaximumRho) {
226 const double theta2 = V3g1.
Angle(V3p2);
227 if (angleGTLE < theta2) angleGTLE = theta2;
231 calculationResult[
"AngleGTLE"] = angleGTLE;
234 double angleG1G2CMSLE = -10.;
235 if (gammaWithMaximumRho) {
236 const ROOT::Math::PxPyPzEVector& V4p1 = gammaWithMaximumRho->
get4Vector();
237 if (gammaWithSecondMaximumRho) {
238 const ROOT::Math::PxPyPzEVector& V4p2 = gammaWithSecondMaximumRho->
get4Vector();
241 angleG1G2CMSLE = V3p1.
Angle(V3p2);
245 calculationResult[
"AngleG1G2CMSLE"] = angleG1G2CMSLE;
248 double maxAngleTTLE = -10.;
251 const double jPsiMasswindow = 0.11;
253 for (
unsigned int i = 0; i <
m_pionParticles->getListSize() - 1; i++) {
255 for (
unsigned int j = i + 1; j <
m_pionParticles->getListSize(); j++) {
257 ROOT::Math::PxPyPzEVector V4p1 = par1->
get4Vector();
258 ROOT::Math::PxPyPzEVector V4p2 = par2->
get4Vector();
259 ROOT::Math::PxPyPzEVector V4pSum = V4p1 + V4p2;
261 const double mSum = V4pSum.M();
262 const double JpsidM = mSum - TDatabasePDG::Instance()->GetParticle(443)->Mass();
263 if (abs(JpsidM) < jPsiMasswindow && chSum == 0) nJpsi++;
266 const double temp = V3p1.
Angle(V3p2);
267 if (maxAngleTTLE < temp) maxAngleTTLE = temp;
272 if (nJpsi != 0) Jpsi = 1;
274 calculationResult[
"maxAngleTTLE"] = maxAngleTTLE;
275 calculationResult[
"Jpsi"] = Jpsi;
278 double maxAngleGGLE = -10.;
284 ROOT::Math::PxPyPzEVector V4p1 = par1->
get4Vector();
285 ROOT::Math::PxPyPzEVector V4p2 = par2->
get4Vector();
288 const double temp = V3p1.
Angle(V3p2);
289 if (maxAngleGGLE < temp) maxAngleGGLE = temp;
294 calculationResult[
"maxAngleGGLE"] = maxAngleGGLE;
299 const double& momentum = p.getMomentumMagnitude();
300 const double& r_rho = getRho(&p);
301 const ECLCluster* eclTrack = p.getECLCluster();
303 const double& energyOverMomentum = eclTrack->getEnergy(
304 ECLCluster::EHypothesisBit::c_nPhotons) / momentum;
305 double r_rhotoebeam = r_rho / BeamEnergyCMS();
306 return (r_rhotoebeam) > 0.35 && energyOverMomentum > 0.8;
311 calculationResult[
"nEidLE"] = nEidLE;
315 const double visibleEnergyTracks = std::accumulate(m_pionParticles->begin(), m_pionParticles->end(), 0.0,
316 [](
const double & visibleEnergy,
const Particle & p) {
317 return visibleEnergy + p.getMomentumMagnitude();
320 const double visibleEnergyGammas = std::accumulate(m_gammaParticles->begin(), m_gammaParticles->end(), 0.0,
321 [](
const double & visibleEnergy,
const Particle & p) {
322 return visibleEnergy + p.getMomentumMagnitude();
325 calculationResult[
"VisibleEnergyLE"] = visibleEnergyTracks + visibleEnergyGammas;
328 const double eTotTracks = std::accumulate(m_pionParticles->begin(), m_pionParticles->end(), 0.0,
329 [](
const double & eTot,
const Particle & p) {
330 const ECLCluster* eclCluster = p.getECLCluster();
332 const double eclEnergy = eclCluster->getEnergy(
333 ECLCluster::EHypothesisBit::c_nPhotons);
334 if (eclEnergy > 0.1) {
335 return eTot + eclCluster->getEnergy(
336 ECLCluster::EHypothesisBit::c_nPhotons);
342 const double eTotGammas = std::accumulate(m_gammaParticles->begin(), m_gammaParticles->end(), 0.0,
343 [](
const double & eTot,
const Particle & p) {
344 return eTot + p.getEnergy();
346 double Etot = eTotTracks + eTotGammas;
347 calculationResult[
"EtotLE"] = Etot;
351 double numMaxLayerKLM = -1.;
352 double numSecMaxLayerKLM = -1.;
355 for (
const auto& klmCluster : klmClusters) {
356 double klmClusterLayer = klmCluster.getLayers();
357 if (numMaxLayerKLM < klmClusterLayer) {
358 numSecMaxLayerKLM = numMaxLayerKLM;
359 numMaxLayerKLM = klmClusterLayer;
360 }
else if (numSecMaxLayerKLM < klmClusterLayer)
361 numSecMaxLayerKLM = klmClusterLayer;
364 calculationResult[
"N1KLMLayer"] = numMaxLayerKLM;
365 calculationResult[
"N2KLMLayer"] = numSecMaxLayerKLM;
369 if (trackWithMaximumRho) charget1 = trackWithMaximumRho->getCharge();
371 if (trackWithSecondMaximumRho) charget2 = trackWithSecondMaximumRho->getCharge();
373 double Bhabha2Trk = 0.;
374 int ntrk_bha = m_pionParticles->getListSize();
375 double rp1ob = rhoOfTrackWithMaximumRho / BeamEnergyCMS();
376 double rp2ob = rhoOfTrackWithSecondMaximumRho / BeamEnergyCMS();
377 bool bhabha2trk_tag =
378 ntrk_bha >= 2 && maxAngleTTLE > 2.88 && nEidLE >= 1 && rp1ob > 0.35 && rp2ob > 0.35 && (Etot) > 4.0
379 && (abs(charget1) == 1 && abs(charget2) == 1 && (charget1 + charget2) == 0);
380 if (bhabha2trk_tag) Bhabha2Trk = 1;
381 calculationResult[
"Bhabha2Trk"] = Bhabha2Trk;
383 double Bhabha1Trk = 0.;
384 double rc1ob = rhoOfGammaWithMaximumRho / BeamEnergyCMS();
385 double rc2ob = rhoOfGammaWithSecondMaximumRho / BeamEnergyCMS();
386 bool bhabha1trk_tag = ntrk_bha == 1 && rp1ob > 0.35 && rc1ob > 0.35 && angleGTLE > 2.618;
387 if (bhabha1trk_tag) Bhabha1Trk = 1;
388 calculationResult[
"Bhabha1Trk"] = Bhabha1Trk;
391 bool gg_tag = ntrk_bha <= 1 && nEidLE == 0 && rc1ob > 0.35 && rc2ob > 0.2 && Etot > 4.0 && maxAngleGGLE > 2.618;
392 if (gg_tag) ggSel = 1;
393 calculationResult[
"GG"] = ggSel;
396 double BhabhaECL = 0.;
398 for (
int i = 0; i < eclClusters.getEntries() - 1; i++) {
404 double Eg1ob = V4g1.E() / (2 * BeamEnergyCMS());
405 for (
int j = i + 1; j < eclClusters.getEntries(); j++) {
410 double Eg2ob = V4g2.E() / (2 * BeamEnergyCMS());
413 double Thetag1 = V4g1.
Theta() * TMath::RadToDeg();
414 double Thetag2 = V4g2.Theta() * TMath::RadToDeg();
415 double deltphi = fabs(V3g1.
DeltaPhi(V3g2) * TMath::RadToDeg());
416 double Tsum = Thetag1 + Thetag2;
417 if ((deltphi > 165. && deltphi < 178.5) && (Eg1ob > 0.4 && Eg2ob > 0.4 && (Eg1ob > 0.45 || Eg2ob > 0.45)) && (Tsum > 178.
418 && Tsum < 182.)) BhabhaECL = 1;
421 calculationResult[
"BhabhaECL"] = BhabhaECL;
424 double BhabhaCDC = 0.;
427 const double lowdEdxEdge = 0.70, highdEdxEdge = 1.30;
428 const double lowEoPEdge = 0.70, highEoPEdge = 1.30;
430 if (m_pionParticles->getListSize() == 2) {
433 for (
unsigned int i = 0; i < m_pionParticles->getListSize() - 1; i++) {
435 Particle* part1 = m_pionParticles->getParticle(i);
436 if (!part1)
continue;
438 const auto chargep1 = part1->
getCharge();
439 if (abs(chargep1) != 1)
continue;
442 if (!eclTrack1)
continue;
447 if (energyOverMomentum1 <= lowEoPEdge || energyOverMomentum1 >= highEoPEdge)
continue;
450 if (!track1)
continue;
453 if (!trackFit1)
continue;
457 for (
unsigned int j = i + 1; j < m_pionParticles->getListSize(); j++) {
459 Particle* part2 = m_pionParticles->getParticle(j);
460 if (!part2)
continue;
462 const auto chargep2 = part2->
getCharge();
463 if (abs(chargep2) != 1 || (chargep1 + chargep2 != 0))
continue;
466 if (!eclTrack2)
continue;
471 if (energyOverMomentum2 <= lowEoPEdge || energyOverMomentum2 >= highEoPEdge)
continue;
474 if (!track2)
continue;
477 if (!trackFit2)
continue;
483 if (!dedxTrack1)
continue;
486 if (!dedxTrack2)
continue;
491 if ((p1_dedxnosat > lowdEdxEdge && p1_dedxnosat < highdEdxEdge) || (p2_dedxnosat > lowdEdxEdge
492 && p2_dedxnosat < highdEdxEdge)) radee = 1;
498 calculationResult[
"BhabhaCDC"] = BhabhaCDC;
499 calculationResult[
"Radee"] = radee;
502 double mumutight = 0.;
503 double eMumuTotGammas = 0.;
506 int nGammas = m_gammaParticles->getListSize();
508 for (
int t = 0; t < nGammas; t++) {
509 const Particle* part = m_gammaParticles->getParticle(t);
511 eMumuTotGammas += frame.getMomentum(part).E();
515 nTracks = tracks.getEntries();
520 if (m_pionParticles->getListSize() == 2) {
523 for (
unsigned int k = 0; k < m_pionParticles->getListSize() - 1; k++) {
525 Particle* part1 = m_pionParticles->getParticle(k);
526 if (!part1)
continue;
528 const auto chargep1 = part1->
getCharge();
529 if (abs(chargep1) != 1)
continue;
532 if (!eclTrack1)
continue;
536 if (!track1)
continue;
539 if (!trackFit1)
continue;
541 const ROOT::Math::PxPyPzEVector V4p1 = trackFit1->
get4Momentum();
544 const double p1MomLab = V4p1.P();
545 double highestP = p1MomLab;
549 if (p1Pid) p1hasKLMid = p1Pid->
isAvailable(Const::KLM);
550 const double p1isInCDC = Variable::inCDCAcceptance(part1);
551 const double p1clusPhi = Variable::eclClusterPhi(part1);
553 const double Pp1 = V3p1.
Mag();
554 const double Thetap1 = (V3p1).Theta() * TMath::RadToDeg();
555 const double Phip1 = (V3p1).Phi() * TMath::RadToDeg();
559 const bool goodTrk1 = enECLTrack1 > 0 && enECLTrack1 < 0.5 && p1CDChits > 0
560 && ((p1hasKLMid == 0 && enECLTrack1 < 0.25 && p1MomLab < 2.0) || p1hasKLMid == 1) && p1isInCDC == 1;
563 for (
unsigned int l = k + 1; l < m_pionParticles->getListSize(); l++) {
565 Particle* part2 = m_pionParticles->getParticle(l);
566 if (!part2)
continue;
568 const auto chargep2 = part2->
getCharge();
569 if (abs(chargep2) != 1 || (chargep1 + chargep2 != 0))
continue;
572 if (!eclTrack2)
continue;
576 if (!track2)
continue;
579 if (!trackFit2)
continue;
581 const ROOT::Math::PxPyPzEVector V4p2 = trackFit2->
get4Momentum();
584 const double p2MomLab = V4p2.P();
585 double lowestP = p2MomLab;
589 if (p2Pid) p2hasKLMid = p2Pid->
isAvailable(Const::KLM);
590 const double p2isInCDC = Variable::inCDCAcceptance(part2);
591 const double p2clusPhi = Variable::eclClusterPhi(part2);
593 const double Pp2 = V3p2.
Mag();
594 const double Thetap2 = (V3p2).Theta() * TMath::RadToDeg();
595 const double Phip2 = (V3p2).Phi() * TMath::RadToDeg();
597 const double acopPhi = fabs(180 - fabs(Phip1 - Phip2));
598 const double acopTheta = fabs(fabs(Thetap1 + Thetap2) - 180);
602 const bool goodTrk2 = enECLTrack2 > 0 && enECLTrack2 < 0.5 && p2CDChits > 0
603 && ((p2hasKLMid == 0 && enECLTrack2 < 0.25 && p2MomLab < 2.0) || p2hasKLMid == 1) && p2isInCDC == 1;
605 double eTotMumuTracks = enECLTrack1 + enECLTrack2;
606 double EMumutot = eTotMumuTracks + eMumuTotGammas;
608 bool mumutight_tag = enECLTrack1 < 0.5 && enECLTrack2 < 0.5 && EMumutot < 2 && acopPhi < 10 && acopTheta < 10 && nTracks == 2
609 && Pp1 > 0.5 && Pp2 > 0.5;
611 if (mumutight_tag) mumutight = 1;
613 if (p1MomLab < p2MomLab) {
618 double diffPhi = p1clusPhi - p2clusPhi;
619 if (fabs(diffPhi) > M_PI) {
620 if (diffPhi > M_PI) {
621 diffPhi = diffPhi - 2 * M_PI;
623 diffPhi = 2 * M_PI + diffPhi;
627 const double recoilP = fr.getMomentum(pIN - V4p1 - V4p2).P();
629 const bool radmumu_tag = nTracks < 4 && goodTrk1 == 1 && goodTrk2 == 1 && highestP > 1 && lowestP < 3 && (p1hasKLMid == 1
630 || p2hasKLMid == 1) && abs(diffPhi) >= 0.5 * M_PI && recoilP > 0.1 && (enECLTrack1 <= 0.25 || enECLTrack2 <= 0.25);
632 if (radmumu_tag) radmumu = 1;
638 calculationResult[
"MumuTight"] = mumutight;
639 calculationResult[
"Radmumu"] = radmumu;
642 double EsumPiHad = 0;
644 int nHadTracks = m_pionHadParticles->getListSize();
648 std::vector<ROOT::Math::XYZVector> m_pionHadv3;
650 for (
int nPiHad = 0; nPiHad < nHadTracks; nPiHad++) {
651 Particle* parPiHad = m_pionHadParticles->getParticle(nPiHad);
654 EsumPiHad += V4PiHad.E();
655 PzPiHad += V4PiHad.Pz();
658 double visibleEnergyCMSnorm = (EsumPiHad + EsumGamma) / (BeamEnergyCMS() * 2.0);
659 double EsumCMSnorm = eneclClusters / (BeamEnergyCMS() * 2.0);
660 double PzTotCMSnorm = (PzPiHad + PzGamma) / (BeamEnergyCMS() * 2.0);
662 bool hadronb_tag = nHadTracks >= 3 && visibleEnergyCMSnorm > 0.2 && abs(PzTotCMSnorm) < 0.5 && neclClusters > 1
663 && EsumCMSnorm > 0.1 && EsumCMSnorm < 0.8;
668 fw.calculateBasicMoments();
669 double R2 = fw.getR(2);
670 if (R2 < 0.4) hadronb1 = 1;
671 if (hadronb1 && nHadTracks >= 5) hadronb2 = 1;
674 calculationResult[
"HadronB"] = hadronb;
675 calculationResult[
"HadronB1"] = hadronb1;
676 calculationResult[
"HadronB2"] = hadronb2;
681 const double KsMassLow = 0.468;
682 const double KsMassHigh = 0.528;
684 if (m_KsParticles.isValid()) {
685 for (
unsigned int i = 0; i < m_KsParticles->getListSize(); i++) {
686 const Particle* mergeKsCand = m_KsParticles->getParticle(i);
687 const double isKsCandGood = Variable::goodBelleKshort(mergeKsCand);
688 const double KsCandMass = mergeKsCand->
getMass();
689 if (KsCandMass > KsMassLow && KsCandMass < KsMassHigh && isKsCandGood == 1.) nKshort++;
693 if (nKshort != 0) Kshort = 1;
695 calculationResult[
"Kshort"] = Kshort;
701 const double visibleEnergyCMS = visibleEnergyCMSnorm * BeamEnergyCMS() * 2.0;
702 const unsigned int n_particles = m_pionHadParticles->getListSize();
704 if (n_particles >= 2) {
705 for (
unsigned int i = 0; i < n_particles - 1; i++) {
706 Particle* par1 = m_pionHadParticles->getParticle(i);
707 for (
unsigned int j = i + 1; j < n_particles; j++) {
708 Particle* par2 = m_pionHadParticles->getParticle(j);
710 const ROOT::Math::PxPyPzEVector V4p1 = par1->
get4Vector();
711 const ROOT::Math::PxPyPzEVector V4p2 = par2->
get4Vector();
712 const double opAng = V4p1.Theta() + V4p2.Theta();
713 const ROOT::Math::PxPyPzEVector V4pSum = V4p1 + V4p2;
715 const double ptCMS = V4pSumCMS.Pt();
716 const double pzCMS = V4pSumCMS.Pz();
717 const double mSum = V4pSum.M();
719 const bool fourLepCand = chSum == 0 && (V4p1.P() > 0.4 && V4p2.P() > 0.4) && cos(opAng) > -0.997 && ptCMS < 0.15 && abs(pzCMS) < 2.5
722 if (fourLepCand) nFourLep++;
727 if (nFourLep != 0 && visibleEnergyCMS < 6) fourLep = 1;
729 calculationResult[
"FourLep"] = fourLep;
732 unsigned int nLambda = 0;
734 if (m_LambdaParticles.isValid()) {
735 for (
unsigned int i = 0; i < m_LambdaParticles->getListSize(); i++) {
736 const Particle* mergeLambdaCand = m_LambdaParticles->getParticle(i);
737 const double flightDist = Variable::flightDistance(mergeLambdaCand);
738 const double flightDistErr = Variable::flightDistanceErr(mergeLambdaCand);
739 const double flightSign = flightDist / flightDistErr;
742 const double protMom = protCand->
getP();
743 const double pionMom = pionCand->
getP();
744 const double asymPDaughters = (protMom - pionMom) / (protMom + pionMom);
745 if (flightSign > 10 && asymPDaughters > 0.41) nLambda++;
750 calculationResult[
"Lambda"] = 1;
752 calculationResult[
"Lambda"] = 0;
756 unsigned int nDstp1 = 0;
757 unsigned int nDstp2 = 0;
758 unsigned int nDstp3 = 0;
759 unsigned int nDstp4 = 0;
761 if (m_DstParticles.isValid() && (ntrk_bha >= 3 && Bhabha2Trk == 0)) {
762 for (
unsigned int i = 0; i < m_DstParticles->getListSize(); i++) {
763 const Particle* allDstCand = m_DstParticles->getParticle(i);
764 const double dstDecID = allDstCand->
getExtraInfo(
"decayModeID");
765 if (dstDecID == 1.) nDstp1++;
766 if (dstDecID == 2.) nDstp2++;
767 if (dstDecID == 3.) nDstp3++;
768 if (dstDecID == 4.) nDstp4++;
774 calculationResult[
"Dstp1"] = 1;
776 calculationResult[
"Dstp1"] = 0;
780 calculationResult[
"Dstp2"] = 1;
782 calculationResult[
"Dstp2"] = 0;
786 calculationResult[
"Dstp3"] = 1;
788 calculationResult[
"Dstp3"] = 0;
792 calculationResult[
"Dstp4"] = 1;
794 calculationResult[
"Dstp4"] = 0;
798 calculationResult[
"nTracksOffIP"] = m_offIpParticles->getListSize();
801 calculationResult[
"NeuroTRG"] = 0;
802 calculationResult[
"GammaGammaFilter"] = 0;
806 const std::map<std::string, int>& nonPrescaledResults = filter_result->getNonPrescaledResults();
807 if (nonPrescaledResults.find(m_filterL1TrgNN) != nonPrescaledResults.end()) {
809 if (hasNN) calculationResult[
"NeuroTRG"] = 1;
811 const bool ggEndcap = (filter_result->getNonPrescaledResult(
"software_trigger_cut&filter&ggEndcapLoose") ==
813 const bool ggBarrel = (filter_result->getNonPrescaledResult(
"software_trigger_cut&filter&ggBarrelLoose") ==
815 if (ggEndcap || ggBarrel) calculationResult[
"GammaGammaFilter"] = 1;
820 double mumuHighMass = 0.;
822 if (trackWithMaximumRho && trackWithSecondMaximumRho) {
824 double eclE1 = 0., eclE2 = 0.;
826 const auto charge1 = trackWithMaximumRho->getCharge();
827 const auto charge2 = trackWithSecondMaximumRho->getCharge();
828 const auto chSum = charge1 + charge2;
830 const ECLCluster* eclTrack1 = trackWithMaximumRho->getECLCluster();
836 const ECLCluster* eclTrack2 = trackWithSecondMaximumRho->getECLCluster();
844 const ROOT::Math::PxPyPzEVector V4pSum = V4p1 + V4p2;
845 const double mSum = V4pSum.M();
847 const double thetaSumCMS = (V4p1.Theta() + V4p2.Theta()) * TMath::RadToDeg();
848 const double phi1CMS = V4p1.Phi() * TMath::RadToDeg();
849 const double phi2CMS = V4p2.Phi() * TMath::RadToDeg();
851 double diffPhi = phi1CMS - phi2CMS;
852 if (fabs(diffPhi) > 180) {
854 diffPhi = diffPhi - 2 * 180;
856 diffPhi = 2 * 180 + diffPhi;
859 const double delThetaCMS = fabs(fabs(thetaSumCMS) - 180);
860 const double delPhiCMS = fabs(180 - fabs(diffPhi));
862 const bool mumuHighMassCand = chSum == 0 && (mSum > 8. && mSum < 12.) && hasClus > 0 && eclE1 <= 1
863 && eclE2 <= 1 && delThetaCMS < 10 && delPhiCMS < 10;
865 if (mumuHighMassCand) mumuHighMass = 1;
869 calculationResult[
"MumuHighM"] = mumuHighMass;
872 calculationResult[
"Bp"] = 0;
873 calculationResult[
"Bz"] = 0;
875 if (m_BpParticles.isValid() && (ntrk_bha >= 3 && Bhabha2Trk == 0)) {
876 calculationResult[
"Bp"] = m_BpParticles->getListSize() >= 1;
879 if (m_BzParticles.isValid() && (ntrk_bha >= 3 && Bhabha2Trk == 0)) {
880 calculationResult[
"Bz"] = m_BzParticles->getListSize() >= 1;
DataType Theta() const
The polar angle.
DataType DeltaPhi(const B2Vector3< DataType > &v) const
returns phi in the interval [-PI,PI)
DataType Mag() const
The magnitude (rho in spherical coordinate system).
DataType Angle(const B2Vector3< DataType > &q) const
The angle w.r.t.
Debug output for CDCDedxPID module.
double getDedxNoSat() const
Get dE/dx truncated mean without the saturation correction for this track.
Class to provide momentum-related information from ECLClusters.
const ROOT::Math::PxPyPzEVector Get4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns four momentum vector.
static const ChargedStable pion
charged pion particle
bool hasHypothesis(EHypothesisBit bitmask) const
Return if specific hypothesis bit is set.
double getEnergy(EHypothesisBit hypothesis) const
Return Energy (GeV).
@ c_nPhotons
CR is split into n photons (N1)
Class to calculate the Fox-Wolfram moments up to order 8.
unsigned short getNHits() const
Get the total Number of CDC hits in the fit.
Class to collect log likelihoods from TOP, ARICH, dEdx, ECL and KLM aimed for output to mdst includes...
bool isAvailable(Const::PIDDetectorSet set=Const::PIDDetectorSet::set()) const
Check whether PID information is available for at least one of the detectors in a given set.
Class to store reconstructed particles.
const Track * getTrack() const
Returns the pointer to the Track object that was used to create this Particle (ParticleType == c_Trac...
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
const PIDLikelihood * getPIDLikelihood() const
Returns the pointer to the PIDLikelihood object that is related to the Track, which was used to creat...
double getCharge(void) const
Returns particle charge.
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
double getMomentumMagnitude() const
Returns momentum magnitude.
double getP() const
Returns momentum magnitude (same as getMomentumMagnitude but with shorter name)
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
double getExtraInfo(const std::string &name) const
Return given value if set.
double getMass() const
Returns invariant mass (= nominal for FS particles)
static const ReferenceFrame & GetCurrent()
Get current rest frame.
StoreObjPtr< ParticleList > m_pionParticles
Internal storage of the tracks as particles.
StoreObjPtr< ParticleList > m_gammaParticles
Internal storage of the ECL clusters as particles.
StoreObjPtr< ParticleList > m_BzParticles
Internal storage of the B0's.
StoreObjPtr< ParticleList > m_LambdaParticles
Internal storage of the Lambda0's.
StoreObjPtr< ParticleList > m_pionHadParticles
Internal storage of the tracks as particles (definition for hadronb).
void requireStoreArrays() override
Require the particle list. We do not need more here.
void doCalculation(SoftwareTriggerObject &calculationResult) override
Actually write out the variables into the map.
SkimSampleCalculator()
Set the default names for the store object particle lists.
StoreObjPtr< ParticleList > m_KsParticles
Internal storage of the K_S0's.
StoreObjPtr< ParticleList > m_DstParticles
Internal storage of the D*'s.
StoreObjPtr< ParticleList > m_pionTauParticles
Internal storage of the tracks as particles (definition for tau skims).
StoreObjPtr< ParticleList > m_BpParticles
Internal storage of the B+'s.
StoreObjPtr< ParticleList > m_offIpParticles
Internal storage of the tracks for alignment calibration.
Accessor to arrays stored in the data store.
bool isValid() const
Check wether the array was registered.
int getEntries() const
Get the number of objects in the array.
iterator end()
Return iterator to last entry +1.
iterator begin()
Return iterator to first entry.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
Values of the result of a track fit with a given particle hypothesis.
ROOT::Math::PxPyPzEVector get4Momentum() const
Getter for the 4Momentum at the closest approach of the track in the r/phi projection.
HitPatternCDC getHitPatternCDC() const
Getter for the hit pattern in the CDC;.
Class that bundles various TrackFitResults.
@ c_accept
Accept this event.
Abstract base class for different kinds of events.