diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 999af2224ec..3f05e59f9df 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -103,7 +103,7 @@ struct HfFilter { // Main struct for HF triggers } evSel; // nsigma PID (except for V0 and cascades) - Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 4, 8, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for ITS/TPC/TOF PID (except for V0 and cascades)"}; + Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 4, 9, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for ITS/TPC/TOF PID (except for V0 and cascades)"}; // min and max pts for tracks and bachelors (except for V0 and cascades) Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 10, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; Configurable> trackQaulityCuts{"trackQaulityCuts", {cutsTrackQuality[0], 2, 7, labelsColumnsPtThresholdsForFemto, labelsColumnsTrackQuality}, "Track quality cuts for proton and deuteron)"}; @@ -142,11 +142,20 @@ struct HfFilter { // Main struct for HF triggers // parameters for resonance triggers Configurable> cutsGammaK0sLambda{"cutsGammaK0sLambda", {cutsV0s[0], 1, 6, labelsEmpty, labelsColumnsV0s}, "Selections for V0s (gamma, K0s, Lambda) for D+V0 triggers"}; - Configurable> cutsPtDeltaMassCharmReso{"cutsPtDeltaMassCharmReso", {cutsCharmReso[0], 4, 13, labelsRowsDeltaMassCharmReso, labelsColumnsDeltaMassCharmReso}, "pt (GeV/c) and invariant-mass delta (GeV/c2) for charm hadron resonances"}; + Configurable> cutsPtDeltaMassCharmReso{"cutsPtDeltaMassCharmReso", {cutsCharmReso[0], 4, 14, labelsRowsDeltaMassCharmReso, labelsColumnsDeltaMassCharmReso}, "pt (GeV/c) and invariant-mass delta (GeV/c2) for charm hadron resonances"}; Configurable keepAlsoWrongDmesLambdaPairs{"keepAlsoWrongDmesLambdaPairs", true, "flat go keep also wrong sign D+Lambda pairs"}; Configurable keepAlsoWrongDmesProtonPairs{"keepAlsoWrongDmesProtonPairs", true, "flat go keep also wrong sign D0p pairs"}; Configurable keepAlsoWrongDstarMesProtonPairs{"keepAlsoWrongDstarMesProtonPairs", true, "flat go keep also wrong sign D*0p pairs"}; + // parameters for Sigma_C proton trigger + Configurable> cutsSigmaCPr{ + "cutsSigmaCPr", + {cutsSigmaCPrDefault[0], + static_cast(labelsRowsSigmaCPr.size()), + static_cast(labelsColumnsSigmaCPr.size()), + labelsRowsSigmaCPr, + labelsColumnsSigmaCPr}, + "Cuts for SigmaCPr trigger (proton pT, PID, TOF)"}; // parameters for charm baryons to Xi bachelor Configurable> cutsXiCascades{"cutsXiCascades", {cutsCascades[0], 1, 8, labelsEmpty, labelsColumnsCascades}, "Selections for cascades (Xi) for Xi+bachelor triggers"}; Configurable> cutsXiBachelor{"cutsXiBachelor", {cutsCharmBaryons[0], 1, 15, labelsEmpty, labelsColumnsCharmBarCuts}, "Selections for charm baryons (Xi+Pi, Xi+Ka, Xi+Pi+Pi)"}; @@ -161,6 +170,7 @@ struct HfFilter { // Main struct for HF triggers Configurable> thresholdBDTScoreDSToPiKK{"thresholdBDTScoreDSToPiKK", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Ds+ candidates"}; Configurable> thresholdBDTScoreLcToPiKP{"thresholdBDTScoreLcToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Lc+ candidates"}; Configurable> thresholdBDTScoreXicToPiKP{"thresholdBDTScoreXicToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Xic+ candidates"}; + Configurable> thresholdBDTScoreScLcToPiKP{"thresholdBDTScoreScLcToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Lc<--Sc candidates"}; Configurable acceptBdtBkgOnly{"acceptBdtBkgOnly", true, "Enable / disable selection based on BDT bkg score only"}; @@ -224,7 +234,7 @@ struct HfFilter { // Main struct for HF triggers std::array, kNCharmParticles> hCharmProtonKstarDistr{}; std::array, kNCharmParticles> hCharmDeuteronKstarDistr{}; std::array, nTotBeautyParts> hMassVsPtB{}; - std::array, kNCharmParticles + 23> hMassVsPtC{}; // +9 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic+* right sign, Xic+* wrong sign, Xic0* right sign, Xic0* wrong sign) +2 for SigmaC (SigmaC++, SigmaC0) +2 for SigmaCK pairs (SigmaC++K-, SigmaC0K0s) +3 for charm baryons (Xi+Pi, Xi+Ka, Xi+Pi+Pi) + JPsi + 4 for charm baryons (D0+p, D0+pWrongSign, D*0p, D*0+pWrongSign) + std::array, kNCharmParticles + 24> hMassVsPtC{}; // +9 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic+* right sign, Xic+* wrong sign, Xic0* right sign, Xic0* wrong sign) +2 for SigmaC (SigmaC++, SigmaC0) +2 for SigmaCK pairs (SigmaC++K-, SigmaC0K0s) +3 for charm baryons (Xi+Pi, Xi+Ka, Xi+Pi+Pi) + JPsi + 4 for charm baryons (D0+p, D0+pWrongSign, D*0p, D*0+pWrongSign) std::array, 4> hPrDePID; // proton TPC, proton TOF, deuteron TPC, deuteron TOF std::array, kNCharmParticles> hBDTScoreBkg{}; std::array, kNCharmParticles> hBDTScorePrompt{}; @@ -265,6 +275,7 @@ struct HfFilter { // Main struct for HF triggers helper.setCutsBtoJPsi(cutsBtoHadrons.cutsBtoJPsiX); helper.setNsigmaProtonCutsForFemto(std::array{nSigmaPidCuts->get(0u, 3u), nSigmaPidCuts->get(1u, 3u), nSigmaPidCuts->get(2u, 3u), nSigmaPidCuts->get(3u, 3u)}); helper.setNsigmaDeuteronCutsForFemto(std::array{nSigmaPidCuts->get(0u, 6u), nSigmaPidCuts->get(1u, 6u), nSigmaPidCuts->get(2u, 6u), nSigmaPidCuts->get(3u, 6u)}); + helper.setNsigmaProtonCutsForSigmaCPr(std::array{nSigmaPidCuts->get(0u, 6u), nSigmaPidCuts->get(1u, 6u), nSigmaPidCuts->get(2u, 6u), nSigmaPidCuts->get(3u, 6u)}); helper.setDeuteronTrackSelectionForFemto(trackQaulityCuts->get(1u, 0u), trackQaulityCuts->get(1u, 1u), trackQaulityCuts->get(1u, 2u), trackQaulityCuts->get(1u, 3u), trackQaulityCuts->get(1u, 4u), trackQaulityCuts->get(1u, 5u), trackQaulityCuts->get(1u, 6u)); helper.setNsigmaProtonCutsForCharmBaryons(nSigmaPidCuts->get(0u, 0u), nSigmaPidCuts->get(1u, 0u)); helper.setNsigmaPionKaonCutsForDzero(nSigmaPidCuts->get(0u, 1u), nSigmaPidCuts->get(1u, 1u)); @@ -283,6 +294,15 @@ struct HfFilter { // Main struct for HF triggers helper.setPtRangeSoftKaonXicResoToSigmaC(ptCuts->get(0u, 5u), ptCuts->get(1u, 5u)); helper.setVtxConfiguration(dfStrangeness, true); // (DCAFitterN, useAbsDCA) helper.setVtxConfiguration(dfStrangeness3, true); // (DCAFitterN, useAbsDCA) + helper.setParSigmaCPr( + cutsPtDeltaMassCharmReso->get(0u, 13u), // min ΔM + cutsPtDeltaMassCharmReso->get(1u, 13u), // max ΔM + cutsPtDeltaMassCharmReso->get(2u, 13u), // min pT SigmaC + cutsSigmaCPr->get(0u, 0u), // min pT proton + cutsSigmaCPr->get(1u, 0u), // max pT proton + static_cast(cutsSigmaCPr->get(2u, 0u)), // force TOF + cutsSigmaCPr->get(3u, 0u) // TOF pT threshold + ); dfStrangeness.setMatCorrType(matCorr); dfStrangeness3.setMatCorrType(matCorr); helper.setVtxConfiguration(df2, false); // (DCAFitterN, useAbsDCA) @@ -369,6 +389,8 @@ struct HfFilter { // Main struct for HF triggers // ThetaC hMassVsPtC[kNCharmParticles + 21] = registry.add("fMassVsPtCharmBaryonToDstarP", "#it{M} vs. #it{p}_{T} distribution of triggered D^{*0}#p candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2D, {ptAxis, massAxisC[kNCharmParticles + 21]}); hMassVsPtC[kNCharmParticles + 22] = registry.add("fMassVsPtCharmBaryonToDstarPWrongSign", "#it{M} vs. #it{p}_{T} distribution of triggered D^{*0}#p wrong sign candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2D, {ptAxis, massAxisC[kNCharmParticles + 22]}); + // SigmaC-p + hMassVsPtC[kNCharmParticles + 23] = registry.add("fMassVsPtSigmaCPr", "#it{M} vs. #it{p}_{T} distribution of #Sigma_{c} for SigmaCPr trigger;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2D, {ptAxis, massAxisC[kNCharmParticles + 23]}); 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::kTH2D, {ptAxis, massAxisB[iBeautyPart]}); @@ -406,6 +428,8 @@ struct HfFilter { // Main struct for HF triggers hPrDePID[1] = registry.add("fProtonTOFPID", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2D, {pAxis, nSigmaAxis}); hPrDePID[2] = registry.add("fDeuteronTPCPID", "#it{N}_{#sigma}^{TPC} vs. #it{p} for selected deuterons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}", HistType::kTH2D, {pAxis, nSigmaAxis}); hPrDePID[3] = registry.add("fDeuteronTOFPID", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected deuterons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2D, {pAxis, nSigmaAxis}); + hPrDePID[4] = registry.add("fProtonTPCPIDSigmaCPr", "#it{N}_{#sigma}^{TPC} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}", HistType::kTH2D, {pAxis, nSigmaAxis}); + hPrDePID[5] = registry.add("fProtonTOFPIDSigmaCPr", "#it{N}_{#sigma}^{TOF} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}", HistType::kTH2D, {pAxis, nSigmaAxis}); hV0Selected = registry.add("fV0Selected", "Selections for V0s;;counts", HistType::kTH2D, {{9, -0.5, 8.5}, {kNV0, -0.5, +kNV0 - 0.5}}); @@ -455,7 +479,7 @@ struct HfFilter { // Main struct for HF triggers bool isSelectedITSROFBorder = evSel.applyITSROFBorderCut ? collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder) : true; bool isSelectedPvZ = (std::fabs(collision.posZ()) < evSel.maxPvZ); if (!isSelectedTVX || !isSelectedTFBorder || !isSelectedITSROFBorder || !isSelectedPvZ) { - tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kV0Charm2P], keepEvent[kV0Charm3P], keepEvent[kCharmBarToXiBach], keepEvent[kSigmaCPPK], keepEvent[kSigmaC0K0], keepEvent[kPhotonCharm2P], keepEvent[kPhotonCharm3P], keepEvent[kSingleCharm2P], keepEvent[kSingleCharm3P], keepEvent[kSingleNonPromptCharm2P], keepEvent[kSingleNonPromptCharm3P], keepEvent[kCharmBarToXi2Bach], keepEvent[kPrCharm2P], keepEvent[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]); + tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kV0Charm2P], keepEvent[kV0Charm3P], keepEvent[kCharmBarToXiBach], keepEvent[kSigmaCPPK], keepEvent[kSigmaC0K0], keepEvent[kSigmaCPr], keepEvent[kPhotonCharm2P], keepEvent[kPhotonCharm3P], keepEvent[kSingleCharm2P], keepEvent[kSingleCharm3P], keepEvent[kSingleNonPromptCharm2P], keepEvent[kSingleNonPromptCharm3P], keepEvent[kCharmBarToXi2Bach], keepEvent[kPrCharm2P], keepEvent[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]); continue; } @@ -815,8 +839,8 @@ struct HfFilter { // Main struct for HF triggers } // end beauty selection // 2-prong femto - bool isProtonForCharm2Prong = helper.isSelectedTrack4Femto(track, trackParThird, activateQA, hPrDePID[0], hPrDePID[1], kProtonForFemto); - bool isDeuteronForCharm2Prong = helper.isSelectedTrack4Femto(track, trackParThird, activateQA, hPrDePID[2], hPrDePID[3], kDeuteronForFemto); + bool isProtonForCharm2Prong = helper.isSelectedTrack4Corr(track, trackParThird, activateQA, hPrDePID[0], hPrDePID[1], kProtonForFemto); + bool isDeuteronForCharm2Prong = helper.isSelectedTrack4Corr(track, trackParThird, activateQA, hPrDePID[2], hPrDePID[3], kDeuteronForFemto); if (track.collisionId() == thisCollId) { if (isProtonForCharm2Prong && !keepEvent[kFemto2P] && enableFemtoChannels->get(0u, 0u) && isD0CharmTagged) { @@ -1486,8 +1510,8 @@ struct HfFilter { // Main struct for HF triggers } // end beauty selection // 3-prong femto - bool isProton = helper.isSelectedTrack4Femto(track, trackParFourth, activateQA, hPrDePID[0], hPrDePID[1], kProtonForFemto); - bool isDeuteron = helper.isSelectedTrack4Femto(track, trackParFourth, activateQA, hPrDePID[2], hPrDePID[3], kDeuteronForFemto); + bool isProton = helper.isSelectedTrack4Corr(track, trackParFourth, activateQA, hPrDePID[0], hPrDePID[1], kProtonForFemto); + bool isDeuteron = helper.isSelectedTrack4Corr(track, trackParFourth, activateQA, hPrDePID[2], hPrDePID[3], kDeuteronForFemto); if (isProton && track.collisionId() == thisCollId) { for (int iHypo{0}; iHypo < kNCharmParticles - 1 && !keepEvent[kFemto3P]; ++iHypo) { @@ -1522,8 +1546,12 @@ struct HfFilter { // Main struct for HF triggers } } // end femto selection - // SigmaC++ K- trigger - if (!keepEvent[kSigmaCPPK] && is3Prong[2] > 0 && is3ProngInMass[2] > 0 && isSignalTagged[2] > 0 && helper.isSelectedKaonFromXicResoToSigmaC(track)) { + // SigmaC++ K- and SigmaC++,0 - p trigger + + bool isTrackKaon = helper.isSelectedKaonFromXicResoToSigmaC(track); + bool isTrackProton = helper.isSelectedTrack4Corr(track, trackParFourth, activateQA, hPrDePID[4], hPrDePID[5], kProtonForScPrCorr); + + if ((!keepEvent[kSigmaCPPK] || !keepEvent[kSigmaCPr]) && is3Prong[2] > 0 && is3ProngInMass[2] > 0 && isSignalTagged[2] > 0 && (isTrackKaon || isTrackProton)) { // we need a candidate Lc->pKpi and a candidate soft kaon // look for SigmaC++ candidates @@ -1538,8 +1566,7 @@ struct HfFilter { // Main struct for HF triggers // do not consider as candidate soft pion a track already used to build the current 3-prong candidate continue; } - - // exclude already the current track if it corresponds to the K- candidate + // exclude already the current track if it corresponds to the K- or proton candidate if (globalIndexSoftPi == track.globalIndex()) { continue; } @@ -1547,9 +1574,6 @@ struct HfFilter { // Main struct for HF triggers // check the candidate SigmaC++ charge std::array chargesSc = {trackFirst.sign(), trackSecond.sign(), trackThird.sign(), trackSoftPi.sign()}; int chargeSc = std::accumulate(chargesSc.begin(), chargesSc.end(), 0); // SIGNED electric charge of SigmaC candidate - if (std::abs(chargeSc) != 2) { - continue; - } // select soft pion candidates auto trackParSoftPi = getTrackPar(trackSoftPi); @@ -1575,51 +1599,63 @@ struct HfFilter { // Main struct for HF triggers /// - it is in the correct mass range // check the charge for SigmaC++K- candidates - if (std::abs(chargeSc + track.sign()) != 1) { - continue; - } - // check the invariant mass - float massSigmaCPKPi{-999.}, massSigmaCPiKP{-999.}, deltaMassXicResoPKPi{-999.}, deltaMassXicResoPiKP{-999.}; - float ptSigmaCKaon = RecoDecay::pt(pVecSigmaC, pVecFourth); + if (!keepEvent[kSigmaCPPK] && (std::abs(chargeSc + track.sign()) == 1 && std::abs(chargeSc) == 2)) { + // check the invariant mass + float massSigmaCPKPi{-999.}, massSigmaCPiKP{-999.}, deltaMassXicResoPKPi{-999.}, deltaMassXicResoPiKP{-999.}; + float ptSigmaCKaon = RecoDecay::pt(pVecSigmaC, pVecFourth); - if (ptSigmaCKaon > cutsPtDeltaMassCharmReso->get(2u, 10u)) { - if (TESTBIT(whichSigmaC, 0)) { - massSigmaCPKPi = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi}, std::array{massProton, massKa, massPi, massPi}); - deltaMassXicResoPKPi = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi, pVecFourth}, std::array{massProton, massKa, massPi, massPi, massKa}) - massSigmaCPKPi; - } - if (TESTBIT(whichSigmaC, 1)) { - massSigmaCPiKP = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi}, std::array{massPi, massKa, massProton, massPi}); - deltaMassXicResoPiKP = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi, pVecFourth}, std::array{massPi, massKa, massProton, massPi, massKa}) - massSigmaCPiKP; - } - bool isPKPiOk = (cutsPtDeltaMassCharmReso->get(0u, 10u) < deltaMassXicResoPKPi && deltaMassXicResoPKPi < cutsPtDeltaMassCharmReso->get(1u, 10u)); - bool isPiKPOk = (cutsPtDeltaMassCharmReso->get(0u, 10u) < deltaMassXicResoPiKP && deltaMassXicResoPiKP < cutsPtDeltaMassCharmReso->get(1u, 10u)); - if (isPKPiOk || isPiKPOk) { - /// This is a good SigmaC++K- event - keepEvent[kSigmaCPPK] = true; + if (ptSigmaCKaon > cutsPtDeltaMassCharmReso->get(2u, 10u)) { + if (TESTBIT(whichSigmaC, 0)) { + massSigmaCPKPi = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi}, std::array{massProton, massKa, massPi, massPi}); + deltaMassXicResoPKPi = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi, pVecFourth}, std::array{massProton, massKa, massPi, massPi, massKa}) - massSigmaCPKPi; + } + if (TESTBIT(whichSigmaC, 1)) { + massSigmaCPiKP = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi}, std::array{massPi, massKa, massProton, massPi}); + deltaMassXicResoPiKP = RecoDecay::m(std::array{pVecFirst, pVecSecond, pVecThird, pVecSoftPi, pVecFourth}, std::array{massPi, massKa, massProton, massPi, massKa}) - massSigmaCPiKP; + } + bool isPKPiOk = (cutsPtDeltaMassCharmReso->get(0u, 10u) < deltaMassXicResoPKPi && deltaMassXicResoPKPi < cutsPtDeltaMassCharmReso->get(1u, 10u)); + bool isPiKPOk = (cutsPtDeltaMassCharmReso->get(0u, 10u) < deltaMassXicResoPiKP && deltaMassXicResoPiKP < cutsPtDeltaMassCharmReso->get(1u, 10u)); + if ((isPKPiOk || isPiKPOk) && isTrackKaon) { + /// This is a good SigmaC++K- event + keepEvent[kSigmaCPPK] = true; - /// QA plot - if (activateQA) { - if (isPKPiOk) { - if (TESTBIT(whichSigmaC, 2)) { - hMassVsPtC[kNCharmParticles + 11]->Fill(ptSigmaCKaon, deltaMassXicResoPKPi); - } - if (TESTBIT(whichSigmaC, 3)) { - hMassVsPtC[kNCharmParticles + 12]->Fill(ptSigmaCKaon, deltaMassXicResoPKPi); - } - } - if (isPiKPOk) { - if (TESTBIT(whichSigmaC, 2)) { - hMassVsPtC[kNCharmParticles + 11]->Fill(ptSigmaCKaon, deltaMassXicResoPiKP); + /// QA plot + if (activateQA) { + if (isPKPiOk) { + if (TESTBIT(whichSigmaC, 2)) { + hMassVsPtC[kNCharmParticles + 11]->Fill(ptSigmaCKaon, deltaMassXicResoPKPi); + } + if (TESTBIT(whichSigmaC, 3)) { + hMassVsPtC[kNCharmParticles + 12]->Fill(ptSigmaCKaon, deltaMassXicResoPKPi); + } } - if (TESTBIT(whichSigmaC, 3)) { - hMassVsPtC[kNCharmParticles + 12]->Fill(ptSigmaCKaon, deltaMassXicResoPiKP); + if (isPiKPOk) { + if (TESTBIT(whichSigmaC, 2)) { + hMassVsPtC[kNCharmParticles + 11]->Fill(ptSigmaCKaon, deltaMassXicResoPiKP); + } + if (TESTBIT(whichSigmaC, 3)) { + hMassVsPtC[kNCharmParticles + 12]->Fill(ptSigmaCKaon, deltaMassXicResoPiKP); + } } } } } } } + float deltaEta = std::abs(RecoDecay::eta(pVecSigmaC) - track.eta()); + if (!keepEvent[kSigmaCPr] && (isTrackProton && deltaEta < 1.0)) { + auto tagBDT = helper.isBDTSelected(scores[2], thresholdBDTScoreScLcToPiKP.value); + int8_t whichSigmaC = helper.isSelectedSigmaCInDeltaMassRange<-1>(pVecFirst, pVecThird, pVecSecond, pVecSoftPi, ptSigmaC, is3Prong[2], hMassVsPtC[kNCharmParticles + 23], activateQA); + if (TESTBIT(whichSigmaC, 4)) { + if (TESTBIT(tagBDT, RecoDecay::OriginType::Prompt)) { + } + } + // helper.selectionSigmaCForScPCorr(pVecFirst, pVecThird, pVecSecond, pVecSoftPi, ptSigmaC, is3Prong[2], hMassVsPtC[kNCharmParticles + 23], activateQA, configSigmaC.minMassSigmaCCorr, configSigmaC.maxMassSigmaCCorr, configSigmaC.minPtSigmaC, configSigmaC.maxPtSigmaC) + if (TESTBIT(whichSigmaC, 4) && TESTBIT(tagBDT, RecoDecay::OriginType::Prompt)) { + keepEvent[kSigmaCPr] = true; + } + } } // end SigmaC++ candidate } // end loop over tracks (soft pi) } // end candidate Lc->pKpi @@ -2016,7 +2052,7 @@ struct HfFilter { // Main struct for HF triggers } } - tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kV0Charm2P], keepEvent[kV0Charm3P], keepEvent[kCharmBarToXiBach], keepEvent[kSigmaCPPK], keepEvent[kSigmaC0K0], keepEvent[kPhotonCharm2P], keepEvent[kPhotonCharm3P], keepEvent[kSingleCharm2P], keepEvent[kSingleCharm3P], keepEvent[kSingleNonPromptCharm2P], keepEvent[kSingleNonPromptCharm3P], keepEvent[kCharmBarToXi2Bach], keepEvent[kPrCharm2P], keepEvent[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]); + tags(keepEvent[kHighPt2P], keepEvent[kHighPt3P], keepEvent[kBeauty3P], keepEvent[kBeauty4P], keepEvent[kFemto2P], keepEvent[kFemto3P], keepEvent[kDoubleCharm2P], keepEvent[kDoubleCharm3P], keepEvent[kDoubleCharmMix], keepEvent[kV0Charm2P], keepEvent[kV0Charm3P], keepEvent[kCharmBarToXiBach], keepEvent[kSigmaCPPK], keepEvent[kSigmaC0K0], keepEvent[kSigmaCPr], keepEvent[kPhotonCharm2P], keepEvent[kPhotonCharm3P], keepEvent[kSingleCharm2P], keepEvent[kSingleCharm3P], keepEvent[kSingleNonPromptCharm2P], keepEvent[kSingleNonPromptCharm3P], keepEvent[kCharmBarToXi2Bach], keepEvent[kPrCharm2P], keepEvent[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]); if (!std::accumulate(keepEvent, keepEvent + kNtriggersHF, 0)) { hProcessedEvents->Fill(1); diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 5988e121e5e..14ec6573ed0 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -97,6 +97,7 @@ enum HfTriggers { kBtoJPsiPhi, kBtoJPsiPrKa, kBtoJPsiPi, + kSigmaCPr, kNtriggersHF }; @@ -154,7 +155,8 @@ enum PIDSpecies { enum trackSpecies { kProtonForFemto, - kDeuteronForFemto + kDeuteronForFemto, + kProtonForScPrCorr }; enum V0Species { @@ -245,7 +247,7 @@ static const int nTotBeautyParts = static_cast(kNBeautyParticles) + static_ static const std::array beautyParticleNames{"Bplus", "B0toDStar", "Bc", "B0", "Bs", "Lb", "Xib", "BplusToJPsi", "B0ToJPsi", "BsToJPsi", "LbToJPsi", "BcToJPsi"}; static const std::array pdgCodesCharm{421, 411, 431, 4122, 4232}; static const std::array eventTitles = {"all", "rejected"}; -static const std::vector hfTriggerNames{filtering::HfHighPt2P::columnLabel(), filtering::HfHighPt3P::columnLabel(), filtering::HfBeauty3P::columnLabel(), filtering::HfBeauty4P::columnLabel(), filtering::HfFemto2P::columnLabel(), filtering::HfFemto3P::columnLabel(), filtering::HfDoubleCharm2P::columnLabel(), filtering::HfDoubleCharm3P::columnLabel(), filtering::HfDoubleCharmMix::columnLabel(), filtering::HfV0Charm2P::columnLabel(), filtering::HfV0Charm3P::columnLabel(), filtering::HfCharmBarToXiBach::columnLabel(), filtering::HfSigmaCPPK::columnLabel(), filtering::HfSigmaC0K0::columnLabel(), filtering::HfPhotonCharm2P::columnLabel(), filtering::HfPhotonCharm3P::columnLabel(), filtering::HfSingleCharm2P::columnLabel(), filtering::HfSingleCharm3P::columnLabel(), filtering::HfSingleNonPromptCharm2P::columnLabel(), filtering::HfSingleNonPromptCharm3P::columnLabel(), filtering::HfCharmBarToXi2Bach::columnLabel(), filtering::HfPrCharm2P::columnLabel(), filtering::HfBtoJPsiKa::columnLabel(), filtering::HfBtoJPsiKstar::columnLabel(), filtering::HfBtoJPsiPhi::columnLabel(), filtering::HfBtoJPsiPrKa::columnLabel(), filtering::HfBtoJPsiPi::columnLabel()}; +static const std::vector hfTriggerNames{filtering::HfHighPt2P::columnLabel(), filtering::HfHighPt3P::columnLabel(), filtering::HfBeauty3P::columnLabel(), filtering::HfBeauty4P::columnLabel(), filtering::HfFemto2P::columnLabel(), filtering::HfFemto3P::columnLabel(), filtering::HfDoubleCharm2P::columnLabel(), filtering::HfDoubleCharm3P::columnLabel(), filtering::HfDoubleCharmMix::columnLabel(), filtering::HfV0Charm2P::columnLabel(), filtering::HfV0Charm3P::columnLabel(), filtering::HfCharmBarToXiBach::columnLabel(), filtering::HfSigmaCPPK::columnLabel(), filtering::HfSigmaC0K0::columnLabel(), filtering::HfPhotonCharm2P::columnLabel(), filtering::HfPhotonCharm3P::columnLabel(), filtering::HfSingleCharm2P::columnLabel(), filtering::HfSingleCharm3P::columnLabel(), filtering::HfSingleNonPromptCharm2P::columnLabel(), filtering::HfSingleNonPromptCharm3P::columnLabel(), filtering::HfCharmBarToXi2Bach::columnLabel(), filtering::HfPrCharm2P::columnLabel(), filtering::HfBtoJPsiKa::columnLabel(), filtering::HfBtoJPsiKstar::columnLabel(), filtering::HfBtoJPsiPhi::columnLabel(), filtering::HfBtoJPsiPrKa::columnLabel(), filtering::HfBtoJPsiPi::columnLabel(), filtering::HfSigmaCPr::columnLabel()}; static const std::array v0Labels{"#gamma", "K_{S}^{0}", "#Lambda", "#bar{#Lambda}"}; static const std::array v0Names{"Photon", "K0S", "Lambda", "AntiLambda"}; @@ -293,7 +295,7 @@ static const o2::framework::AxisSpec alphaAxis{100, -1.f, 1.f}; static const o2::framework::AxisSpec qtAxis{100, 0.f, 0.25f}; static const o2::framework::AxisSpec bdtAxis{100, 0.f, 1.f}; static const o2::framework::AxisSpec phiAxis{36, 0., o2::constants::math::TwoPI}; -static const std::array massAxisC = {o2::framework::AxisSpec{250, 1.65f, 2.15f}, o2::framework::AxisSpec{250, 1.65f, 2.15f}, o2::framework::AxisSpec{250, 1.75f, 2.25f}, o2::framework::AxisSpec{250, 2.05f, 2.55f}, o2::framework::AxisSpec{250, 2.25f, 2.75f}, o2::framework::AxisSpec{200, 0.139f, 0.159f}, o2::framework::AxisSpec{250, 0.f, 0.25f}, o2::framework::AxisSpec{250, 0.f, 0.25f}, o2::framework::AxisSpec{200, 0.48f, 0.88f}, o2::framework::AxisSpec{200, 0.48f, 0.88f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{170, 0.13f, 0.3f}, o2::framework::AxisSpec{170, 0.13f, 0.3f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{240, 2.4f, 3.6f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}}; +static const std::array massAxisC = {o2::framework::AxisSpec{250, 1.65f, 2.15f}, o2::framework::AxisSpec{250, 1.65f, 2.15f}, o2::framework::AxisSpec{250, 1.75f, 2.25f}, o2::framework::AxisSpec{250, 2.05f, 2.55f}, o2::framework::AxisSpec{250, 2.25f, 2.75f}, o2::framework::AxisSpec{200, 0.139f, 0.159f}, o2::framework::AxisSpec{250, 0.f, 0.25f}, o2::framework::AxisSpec{250, 0.f, 0.25f}, o2::framework::AxisSpec{200, 0.48f, 0.88f}, o2::framework::AxisSpec{200, 0.48f, 0.88f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{200, 1.1f, 1.4f}, o2::framework::AxisSpec{170, 0.13f, 0.3f}, o2::framework::AxisSpec{170, 0.13f, 0.3f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{200, 0.4f, 0.8f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{350, 2.3f, 3.0f}, o2::framework::AxisSpec{240, 2.4f, 3.6f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.7f, 1.3f}, o2::framework::AxisSpec{300, 0.14f, 0.26f}}; static const std::array massAxisB = {o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 5.4f, 7.4f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 4.4f, 6.4f}, o2::framework::AxisSpec{400, 5.0f, 6.6f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{500, 4.2f, 6.2f}, o2::framework::AxisSpec{400, 5.0f, 6.6f}, o2::framework::AxisSpec{240, 5.8f, 7.0f}}; // default values for configurables @@ -312,13 +314,13 @@ static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlu static const std::vector labelsRowsCutsPt = {"Minimum", "Maximum"}; // PID cuts -constexpr float cutsNsigma[4][8] = { - {3., 3., 3., 5., 3., 3., 5., 3.}, // TPC proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron, K/p from beauty->JPsiX - {3., 3., 3., 2.5, 3., 3., 5., 3.}, // TOF proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron, K/p from beauty->JPsiX - {999., 999., 999., 2.5, 999., 999., 5., 999.}, // Sum in quadrature of TPC and TOF (used only for femto selected proton and deuteron for pT < 4 GeV/c) - {999., 999., 999., 999., 999., 999., -4., 999.} // ITS used only for femto selected deuteron for less than pt threshold +constexpr float cutsNsigma[4][9] = { + {3., 3., 3., 5., 3., 3., 5., 3., 3.}, // TPC proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron, K/p from beauty->JPsiX, proton from SigmaC-Pr correaltion + {3., 3., 3., 2.5, 3., 3., 5., 3., 3.}, // TOF proton from Lc, pi/K from D0, K from 3-prong, femto selected proton, pi/K from Xic/Omegac, K from Xic*->SigmaC-Kaon, femto selected deuteron, K/p from beauty->JPsiX, proton from SigmaC-Pr correaltion + {999., 999., 999., 2.5, 999., 999., 5., 999., 3.}, // Sum in quadrature of TPC and TOF (used only for femto selected proton and deuteron for pT < 4 GeV/c) + {999., 999., 999., 999., 999., 999., -4., 999., 999.} // ITS used only for femto selected deuteron for less than pt threshold }; -static const std::vector labelsColumnsNsigma = {"PrFromLc", "PiKaFromDZero", "KaFrom3Prong", "PrForFemto", "PiKaFromCharmBaryon", "SoftKaonFromXicResoToSigmaC", "DeForFemto", "KaPrFromBeautyToJPsi"}; +static const std::vector labelsColumnsNsigma = {"PrFromLc", "PiKaFromDZero", "KaFrom3Prong", "PrForFemto", "PiKaFromCharmBaryon", "SoftKaonFromXicResoToSigmaC", "DeForFemto", "KaPrFromBeautyToJPsi", "PrFromSigmaCPr"}; static const std::vector labelsRowsNsigma = {"TPC", "TOF", "Comb", "ITS"}; // track cut @@ -363,11 +365,11 @@ static const std::vector labelsColumnsDoubleCharmChannels = {"Doubl static const std::vector labelsRowsDoubleCharmChannels = {"", "KeepNonprompt"}; // charm resonances -constexpr float cutsCharmReso[4][13] = {{0.0, 0.0, 0.0, 0.0, 0.4, 0., 0.0, 0.00, 0.21, 0.21, 0.0, 0.7, 0.7}, - {0.155, 0.3, 0.3, 0.88, 0.88, 1.35, 0.18, 0.18, 0.25, 0.25, 0.8, 1.3, 1.3}, - {0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 6.0, 0.0, 6.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; // D*+, D*0, Ds*0, Ds1+, Ds2*+, Xic*->D, SigmaC0, SigmaC++, SigmaC(2520)0, SigmaC(2520)++, Xic*->SigmaC, Lc*->D0P, Lc*->D*+P -static const std::vector labelsColumnsDeltaMassCharmReso = {"DstarPlus", "DstarZero", "DsStarZero", "Ds1Plus", "Ds2StarPlus", "XicResoToD", "SigmaC0", "SigmaCPlusPlus", "SigmaC02520", "SigmaCPlusPlus2520", "XicResoToSigmaC", "LcResoToD0Pr", "ThetaC"}; +constexpr float cutsCharmReso[4][14] = {{0.0, 0.0, 0.0, 0.0, 0.4, 0., 0.0, 0.00, 0.21, 0.21, 0.0, 0.7, 0.7, 0.15}, + {0.155, 0.3, 0.3, 0.88, 0.88, 1.35, 0.18, 0.18, 0.25, 0.25, 0.8, 1.3, 1.3, 0.19}, + {0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 6.0, 0.0, 6.0, 0.0, 0.0, 0.0, 5.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; // D*+, D*0, Ds*0, Ds1+, Ds2*+, Xic*->D, SigmaC0, SigmaC++, SigmaC(2520)0, SigmaC(2520)++, Xic*->SigmaC, Lc*->D0P, Lc*->D*+P +static const std::vector labelsColumnsDeltaMassCharmReso = {"DstarPlus", "DstarZero", "DsStarZero", "Ds1Plus", "Ds2StarPlus", "XicResoToD", "SigmaC0", "SigmaCPlusPlus", "SigmaC02520", "SigmaCPlusPlus2520", "XicResoToSigmaC", "LcResoToD0Pr", "ThetaC", "SigmaCPr"}; static const std::vector labelsRowsDeltaMassCharmReso = {"deltaMassMin", "deltaMassMax", "ptMin", "ptMinCharmDaugh"}; // V0s for charm resonances constexpr float cutsV0s[1][6] = {{0.85, 0.97, 0.5, 4., 0.02, 0.01}}; // cosPaGamma, cosPaK0sLambda, radiusK0sLambda, nSigmaPrLambda, deltaMassK0S, deltaMassLambda @@ -379,6 +381,21 @@ static const std::vector labelsColumnsCascades = {"PtBachelor", "Pt constexpr float cutsCharmBaryons[1][15] = {{5., 5., 1000., 2.35, 2.60, 2.35, 3., 3., 2.7, -2., -2., 1.e6, 1.e6, -1., -1.}}; // MinPtXiPi, MinPtXiKa, MinPtXiPiPi, MinMassXiPi, MinMassXiKa, MinMassXiPiPi, MaxMassXiPi, MaxMassXiKa, MaxMassXiPiPi, CosPaXiBach, CosPaXiBachBach, Chi2PcaXiBach, Chi2PcaXiBachBach, DecLenXiBach, DecLenBachBach static const std::vector labelsColumnsCharmBarCuts = {"MinPtXiPi", "MinPtXiKa", "MinPtXiPiPi", "MinMassXiPi", "MinMassXiKa", "MinMassXiPiPi", "MaxMassXiPi", "MaxMassXiKa", "MaxMassXiPiPi", "CosPaXiBach", "CosPaXiBachBach", "Chi2PcaXiBach", "Chi2PcaXiBachBach", "DecLenXiBach", "DecLenBachBach"}; +// proton for SigmaC-pr trigger +constexpr float cutsSigmaCPrDefault[4][1] = { + {0.399}, // ptPrMin + {4.501}, // ptPrMax + {1}, // forceTOF (0=false, 1=true) + {1.0} // ptTOFThreshold +}; +static const std::vector labelsRowsSigmaCPr = { + "ptPrMin", + "ptPrMax", + "forceTOF", + "ptTOFThreshold"}; +static const std::vector labelsColumnsSigmaCPr = { + "SigmaCPr"}; + constexpr int requireStrangenessTrackedXi[1][2] = {{1, 0}}; static const std::vector labelsColumnsCharmBaryons = {"CharmBarToXiBach", "CharmBarToXiBachBach"}; @@ -479,6 +496,19 @@ class HfFilterHelper mPtMinSigmaCPlusPlus = minPtSigmaCPlusPlus; mPtMinSigmaC2520PlusPlus = minPtSigmaC2520PlusPlus; } + void setParSigmaCPr(float minDeltaMassSigmaC, float maxDeltaMassSigmaC, float minPtSigmaC, float minPtProton, float maxPtProton, bool forceTOF, float minPtForTOF) + { + minDeltaMassScSigmaCPr = minDeltaMassSigmaC; + maxDeltaMassScSigmaCPr = maxDeltaMassSigmaC; + + minPtScSigmaPr = minPtSigmaC; + + minPtPrSigmaCPr = minPtProton; + maxPtPrSigmaCPr = maxPtProton; + + forceTOFForPrSigmaCPr = forceTOF; + thresholdPtTOFForPrSigmaCPr = minPtForTOF; + } void setPtRangeSoftKaonXicResoToSigmaC(float minPt, float maxPt) { mPtMinSoftKaonForXicResoToSigmaC = minPt; @@ -502,6 +532,7 @@ class HfFilterHelper void setNsigmaProtonCutsForFemto(std::array nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; } void setNsigmaDeuteronCutsForFemto(std::array nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; } + void setNsigmaProtonCutsForSigmaCPr(std::array nSigmaCuts) { mNSigmaPrCutsForSigmaCPr = nSigmaCuts; } void setDeuteronTrackSelectionForFemto(float minTpcCluster, float minTpcRow, float minTpcCrossedOverFound, float maxTpcShared, float maxTpcFracShared, float minItsCluster, float minItsIbCluster) { @@ -628,7 +659,7 @@ class HfFilterHelper template int16_t isSelectedTrackForSoftPionOrBeauty(const T& track, const T1& trackPar, const T2& dca); template - bool isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies); + bool isSelectedTrack4Corr(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies); template int8_t isDzeroPreselected(const T& trackPos, const T& trackNeg); template @@ -748,6 +779,7 @@ class HfFilterHelper float mPtMinSigmaC2520PlusPlus{0.f}; // pt min SigmaC(2520)++ candidate std::array mNSigmaPrCutsForFemto{3., 3., 3., -4.}; // cut values for Nsigma TPC, TOF, combined, ITS for femto protons std::array mNSigmaDeCutsForFemto{3., 3., 3., -4.}; // cut values for Nsigma TPC, TOF, combined, ITS for femto deuterons + std::array mNSigmaPrCutsForSigmaCPr{3., 3., 3., -4.}; // cut values for Nsigma TPC, TOF, combined, ITS for proton in Sc-p correaltion float mNSigmaTpcPrCutForCharmBaryons{3.}; // maximum Nsigma TPC for protons in Lc and Xic decays float mNSigmaTofPrCutForCharmBaryons{3.}; // maximum Nsigma TOF for protons in Lc and Xic decays float mNSigmaTpcKaCutFor3Prongs{3.}; // maximum Nsigma TPC for kaons in 3-prong decays @@ -807,6 +839,15 @@ class HfFilterHelper float mMaxTpcFracShared{1.}; // Maximum allowed fraction of shared TPC clusters relative to total clusters float mMinItsCluster{1.}; // Minimum required number of ITS clusters float mMinItsIbCluster{1.}; // Minimum required number of ITS clusters for IB + // SigmaC–p (ScPr) trigger + float minDeltaMassScSigmaCPr{0.15f}; // min Delta mass (SigmaC) + float maxDeltaMassScSigmaCPr{0.19f}; // max Delta mass (SigmaC) + float minPtScSigmaPr{4.99f}; // min pT(SigmaC) + float minPtPrSigmaCPr{0.399f}; // min pT(proton) + float maxPtPrSigmaCPr{4.501f}; // max pT(proton) + bool forceTOFForPrSigmaCPr{true}; // force TOF for proton + float thresholdPtTOFForPrSigmaCPr{1.0f}; // pT threshold above which TOF is required + // PID recalibrations int mTpcPidCalibrationOption{0}; // Option for TPC PID calibration (0 -> AO2D, 1 -> postcalibrations, 2 -> alternative bethe bloch parametrisation) std::array mHistMapPiPrKaDe{}; // Map for TPC PID postcalibrations for pions, kaon, protons and deuterons @@ -873,7 +914,7 @@ inline int16_t HfFilterHelper::isSelectedTrackForSoftPionOrBeauty(const T& track return kRejected; } - if constexpr (whichTrigger == kSigmaCPPK || whichTrigger == kSigmaC0K0) { + if constexpr (whichTrigger == kSigmaCPPK || whichTrigger == kSigmaC0K0 || whichTrigger == kSigmaCPr) { // SigmaC0,++ soft pion pt cut if (pT < mPtMinSoftPionForSigmaC || pT > mPtMaxSoftPionForSigmaC) { @@ -937,7 +978,7 @@ inline int16_t HfFilterHelper::isSelectedTrackForSoftPionOrBeauty(const T& track /// \param trackSpecies flag to choose proton or deuteron /// \return true if track passes all cuts template -inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies) +inline bool HfFilterHelper::isSelectedTrack4Corr(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies) { float pt = trackPar.getPt(); float ptMin, ptMax, ptThresholdPidStrategy; @@ -960,6 +1001,13 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra forceTof = mForceTofDeuteronForFemto; ptThresholdPidStrategy = mPtThresholdDeuteronForFemto; break; + case kProtonForScPrCorr: + ptMin = minPtPrSigmaCPr; + ptMax = maxPtPrSigmaCPr; + nSigmaCuts = mNSigmaPrCutsForSigmaCPr; + forceTof = forceTOFForPrSigmaCPr; + ptThresholdPidStrategy = thresholdPtTOFForPrSigmaCPr; + break; default: return false; // Unknown particle type } @@ -977,27 +1025,27 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra return false; // use only global tracks } // PID evaluation - float NSigmaITS = (trackSpecies == kProtonForFemto) ? track.itsNSigmaPr() : track.itsNSigmaDe(); // only used for deuteron - float NSigmaTPC = (trackSpecies == kProtonForFemto) ? track.tpcNSigmaPr() : track.tpcNSigmaDe(); - float NSigmaTOF = (trackSpecies == kProtonForFemto) ? track.tofNSigmaPr() : track.tofNSigmaDe(); + float NSigmaITS = (trackSpecies == kDeuteronForFemto) ? track.itsNSigmaDe() : track.itsNSigmaPr(); // only used for deuteron + float NSigmaTPC = (trackSpecies == kDeuteronForFemto) ? track.tpcNSigmaDe() : track.tpcNSigmaPr(); + float NSigmaTOF = (trackSpecies == kDeuteronForFemto) ? track.tofNSigmaDe() : track.tofNSigmaPr(); if (!forceTof && !track.hasTOF()) { NSigmaTOF = 0.; // always accepted } // Apply TPC PID post-calibration(only available for proton, dummy for deuteron) if (mTpcPidCalibrationOption == 1) { - NSigmaTPC = getTPCPostCalib(track, trackSpecies == kProtonForFemto ? kPr : kDe); + NSigmaTPC = getTPCPostCalib(track, trackSpecies == kDeuteronForFemto ? kDe : kPr); } else if (mTpcPidCalibrationOption == 2) { if (track.sign() > 0) { - NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kProtonForFemto ? kPr : kDe); + NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kDeuteronForFemto ? kDe : kPr); } else { - NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kProtonForFemto ? kAntiPr : kAntiDe); + NSigmaTPC = getTPCSplineCalib(track, trackSpecies == kDeuteronForFemto ? kAntiDe : kAntiPr); } } float NSigma = std::sqrt(NSigmaTPC * NSigmaTPC + NSigmaTOF * NSigmaTOF); float momentum = track.p(); - if (trackSpecies == kProtonForFemto) { + if (trackSpecies == kProtonForFemto || trackSpecies == kProtonForScPrCorr) { if (momentum <= ptThresholdPidStrategy) { if (NSigma > nSigmaCuts[2]) { return false; @@ -1340,18 +1388,26 @@ inline int8_t HfFilterHelper::isSelectedSigmaCInDeltaMassRange(const T& pTrackSa } if (isSigmaC2455 || isSigmaC2520) { retValue |= BIT(0); - if (isSigmaC2455) { + if (isSigmaC2455) SETBIT(retValue, 2); - } - if (isSigmaC2520) { + if (isSigmaC2520) SETBIT(retValue, 3); - } - /// QA plot - if (activateQA) { - hMassVsPt->Fill(ptSigmaC, deltaMassPKPi); + } + + // --- SigmaCPr selection --- + if constexpr (charge == -1) { + if (deltaMassPKPi > minDeltaMassScSigmaCPr && + deltaMassPKPi < maxDeltaMassScSigmaCPr && + ptSigmaC > minPtScSigmaPr) // proton cuts + { + SETBIT(retValue, 4); // SigmaCPr bit } } - } + + if (activateQA) + hMassVsPt->Fill(ptSigmaC, deltaMassPKPi); + } + if (TESTBIT(isSelectedLc, 1)) { /// Lc->piKp case auto invMassLcToPiKP = RecoDecay::m(std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massKa, massProton}); @@ -1369,17 +1425,22 @@ inline int8_t HfFilterHelper::isSelectedSigmaCInDeltaMassRange(const T& pTrackSa } if (isSigmaC2455 || isSigmaC2520) { retValue |= BIT(1); - if (isSigmaC2455) { + if (isSigmaC2455) SETBIT(retValue, 2); - } - if (isSigmaC2520) { + if (isSigmaC2520) SETBIT(retValue, 3); - } - /// QA plot - if (activateQA) { - hMassVsPt->Fill(ptSigmaC, deltaMassPiKP); + } + + // --- SigmaCPr selection --- + if constexpr (charge == -1) { + if (deltaMassPiKP > minDeltaMassScSigmaCPr && + deltaMassPiKP < maxDeltaMassScSigmaCPr && + ptSigmaC > minPtScSigmaPr) { + SETBIT(retValue, 4); // SigmaCPr bit } } + if (activateQA) + hMassVsPt->Fill(ptSigmaC, deltaMassPiKP); } /// TODO: add QA plot diff --git a/EventFiltering/filterTables.h b/EventFiltering/filterTables.h index c1463ba55f2..1e8909dcb7b 100644 --- a/EventFiltering/filterTables.h +++ b/EventFiltering/filterTables.h @@ -92,6 +92,7 @@ DECLARE_SOA_COLUMN(HfCharmBarToXi2Bach, hasHfCharmBarToXi2Bach, bool); DECLARE_SOA_COLUMN(HfPrCharm2P, hasHfPrCharm2P, bool); //! Charm baryon to 2-prong + bachelors DECLARE_SOA_COLUMN(HfSigmaCPPK, hasHfSigmaCPPK, bool); //! SigmaC(2455)++K- and SigmaC(2520)++K- + c.c. DECLARE_SOA_COLUMN(HfSigmaC0K0, hasHfSigmaC0K0, bool); //! SigmaC(2455)0KS0 and SigmaC(2520)0KS0 +DECLARE_SOA_COLUMN(HfSigmaCPr, hasHfSigmaCPr, bool); //! SigmaC(2455)Proton corr DECLARE_SOA_COLUMN(HfPhotonCharm2P, hasHfPhotonCharm2P, bool); //! photon with 2-prong charm hadron DECLARE_SOA_COLUMN(HfPhotonCharm3P, hasHfPhotonCharm3P, bool); //! photon with 3-prong charm hadron DECLARE_SOA_COLUMN(HfSingleCharm2P, hasHfSingleCharm2P, bool); //! 2-prong charm hadron (for efficiency studies) @@ -281,6 +282,7 @@ DECLARE_SOA_TABLE(HfFilters, "AOD", "HfFilters", //! filtering::HfCharmBarToXiBach, filtering::HfSigmaCPPK, filtering::HfSigmaC0K0, + filtering::HfSigmaCPr, filtering::HfPhotonCharm2P, filtering::HfPhotonCharm3P, filtering::HfSingleCharm2P,