From 1a6ca932003ebbc65b2485d05b9901c0447e1ac9 Mon Sep 17 00:00:00 2001 From: Fabrizio Grosa Date: Wed, 14 Jun 2023 21:39:19 +0200 Subject: [PATCH 1/2] EventFiltering: Add more channels to D+V0 triggers --- EventFiltering/PWGHF/HFFilter.cxx | 188 +++++++++++++++++------- EventFiltering/PWGHF/HFFilterHelpers.h | 190 +++++++++++++++---------- EventFiltering/PWGHF/HFFilterQC.cxx | 4 +- 3 files changed, 251 insertions(+), 131 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 7d8ae9c164a..1d215b10f66 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -78,6 +78,8 @@ struct HfFilter { // Main struct for HF triggers Configurable> cutsTrackBeauty3Prong{"cutsTrackBeauty3Prong", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for 3-prong beauty candidates"}; Configurable> cutsTrackBeauty4Prong{"cutsTrackBeauty4Prong", {hf_cuts_single_track::cutsTrack[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for 4-prong beauty candidates"}; std::array, 2> cutsSingleTrackBeauty; + static constexpr double cutsTrackDummy[hf_cuts_single_track::nBinsPtTrack][hf_cuts_single_track::nCutVarsTrack] = {{0., 10.}, {0., 10.}, {0., 10.}, {0., 10.}, {0., 10.}, {0., 10.}}; + LabeledArray cutsSingleTrackDummy{cutsTrackDummy[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}; // parameters for femto triggers Configurable femtoMaxRelativeMomentum{"femtoMaxRelativeMomentum", 2., "Maximal allowed value for relative momentum between charm-proton pairs in GeV/c"}; @@ -85,8 +87,12 @@ struct HfFilter { // Main struct for HF triggers Configurable femtoProtonOnlyTOF{"femtoProtonOnlyTOF", false, "Use only TOF information for proton identification if true"}; Configurable femtoMaxNsigmaProton{"femtoMaxNsigmaProton", 3., "Maximum value for PID proton Nsigma for femto triggers"}; - // parameters for photon triggers - Configurable photonMinCosPA{"photonMinCosPA", 0.85, "Minimal required cosine of pointing angle for photons"}; + // parameters for V0 triggers + Configurable minCosPaGamma{"minCosPaGamma", 0.85, "Minimal required cosine of pointing angle for photons"}; + Configurable minCosPaV0{"minCosPaV0", 0.95, "Minimal required cosine of pointing angle for K0S and Lambdas"}; + Configurable maxMassDstarToGamma{"maxMassDstarToGamma", 3., "Maximum invariant mass for D* -> D gamma"}; + Configurable maxMassDs12{"maxMassDs12", 2.85, "Maximum invariant mass for Ds1+ and Ds2*+"}; + Configurable maxMassXicStar{"maxMassXicStar", 3.3, "Maximum invariant mass for Xic(3055) and Xic(3080)"}; // parameters for ML application with ONNX Configurable applyML{"applyML", false, "Flag to enable or disable ML application"}; @@ -142,14 +148,13 @@ struct HfFilter { // Main struct for HF triggers std::array, kNCharmParticles> hCharmHighPt{}; std::array, kNCharmParticles> hCharmProtonKstarDistr{}; std::array, kNBeautyParticles> hMassVsPtB{}; - std::array, kNCharmParticles + 3> hMassVsPtC{}; // +3 for resonances (D*+, D*0, Ds*+) - std::array, kNCharmParticles> hMassVsPhiC{}; + std::array, kNCharmParticles + 6> hMassVsPtC{}; // +6 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic*) std::shared_ptr hProtonTPCPID, hProtonTOFPID; std::array, kNCharmParticles> hBDTScoreBkg{}; std::array, kNCharmParticles> hBDTScorePrompt{}; std::array, kNCharmParticles> hBDTScoreNonPrompt{}; - std::shared_ptr hGammaSelected, hGammaEtaBefore, hGammaEtaAfter; - std::shared_ptr hGammaArmPodBefore, hGammaArmPodAfter; + std::array, kNV0> hArmPod{}; + std::shared_ptr hV0Selected; // Histograms of TPC calibration for pion and proton std::array hMapPion = {nullptr, nullptr}; @@ -177,7 +182,6 @@ struct HfFilter { // Main struct for HF triggers cutsSingleTrackBeauty = {cutsTrackBeauty3Prong, cutsTrackBeauty4Prong}; hProcessedEvents = registry.add("fProcessedEvents", "HF - event filtered;;counts", HistType::kTH1F, {{kNtriggersHF + 2, -0.5, kNtriggersHF + 1.5}}); - std::array eventTitles = {"all", "rejected", "w/ high-#it{p}_{T} 2p charm", "w/ high-#it{p}_{T} 3p charm", "w/ 3p beauty", "w/ 4p beauty", "w/ 2p femto", "w/ 3p femto", "w/ 2p double charm", "w/ 3p double charm", "w/ 2p and 3p double charm", "w/ 2p soft gamma", "w/ 3p soft gamma"}; for (auto iBin = 0; iBin < kNtriggersHF + 2; ++iBin) { hProcessedEvents->GetXaxis()->SetBinLabel(iBin + 1, eventTitles[iBin].data()); } @@ -194,24 +198,35 @@ struct HfFilter { // Main struct for HF triggers hBDTScorePrompt[iCharmPart] = registry.add(Form("f%sBDTScorePromptDistr", charmParticleNames[iCharmPart].data()), Form("BDT prompt score distribution for %s;BDT prompt score;counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {bdtAxis}); hBDTScoreNonPrompt[iCharmPart] = registry.add(Form("f%sBDTScoreNonPromptDistr", charmParticleNames[iCharmPart].data()), Form("BDT nonprompt score distribution for %s;BDT nonprompt score;counts", charmParticleNames[iCharmPart].data()), HistType::kTH1F, {bdtAxis}); } - if (activateQA > 2) { - hMassVsPhiC[iCharmPart] = registry.add(Form("fMassVsPhi%s", charmParticleNames[iCharmPart].data()), Form("#it{M} vs. #varphi distribution of triggered %s candidates;#varphi;#it{M} (GeV/#it{c}^{2});counts", charmParticleNames[iCharmPart].data()), HistType::kTH2F, {phiAxis, massAxisC[iCharmPart]}); - } } hMassVsPtC[kNCharmParticles] = registry.add("fMassVsPtDStarPlus", "#it{M} vs. #it{p}_{T} distribution of triggered DStarPlus candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles]}); hMassVsPtC[kNCharmParticles + 1] = registry.add("fMassVsPtDStarZero", "#it{M} vs. #it{p}_{T} distribution of triggered DStarZero candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles + 1]}); hMassVsPtC[kNCharmParticles + 2] = registry.add("fMassVsPtDStarS", "#it{M} vs. #it{p}_{T} distribution of triggered DStarS candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles + 2]}); + hMassVsPtC[kNCharmParticles + 3] = registry.add("fMassVsPtDs1Plus", "#it{M} vs. #it{p}_{T} distribution of triggered Ds1Plus candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles + 3]}); + hMassVsPtC[kNCharmParticles + 4] = registry.add("fMassVsPtDs2StarPlus", "#it{M} vs. #it{p}_{T} distribution of triggered Ds2StarPlus candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles + 4]}); + hMassVsPtC[kNCharmParticles + 5] = registry.add("fMassVsPtXicStar", "#it{M} vs. #it{p}_{T} distribution of triggered XicStar candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2F, {ptAxis, massAxisC[kNCharmParticles + 5]}); for (int iBeautyPart{0}; iBeautyPart < kNBeautyParticles; ++iBeautyPart) { hMassVsPtB[iBeautyPart] = registry.add(Form("fMassVsPt%s", beautyParticleNames[iBeautyPart].data()), Form("#it{M} vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", beautyParticleNames[iBeautyPart].data()), HistType::kTH2F, {ptAxis, massAxisB[iBeautyPart]}); } + for (int iV0{kPhoton}; iV0 < kNV0; ++iV0) { + hArmPod[iV0] = registry.add(Form("fArmPod%s", v0Names[iV0].data()), "Armenteros Podolanski plot for V0s, selections;#it{#alpha};#it{q}_{T} (GeV/#it{c})", HistType::kTH2F, {alphaAxis, qtAxis}); + } + if (activateQA > 1) { hProtonTPCPID = registry.add("fProtonTPCPID", "#it{N}_{#sigma}^{TPC} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}", HistType::kTH2F, {pAxis, nSigmaAxis}); hProtonTOFPID = registry.add("fProtonTOFPID", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2F, {pAxis, nSigmaAxis}); - hGammaSelected = registry.add("fGammaSelected", "Selections for converted gamma;;counts", HistType::kTH1F, {{7, -0.5, 6.5}}); - hGammaEtaBefore = registry.add("fGammaEtaBefore", "#eta of converted gamma before selections;;counts", HistType::kTH1F, {etaAxis}); - hGammaEtaAfter = registry.add("hGammaEtaAfter", "#eta of converted gamma after selections;;counts", HistType::kTH1F, {etaAxis}); - hGammaArmPodBefore = registry.add("fGammaAPbefore", "Armenteros Podolanski plot for converted gamma, before selections;#it{#alpha};#it{q}_{T} (GeV/#it{c})", HistType::kTH2F, {alphaAxis, qtAxis}); - hGammaArmPodAfter = registry.add("fGammaAPafter", "Armenteros Podolanski plot for converted gamma, after selections;#it{#alpha};#it{q}_{T} (GeV/#it{c})", HistType::kTH2F, {alphaAxis, qtAxis}); + hV0Selected = registry.add("fV0Selected", "Selections for V0s;;counts", HistType::kTH2F, {{7, -0.5, 6.5}, {kNV0, -0.5, kNV0 - 0.5}}); + + for (int iV0{kPhoton}; iV0 < kNV0; ++iV0) { + hV0Selected->GetYaxis()->SetBinLabel(iV0 + 1, v0Labels[iV0].data()); + } + hV0Selected->GetXaxis()->SetBinLabel(1, "analysed"); + hV0Selected->GetXaxis()->SetBinLabel(2, "rej. |#eta|"); + hV0Selected->GetXaxis()->SetBinLabel(3, "rej. radius"); + hV0Selected->GetXaxis()->SetBinLabel(4, "rej. cos(#theta_{P})"); + hV0Selected->GetXaxis()->SetBinLabel(5, "rej. AP"); + hV0Selected->GetXaxis()->SetBinLabel(6, "rej. pair cut"); + hV0Selected->GetXaxis()->SetBinLabel(7, "selected"); } } @@ -405,7 +420,7 @@ struct HfFilter { // Main struct for HF triggers optimisationTreeCharm(thisCollId, pdg::Code::kD0, pt2Prong, scoresToFill[0], scoresToFill[1], scoresToFill[2]); } - auto selD0 = isSelectedD0InMassRange(pVecPos, pVecNeg, pt2Prong, phi2Prong, preselD0, deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kD0], hMassVsPhiC[kD0]); + auto selD0 = isSelectedD0InMassRange(pVecPos, pVecNeg, pt2Prong, phi2Prong, preselD0, deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kD0]); if (pt2Prong >= pTThreshold2Prong) { keepEvent[kHighPt2P] = true; @@ -436,7 +451,7 @@ struct HfFilter { // Main struct for HF triggers } if (!keepEvent[kBeauty3P] && isBeautyTagged) { - int isTrackSelected = isSelectedTrackForBeauty(trackParThird, dcaThird, pTMinSoftPion, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty3P - 2]); + int isTrackSelected = isSelectedTrackForSoftPionOrBeauty(trackParThird, dcaThird, pTMinSoftPion, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty3P - 2]); if (isTrackSelected && ((TESTBIT(selD0, 0) && track.sign() < 0) || (TESTBIT(selD0, 1) && track.sign() > 0))) { auto massCand = RecoDecay::m(std::array{pVec2Prong, pVecThird}, std::array{massD0, massPi}); auto pVecBeauty3Prong = RecoDecay::pVec(pVec2Prong, pVecThird); @@ -467,8 +482,8 @@ struct HfFilter { // Main struct for HF triggers getPxPyPz(trackParFourth, pVecFourth); } - if (track.sign() * trackB.sign() < 0 && isSelectedTrackForBeauty(trackParFourth, dcaFourth, pTMinSoftPion, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty3P - 2]) == kRegular) { - auto massCandB0 = RecoDecay::m(std::array{pVec2Prong, pVecThird, pVecFourth}, std::array{massD0, massPi, massPi}); + if (track.sign() * trackB.sign() < 0 && isSelectedTrackForSoftPionOrBeauty(trackParFourth, dcaFourth, pTMinSoftPion, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty3P - 2]) == kRegular) { + auto massCandB0 = RecoDecay::m(std::array{pVecBeauty3Prong, pVecFourth}, std::array{massDStar, massPi}); if (std::abs(massCandB0 - massB0) <= deltaMassB0) { keepEvent[kBeauty3P] = true; // fill optimisation tree for D0 @@ -508,20 +523,61 @@ struct HfFilter { // Main struct for HF triggers // 2-prong with Gamma (conversion photon) auto v0sThisCollision = theV0s.sliceBy(v0sPerCollision, thisCollId); - for (auto& gamma : v0sThisCollision) { - if (!keepEvent[kGammaCharm2P] && (isCharmTagged || isBeautyTagged) && (TESTBIT(selD0, 0) || (TESTBIT(selD0, 1)))) { - float V0CosinePA = gamma.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); - bool isGamma = isSelectedGamma(gamma, photonMinCosPA, V0CosinePA, activateQA, hGammaSelected, hGammaEtaBefore, hGammaEtaAfter, hGammaArmPodBefore, hGammaArmPodAfter); - if (isGamma) { - std::array gammaVec = {gamma.px(), gamma.py(), gamma.pz()}; - auto massGammaCharm = RecoDecay::m(std::array{pVec2Prong, gammaVec}, std::array{massD0, massGamma}); - if (massGammaCharm < 3.0) { // remove candidates with invariant mass above 3 GeV - if (activateQA) { - auto pVecReso2Prong = RecoDecay::pVec(pVec2Prong, gammaVec); - auto ptCand = RecoDecay::pt(pVecReso2Prong); - hMassVsPtC[kNCharmParticles + 1]->Fill(ptCand, massGammaCharm); + for (auto& v0 : v0sThisCollision) { + if (!keepEvent[kV0Charm2P] && (isCharmTagged || isBeautyTagged) && (TESTBIT(selD0, 0) || (TESTBIT(selD0, 1)))) { + float v0CosinePa = v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + auto selV0 = isSelectedV0(v0, minCosPaGamma, minCosPaV0, v0CosinePa, activateQA, hV0Selected, hArmPod); + if(selV0) { + std::array pVecV0 = {v0.px(), v0.py(), v0.pz()}; + if (TESTBIT(selV0, kPhoton)) { + auto massD0Gamma = RecoDecay::m(std::array{pVec2Prong, pVecV0}, std::array{massD0, massGamma}); + if (massD0Gamma < maxMassDstarToGamma) { + if (activateQA) { + auto pVecReso2Prong = RecoDecay::pVec(pVec2Prong, pVecV0); + auto ptCand = RecoDecay::pt(pVecReso2Prong); + hMassVsPtC[kNCharmParticles + 1]->Fill(ptCand, massD0Gamma); + } + keepEvent[kV0Charm2P] = true; + } + } + if (!keepEvent[kV0Charm2P] && TESTBIT(selV0, kK0S)) { + + // we first look for a D*+ + for (const auto& trackBachelorId : trackIdsThisCollision) { // start loop over tracks + auto trackBachelor = trackBachelorId.track_as(); + if (trackBachelor.globalIndex() == trackPos.globalIndex() || trackBachelor.globalIndex() == trackNeg.globalIndex()) { + continue; + } + + auto trackParBachelor = getTrackPar(trackBachelor); + o2::gpu::gpustd::array dcaBachelor{trackBachelor.dcaXY(), trackBachelor.dcaZ()}; + std::array pVecBachelor = {trackBachelor.px(), trackBachelor.py(), trackBachelor.pz()}; + if (trackBachelor.collisionId() != thisCollId) { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelor, 2.f, noMatCorr, &dcaBachelor); + getPxPyPz(trackParBachelor, pVecBachelor); + } + + int isTrackSelected = isSelectedTrackForSoftPionOrBeauty(trackParBachelor, dcaBachelor, pTMinSoftPion, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackDummy); + if (isTrackSelected && ((TESTBIT(selD0, 0) && trackBachelor.sign() < 0) || (TESTBIT(selD0, 1) && trackBachelor.sign() > 0))) { + auto massDStarCand = RecoDecay::m(std::array{pVec2Prong, pVecBachelor}, std::array{massD0, massPi}); + auto pVecDStarCand = RecoDecay::pVec(pVec2Prong, pVecBachelor); + auto ptDStarCand = RecoDecay::pt(pVecDStarCand); + if (std::abs(massDStarCand - massDStar) <= deltaMassDStar) { + if (activateQA) { + hMassVsPtC[kNCharmParticles]->Fill(ptDStarCand, massDStarCand); + } + auto massDStarK0S = RecoDecay::m(std::array{pVecDStarCand, pVecV0}, std::array{massDStar, massK0S}); + if (massDStarK0S < maxMassDs12) { + if (activateQA) { + auto pVecReso2Prong = RecoDecay::pVec(pVecDStarCand, pVecV0); + auto ptCand = RecoDecay::pt(pVecReso2Prong); + hMassVsPtC[kNCharmParticles + 3]->Fill(ptCand, massDStarK0S); + } + keepEvent[kV0Charm2P] = true; + } + } + } } - keepEvent[kGammaCharm2P] = true; } } } @@ -646,25 +702,25 @@ struct HfFilter { // Main struct for HF triggers std::array is3ProngInMass{0}; if (is3Prong[0]) { - is3ProngInMass[0] = isSelectedDplusInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kDplus], hMassVsPhiC[kDplus]); + is3ProngInMass[0] = isSelectedDplusInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kDplus]); if (applyOptimisation) { optimisationTreeCharm(thisCollId, pdg::Code::kDPlus, pt3Prong, scoresToFill[0][0], scoresToFill[0][1], scoresToFill[0][2]); } } if (is3Prong[1]) { - is3ProngInMass[1] = isSelectedDsInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[1], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kDs], hMassVsPhiC[kDs]); + is3ProngInMass[1] = isSelectedDsInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[1], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kDs]); if (applyOptimisation) { optimisationTreeCharm(thisCollId, pdg::Code::kDS, pt3Prong, scoresToFill[1][0], scoresToFill[1][1], scoresToFill[1][2]); } } if (is3Prong[2]) { - is3ProngInMass[2] = isSelectedLcInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[2], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kLc], hMassVsPhiC[kLc]); + is3ProngInMass[2] = isSelectedLcInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[2], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kLc]); if (applyOptimisation) { optimisationTreeCharm(thisCollId, pdg::Code::kLambdaCPlus, pt3Prong, scoresToFill[2][0], scoresToFill[2][1], scoresToFill[2][2]); } } if (is3Prong[3]) { - is3ProngInMass[3] = isSelectedXicInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[3], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kXic], hMassVsPhiC[kXic]); + is3ProngInMass[3] = isSelectedXicInMassRange(pVecFirst, pVecThird, pVecSecond, pt3Prong, phi3Prong, is3Prong[3], deltaMassCharmHadronForBeauty, activateQA, hMassVsPtC[kXic]); if (applyOptimisation) { optimisationTreeCharm(thisCollId, pdg::Code::kXiCPlus, pt3Prong, scoresToFill[3][0], scoresToFill[3][1], scoresToFill[3][2]); } @@ -702,7 +758,7 @@ struct HfFilter { // Main struct for HF triggers float massCharmHypos[kNBeautyParticles - 2] = {massDPlus, massDs, massLc, massXic}; float massBeautyHypos[kNBeautyParticles - 2] = {massB0, massBs, massLb, massXib}; float deltaMassHypos[kNBeautyParticles - 2] = {deltaMassB0, deltaMassBs, deltaMassLb, deltaMassXib}; - if (track.sign() * sign3Prong < 0 && isSelectedTrackForBeauty(trackParFourth, dcaFourth, pTMinBeautyBachelor, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty4P - 2]) == kRegular) { + if (track.sign() * sign3Prong < 0 && isSelectedTrackForSoftPionOrBeauty(trackParFourth, dcaFourth, pTMinBeautyBachelor, pTMinBeautyBachelor, pTBinsTrack, cutsSingleTrackBeauty[kBeauty4P - 2]) == kRegular) { for (int iHypo{0}; iHypo < kNBeautyParticles - 2 && !keepEvent[kBeauty4P]; ++iHypo) { if (isBeautyTagged[iHypo] && (TESTBIT(is3ProngInMass[iHypo], 0) || TESTBIT(is3ProngInMass[iHypo], 1))) { auto massCandB = RecoDecay::m(std::array{pVec3Prong, pVecFourth}, std::array{massCharmHypos[iHypo], massPi}); @@ -742,22 +798,50 @@ struct HfFilter { // Main struct for HF triggers } // end loop over tracks - // 3-prong with Gamma (conversion photon) + // 3-prong with V0 (Ds gamma, D+ K0S, D+ Lambda) auto v0sThisCollision = theV0s.sliceBy(v0sPerCollision, thisCollId); - for (auto& gamma : v0sThisCollision) { - if (!keepEvent[kGammaCharm3P] && (isCharmTagged[kDs - 1] || isBeautyTagged[kDs - 1]) && (TESTBIT(is3ProngInMass[kDs - 1], 0) || TESTBIT(is3ProngInMass[kDs - 1], 1))) { - float V0CosinePA = gamma.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); - bool isGamma = isSelectedGamma(gamma, photonMinCosPA, V0CosinePA, activateQA, hGammaSelected, hGammaEtaBefore, hGammaEtaAfter, hGammaArmPodBefore, hGammaArmPodAfter); - if (isGamma) { - std::array gammaVec = {gamma.px(), gamma.py(), gamma.pz()}; - auto massGammaCharm = RecoDecay::m(std::array{pVec3Prong, gammaVec}, std::array{massDs, massGamma}); - if (massGammaCharm < 3.) { // remove candidates with invariant mass above some value (TODO: set me as a configurable) - if (activateQA) { - auto pVecReso3Prong = RecoDecay::pVec(pVec3Prong, gammaVec); - auto ptCand = RecoDecay::pt(pVecReso3Prong); - hMassVsPtC[kNCharmParticles + 2]->Fill(ptCand, massGammaCharm); + bool isGoodDs = (isCharmTagged[kDs - 1] || isBeautyTagged[kDs - 1]) && (TESTBIT(is3ProngInMass[kDs - 1], 0) || TESTBIT(is3ProngInMass[kDs - 1], 1)); + bool isGoodDPlus = (isCharmTagged[kDplus - 1] || isBeautyTagged[kDplus - 1]) && is3ProngInMass[kDplus - 1]; + for (auto& v0 : v0sThisCollision) { + if (!keepEvent[kV0Charm3P] && (isGoodDs || isGoodDPlus)) { + float v0CosinePa = v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + auto v0Sel = isSelectedV0(v0, minCosPaGamma, minCosPaV0, v0CosinePa, activateQA, hV0Selected, hArmPod); + if (v0Sel > 0) { + std::array pVecV0 = {v0.px(), v0.py(), v0.pz()}; + if (!keepEvent[kV0Charm3P] && isGoodDs && TESTBIT(v0Sel, kPhoton)) { + auto massDsGamma = RecoDecay::m(std::array{pVec3Prong, pVecV0}, std::array{massDs, massGamma}); + if (massDsGamma < maxMassDstarToGamma) { + if (activateQA) { + auto pVecReso3Prong = RecoDecay::pVec(pVec3Prong, pVecV0); + auto ptCand = RecoDecay::pt(pVecReso3Prong); + hMassVsPtC[kNCharmParticles + 2]->Fill(ptCand, massDsGamma); + } + keepEvent[kV0Charm3P] = true; + } + } + if (!keepEvent[kV0Charm3P] && isGoodDPlus) { + if (TESTBIT(v0Sel, kK0S)) { // Ds2* + auto massDPlusK0S = RecoDecay::m(std::array{pVec3Prong, pVecV0}, std::array{massDPlus, massK0S}); + if (massDPlusK0S < maxMassDs12) { + if (activateQA) { + auto pVecReso3Prong = RecoDecay::pVec(pVec3Prong, pVecV0); + auto ptCand = RecoDecay::pt(pVecReso3Prong); + hMassVsPtC[kNCharmParticles + 4]->Fill(ptCand, massDPlusK0S); + } + keepEvent[kV0Charm3P] = true; + } + } + if ((TESTBIT(v0Sel, kLambda) && sign3Prong > 0) || (TESTBIT(v0Sel, kAntiLambda) && sign3Prong < 0)) { // Xic(3055) and Xic(3080) + auto massDPlusLambda = RecoDecay::m(std::array{pVec3Prong, pVecV0}, std::array{massDPlus, massLambda}); + if (massDPlusLambda < maxMassXicStar) { + if (activateQA) { + auto pVecReso3Prong = RecoDecay::pVec(pVec3Prong, pVecV0); + auto ptCand = RecoDecay::pt(pVecReso3Prong); + hMassVsPtC[kNCharmParticles + 5]->Fill(ptCand, massDPlusLambda); + } + keepEvent[kV0Charm3P] = true; + } } - keepEvent[kGammaCharm3P] = true; } } } @@ -785,7 +869,7 @@ struct HfFilter { // Main struct for HF triggers keepEvent[kDoubleCharmMix] = true; } - tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kGammaCharm2P], keepEvent[kGammaCharm3P]); + tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kV0Charm2P], keepEvent[kV0Charm3P]); if (!std::accumulate(keepEvent, keepEvent + kNtriggersHF, 0)) { hProcessedEvents->Fill(1); diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 5dc2cc7060f..42684a9c49f 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -69,8 +69,8 @@ enum HfTriggers { kDoubleCharm2P, kDoubleCharm3P, kDoubleCharmMix, - kGammaCharm2P, - kGammaCharm3P, + kV0Charm2P, + kV0Charm3P, kNtriggersHF }; @@ -106,10 +106,21 @@ enum PIDSpecies { kPr }; -static const std::array HfTriggerNames{"highPt", "beauty", "femto", "doubleCharm", "softGamma"}; +enum V0Species { + kPhoton = 0, + kK0S, + kLambda, + kAntiLambda, + kNV0 +}; + static const std::array charmParticleNames{"D0", "Dplus", "Ds", "Lc", "Xic"}; static const std::array beautyParticleNames{"Bplus", "B0toDStar", "B0", "Bs", "Lb", "Xib"}; static const std::array pdgCodesCharm{421, 411, 431, 4122, 4232}; +static const std::array eventTitles = {"all", "rejected", "w/ high-#it{p}_{T} 2p charm", "w/ high-#it{p}_{T} 3p charm", "w/ 3p beauty", "w/ 4p beauty", "w/ 2p femto", "w/ 3p femto", "w/ 2p double charm", "w/ 3p double charm", "w/ 2p and 3p double charm", "w/ 2p soft gamma", "w/ 3p soft gamma"}; +static const std::array hfTriggerNames{"kHighPt2P", "kHighPt3P", "kBeauty3P", "kBeauty4P", "kFemto2P", "kFemto3P", "kDoubleCharm2P", "kDoubleCharm3P", "kDoubleCharmMix", "kV0Charm2P", "kV0Charm3P"}; +static const std::array v0Labels{"#gamma", "K_{S}^{0}", "#Lambda", "#bar{#Lambda}"}; +static const std::array v0Names{"Photon", "K0S", "Lambda", "AntiLambda"}; static const std::tuple pdgCharmDaughters{ std::array{-321, 211}, // D0 @@ -134,6 +145,8 @@ static const float massBs = RecoDecay::getMassPDG(531); static const float massLb = RecoDecay::getMassPDG(5122); static const float massXib = RecoDecay::getMassPDG(5232); static const float massGamma = RecoDecay::getMassPDG(22); +static const float massK0S = RecoDecay::getMassPDG(310); +static const float massLambda = RecoDecay::getMassPDG(3122); static const AxisSpec ptAxis{50, 0.f, 50.f}; static const AxisSpec pAxis{50, 0.f, 10.f}; @@ -144,7 +157,7 @@ static const AxisSpec alphaAxis{100, -1.f, 1.f}; static const AxisSpec qtAxis{100, 0.f, 0.25f}; static const AxisSpec bdtAxis{100, 0.f, 1.f}; static const AxisSpec phiAxis{36, 0., TwoPI}; -static const std::array massAxisC = {AxisSpec{100, 1.65f, 2.05f}, AxisSpec{100, 1.65f, 2.05f}, AxisSpec{100, 1.75f, 2.15f}, AxisSpec{100, 2.05f, 2.45f}, AxisSpec{100, 2.25f, 2.65f}, AxisSpec{100, 2.00f, 2.04f}, AxisSpec{100, 1.98f, 2.08f}, AxisSpec{100, 2.08f, 2.18f}}; +static const std::array massAxisC = {AxisSpec{100, 1.65f, 2.05f}, AxisSpec{100, 1.65f, 2.05f}, AxisSpec{100, 1.75f, 2.15f}, AxisSpec{100, 2.05f, 2.45f}, AxisSpec{100, 2.25f, 2.65f}, AxisSpec{100, 2.00f, 2.04f}, AxisSpec{100, 1.98f, 2.08f}, AxisSpec{100, 2.08f, 2.18f}, AxisSpec{100, 2.35f, 2.85f}, AxisSpec{100, 2.35f, 2.85f}, AxisSpec{100, 2.80f, 3.30f}}; static const std::array massAxisB = {AxisSpec{240, 4.8f, 6.0f}, AxisSpec{240, 4.8f, 6.0f}, AxisSpec{240, 4.8f, 6.0f}, AxisSpec{240, 4.8f, 6.0f}, AxisSpec{240, 5.0f, 6.2f}, AxisSpec{240, 5.0f, 6.2f}}; /// load the TPC spline from the CCDB @@ -193,7 +206,7 @@ double getTPCSplineCalib(const T& track, const float mMassPar, const std::vector /// \param cutsSingleTrackBeauty cuts for all tracks /// \return 0 if track is rejected, 1 if track is soft pion, 2 if it is regular beauty template -int isSelectedTrackForBeauty(const T1& trackPar, const T2& dca, const float& pTMinSoftPion, const float& pTMinBeautyBachelor, const T3& pTBinsTrack, const T4& cutsSingleTrackBeauty) +int isSelectedTrackForSoftPionOrBeauty(const T1& trackPar, const T2& dca, const float& pTMinSoftPion, const float& pTMinBeautyBachelor, const T3& pTBinsTrack, const T4& cutsSingleTrackBeauty) { auto pT = trackPar.getPt(); auto pTBinTrack = findBin(pTBinsTrack, pT); @@ -201,7 +214,7 @@ int isSelectedTrackForBeauty(const T1& trackPar, const T2& dca, const float& pTM return kRejected; } - if (pT < pTMinSoftPion) { // soft pion should be more stringent than usual tracks + if (pT < pTMinSoftPion) { // soft pion should be less stringent than usual tracks return kRejected; } @@ -277,7 +290,7 @@ bool isSelectedProton4Femto(const T1& track, const T2& trackPar, const float& fe return false; } - if (activateQA > 1) { + if (activateQA) { hProtonTPCPID->Fill(track.p(), NSigmaTPC); hProtonTOFPID->Fill(track.p(), NSigmaTOF); } @@ -492,16 +505,13 @@ int8_t isDzeroPreselected(const T& trackPos, const T& trackNeg, const float& nsi /// \param hMassVsPt histo with invariant mass vs pt /// \return 1 for D0, 2 for D0bar, 3 for both template -int8_t isSelectedD0InMassRange(const T& pTrackPos, const T& pTrackNeg, const float& ptD, const float& phiD, int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt, H2 hMassVsPhi) +int8_t isSelectedD0InMassRange(const T& pTrackPos, const T& pTrackNeg, const float& ptD, const float& phiD, int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt) { int8_t retValue = 0; if (TESTBIT(isSelected, 0)) { auto invMassD0 = RecoDecay::m(std::array{pTrackPos, pTrackNeg}, std::array{massPi, massK}); if (activateQA) { hMassVsPt->Fill(ptD, invMassD0); - if (activateQA > 2) { - hMassVsPhi->Fill(phiD, invMassD0); - } } if (std::abs(invMassD0 - massD0) < deltaMassCharmHadronForBeauty || ptD > 10) { retValue |= BIT(0); @@ -511,9 +521,6 @@ int8_t isSelectedD0InMassRange(const T& pTrackPos, const T& pTrackNeg, const flo auto invMassD0bar = RecoDecay::m(std::array{pTrackPos, pTrackNeg}, std::array{massK, massPi}); if (activateQA) { hMassVsPt->Fill(ptD, invMassD0bar); - if (activateQA > 2) { - hMassVsPhi->Fill(phiD, invMassD0bar); - } } if (std::abs(invMassD0bar - massD0) < deltaMassCharmHadronForBeauty || ptD > 10) { retValue |= BIT(1); @@ -533,14 +540,11 @@ int8_t isSelectedD0InMassRange(const T& pTrackPos, const T& pTrackNeg, const flo /// \param hMassVsPt histo with invariant mass vs pt /// \return BIT(0) (==1) for D+, 0 otherwise template -int8_t isSelectedDplusInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptD, const float& phiD, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt, H2 hMassVsPhi) +int8_t isSelectedDplusInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptD, const float& phiD, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt) { auto invMassDplus = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackSameChargeSecond, pTrackOppositeCharge}, std::array{massPi, massPi, massK}); if (activateQA) { hMassVsPt->Fill(ptD, invMassDplus); - if (activateQA > 2) { - hMassVsPhi->Fill(phiD, invMassDplus); - } } if (std::abs(invMassDplus - massDPlus) > deltaMassCharmHadronForBeauty && ptD > 0) { @@ -561,16 +565,13 @@ int8_t isSelectedDplusInMassRange(const T& pTrackSameChargeFirst, const T& pTrac /// \param hMassVsPt histo with invariant mass vs pt /// \return BIT(0) for KKpi, BIT(1) for piKK, BIT(2) for phipi, BIT(3) for piphi template -int8_t isSelectedDsInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptD, const float& phiD, int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt, H2 hMassVsPhi) +int8_t isSelectedDsInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptD, const float& phiD, int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt) { int8_t retValue = 0; if (TESTBIT(isSelected, 0)) { auto invMassDsToKKPi = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massK, massK, massPi}); if (activateQA) { hMassVsPt->Fill(ptD, invMassDsToKKPi); - if (activateQA > 2) { - hMassVsPhi->Fill(phiD, invMassDsToKKPi); - } } if (std::abs(invMassDsToKKPi - massDs) < deltaMassCharmHadronForBeauty || ptD > 10) { retValue |= BIT(0); @@ -580,9 +581,6 @@ int8_t isSelectedDsInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSa auto invMassDsToPiKK = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massK}); if (activateQA) { hMassVsPt->Fill(ptD, invMassDsToPiKK); - if (activateQA > 2) { - hMassVsPhi->Fill(phiD, invMassDsToPiKK); - } } if (std::abs(invMassDsToPiKK - massDs) < deltaMassCharmHadronForBeauty || ptD > 10) { retValue |= BIT(1); @@ -603,16 +601,13 @@ int8_t isSelectedDsInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSa /// \param hMassVsPt histo with invariant mass vs pt /// \return BIT(0) for pKpi with mass cut, BIT(1) for piKp with mass cut template -int8_t isSelectedLcInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptLc, const float& phiLc, const int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt, H2 hMassVsPhi) +int8_t isSelectedLcInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptLc, const float& phiLc, const int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt) { int8_t retValue = 0; if (TESTBIT(isSelected, 0)) { auto invMassLcToPKPi = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massProton, massK, massPi}); if (activateQA) { hMassVsPt->Fill(ptLc, invMassLcToPKPi); - if (activateQA > 2) { - hMassVsPhi->Fill(phiLc, invMassLcToPKPi); - } } if (std::abs(invMassLcToPKPi - massLc) < deltaMassCharmHadronForBeauty || ptLc > 10) { retValue |= BIT(0); @@ -622,9 +617,6 @@ int8_t isSelectedLcInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSa auto invMassLcToPiKP = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massProton}); if (activateQA) { hMassVsPt->Fill(ptLc, invMassLcToPiKP); - if (activateQA > 2) { - hMassVsPhi->Fill(phiLc, invMassLcToPiKP); - } } if (std::abs(invMassLcToPiKP - massLc) < deltaMassCharmHadronForBeauty || ptLc > 10) { retValue |= BIT(1); @@ -645,16 +637,13 @@ int8_t isSelectedLcInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSa /// \param hMassVsPt histo with invariant mass vs pt /// \return BIT(0) for pKpi with mass cut, BIT(1) for piKp with mass cut template -int8_t isSelectedXicInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptXic, const float& phiXic, const int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt, H2 hMassVsPhi) +int8_t isSelectedXicInMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float& ptXic, const float& phiXic, const int8_t isSelected, const float& deltaMassCharmHadronForBeauty, const int& activateQA, H2 hMassVsPt) { int8_t retValue = 0; if (TESTBIT(isSelected, 0)) { auto invMassXicToPKPi = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massProton, massK, massPi}); if (activateQA) { hMassVsPt->Fill(ptXic, invMassXicToPKPi); - if (activateQA > 2) { - hMassVsPhi->Fill(phiXic, invMassXicToPKPi); - } } if (std::abs(invMassXicToPKPi - massXic) < deltaMassCharmHadronForBeauty || ptXic > 10) { retValue |= BIT(0); @@ -664,9 +653,6 @@ int8_t isSelectedXicInMassRange(const T& pTrackSameChargeFirst, const T& pTrackS auto invMassXicToPiKP = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massProton}); if (activateQA) { hMassVsPt->Fill(ptXic, invMassXicToPiKP); - if (activateQA > 2) { - hMassVsPhi->Fill(phiXic, invMassXicToPiKP); - } } if (std::abs(invMassXicToPiKP - massXic) < deltaMassCharmHadronForBeauty || ptXic > 10) { retValue |= BIT(1); @@ -677,59 +663,109 @@ int8_t isSelectedXicInMassRange(const T& pTrackSameChargeFirst, const T& pTrackS } /// Basic selection of gamma candidates -/// \param gamma is the gamma candidate -/// \param minGammaCosinePA is the minimum required cosp of the gamma -/// \param gammaCosinePA is the cosp of the gamma -/// \param hGammaSelected is the pointer to the QA histo for selected gammas -/// \param hGammaEtaBefore is the pointer to the QA histo for gamma eta before selection -/// \param hGammaArmPodBefore is the pointer to the QA histo AP plot before selection -/// \param hGammaEtaAfter is the pointer to the QA histo for gamma eta before selection -/// \param hGammaArmPodAfter is the pointer to the QA histo AP plot before selection +/// \param v0 is the v0 candidate +/// \param minGammaCosinePa is the minimum required cosp of the gamma +/// \param gammaCosinePa is the cosp of the gamma +/// \param minV0CosinePa is the cosp of the V0s +/// \param hV0Selected is the pointer to the QA histo for selected gammas +/// \param hArmPod is the pointer to an array of QA histo AP plot before selection /// \return true if gamma passes all cuts -template -bool isSelectedGamma(const T& gamma, const float& minGammaCosinePA, const float& gammaCosinePA, const int& activateQA, H1 hGammaSelected, H1 hGammaEtaBefore, H1 hGammaEtaAfter, H2 hGammaArmPodBefore, H2 hGammaArmPodAfter) +template +int isSelectedV0(const T& v0, const float& minGammaCosinePa, const float& minV0CosinePa, const float& v0CosinePa, const int& activateQA, H2 hV0Selected, A hArmPod) { + int isSelected{BIT(kPhoton) | BIT(kK0S) | BIT(kLambda) | BIT(kAntiLambda)}; + bool isRejected[kNV0] = {false, false, false, false}; + if (activateQA > 1) { - hGammaSelected->Fill(0); - hGammaEtaBefore->Fill(gamma.eta()); - hGammaArmPodBefore->Fill(gamma.alpha(), gamma.qtarm()); + for (int iV0{kPhoton}; iV0Fill(0., iV0); + } } - if (std::abs(gamma.eta()) > 0.8) { - if (activateQA > 1) - hGammaSelected->Fill(1); - return false; + + if (std::abs(v0.eta()) > 0.8) { // cut all V0s with |eta| > 0.8 + if (activateQA > 1) { + for (int iV0{kPhoton}; iV0Fill(1., iV0); + } + } + return 0; } - if (gamma.v0radius() < 0. || gamma.v0radius() > 180.) { - if (activateQA > 1) - hGammaSelected->Fill(2); - return false; + if (v0.v0radius() < 0. || v0.v0radius() > 180.) { + CLRBIT(isSelected, kPhoton); + if (activateQA > 1) { + isRejected[kPhoton] = true; + hV0Selected->Fill(2., kPhoton); + } } - if ((std::pow(gamma.alpha() / 0.95, 2) + std::pow(gamma.qtarm() / 0.05, 2)) >= 1) { - if (activateQA > 1) - hGammaSelected->Fill(3); - return false; + if (!isRejected[kPhoton] && v0CosinePa < minGammaCosinePa) { + CLRBIT(isSelected, kPhoton); + if (activateQA > 1) { + isRejected[kPhoton] = true; + hV0Selected->Fill(3., kPhoton); + } } - if (std::abs(gamma.psipair()) > 0.1) { - if (activateQA > 1) - hGammaSelected->Fill(4); - return false; + if (v0CosinePa < minV0CosinePa) { + if (activateQA > 1) { + for (int iV0{kK0S}; iV0Fill(3., iV0); + } + } + CLRBIT(isSelected, kK0S); + CLRBIT(isSelected, kLambda); + CLRBIT(isSelected, kAntiLambda); } - if (gammaCosinePA < minGammaCosinePA) { - if (activateQA > 1) - hGammaSelected->Fill(5); - return false; + if (!isRejected[kPhoton] && (std::pow(v0.alpha() / 0.95, 2) + std::pow(v0.qtarm() / 0.05, 2)) >= 1) { + CLRBIT(isSelected, kPhoton); + if (activateQA > 1) { + isRejected[kPhoton] = true; + hV0Selected->Fill(4., kPhoton); + } } - if (activateQA > 1) { - hGammaSelected->Fill(6); - hGammaEtaAfter->Fill(gamma.eta()); - hGammaArmPodAfter->Fill(gamma.alpha(), gamma.qtarm()); + if (!isRejected[kK0S] && std::abs(v0.mK0Short() - massK0S) > 0.08) { + CLRBIT(isSelected, kK0S); + if (activateQA > 1) { + isRejected[kK0S] = true; + hV0Selected->Fill(5., kK0S); + } } - return true; + if (!isRejected[kLambda] && std::abs(v0.mLambda() - massLambda) > 0.1) { + CLRBIT(isSelected, kLambda); + if (activateQA > 1) { + isRejected[kLambda] = true; + hV0Selected->Fill(5., kLambda); + } + } + if (!isRejected[kAntiLambda] && std::abs(v0.mAntiLambda() - massLambda) > 0.1) { + CLRBIT(isSelected, kAntiLambda); + if (activateQA > 1) { + isRejected[kAntiLambda] = true; + hV0Selected->Fill(5., kAntiLambda); + } + } + + if (!isRejected[kPhoton] && std::abs(v0.psipair()) > 0.1) { + CLRBIT(isSelected, kPhoton); + if (activateQA > 1) { + hV0Selected->Fill(6., kPhoton); + } + } + + if (activateQA) { + for (int iV0{kPhoton}; iV0Fill(v0.alpha(), v0.qtarm()); + if (activateQA > 1) { + hV0Selected->Fill(7., iV0); + } + } + } + + return isSelected; } /// Single-track cuts for bachelor track of beauty candidates diff --git a/EventFiltering/PWGHF/HFFilterQC.cxx b/EventFiltering/PWGHF/HFFilterQC.cxx index 60e0747834a..2e4e497d18c 100644 --- a/EventFiltering/PWGHF/HFFilterQC.cxx +++ b/EventFiltering/PWGHF/HFFilterQC.cxx @@ -52,8 +52,8 @@ struct HfFilterQc { // Main struct for HF trigger QC hPtDistr[0] = registry.add("hPtDistrAll", "All events;;#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {50, -0.5, 10.5}}); hPtDistr[1] = registry.add("hPtDistrTriggered", "HF triggered events;;#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {11, -0.5, 10.5}}); for (auto iTrig = 0; iTrig < kNtriggersHF; ++iTrig) { - hPartPerEvent[iTrig + 2] = registry.add(Form("hPartPerEvent%s", HfTriggerNames[iTrig].data()), Form("%s Filtered events;;number of particles", HfTriggerNames[iTrig].data()), HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {11, -0.5, 10.5}}); - hPtDistr[iTrig + 2] = registry.add(Form("hPtDistr%s", HfTriggerNames[iTrig].data()), Form("%s Filtered events;;#it{p}_{T} (GeV/#it{c})", HfTriggerNames[iTrig].data()), HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {11, -0.5, 10.5}}); + hPartPerEvent[iTrig + 2] = registry.add(Form("hPartPerEvent%s", hfTriggerNames[iTrig].data()), Form("%s Filtered events;;number of particles", hfTriggerNames[iTrig].data()), HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {11, -0.5, 10.5}}); + hPtDistr[iTrig + 2] = registry.add(Form("hPtDistr%s", hfTriggerNames[iTrig].data()), Form("%s Filtered events;;#it{p}_{T} (GeV/#it{c})", hfTriggerNames[iTrig].data()), HistType::kTH2F, {{kNCharmParticles, -0.5, kNCharmParticles - 0.5}, {11, -0.5, 10.5}}); } for (auto iTrig = 0; iTrig < kNtriggersHF + 1; ++iTrig) { for (auto iBin = 0; iBin < kNCharmParticles; ++iBin) { From bfe6220b29cbdb27e124b2c07e63eebf55c2feb4 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Wed, 14 Jun 2023 19:40:51 +0000 Subject: [PATCH 2/2] Please consider the following formatting changes --- EventFiltering/PWGHF/HFFilter.cxx | 2 +- EventFiltering/PWGHF/HFFilterHelpers.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 1d215b10f66..67787acaf85 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -527,7 +527,7 @@ struct HfFilter { // Main struct for HF triggers if (!keepEvent[kV0Charm2P] && (isCharmTagged || isBeautyTagged) && (TESTBIT(selD0, 0) || (TESTBIT(selD0, 1)))) { float v0CosinePa = v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); auto selV0 = isSelectedV0(v0, minCosPaGamma, minCosPaV0, v0CosinePa, activateQA, hV0Selected, hArmPod); - if(selV0) { + if (selV0) { std::array pVecV0 = {v0.px(), v0.py(), v0.pz()}; if (TESTBIT(selV0, kPhoton)) { auto massD0Gamma = RecoDecay::m(std::array{pVec2Prong, pVecV0}, std::array{massD0, massGamma}); diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 42684a9c49f..a5e8238780a 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -677,14 +677,14 @@ int isSelectedV0(const T& v0, const float& minGammaCosinePa, const float& minV0C bool isRejected[kNV0] = {false, false, false, false}; if (activateQA > 1) { - for (int iV0{kPhoton}; iV0Fill(0., iV0); } } if (std::abs(v0.eta()) > 0.8) { // cut all V0s with |eta| > 0.8 if (activateQA > 1) { - for (int iV0{kPhoton}; iV0Fill(1., iV0); } } @@ -709,7 +709,7 @@ int isSelectedV0(const T& v0, const float& minGammaCosinePa, const float& minV0C if (v0CosinePa < minV0CosinePa) { if (activateQA > 1) { - for (int iV0{kK0S}; iV0Fill(3., iV0); } @@ -757,7 +757,7 @@ int isSelectedV0(const T& v0, const float& minGammaCosinePa, const float& minV0C } if (activateQA) { - for (int iV0{kPhoton}; iV0Fill(v0.alpha(), v0.qtarm()); if (activateQA > 1) { hV0Selected->Fill(7., iV0);