Skip to content

Commit 1b50717

Browse files
authored
[PWGHF,Trigger] Add Charm baryons in D0p to HF filters (#10340)
1 parent 1d9d1cd commit 1b50717

File tree

3 files changed

+160
-13
lines changed

3 files changed

+160
-13
lines changed

EventFiltering/PWGHF/HFFilter.cxx

Lines changed: 147 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/// \author Alexandre Bigot <alexandre.bigot@cern.ch>, Strasbourg University
1919
/// \author Biao Zhang <biao.zhang@cern.ch>, CCNU
2020
/// \author Federica Zanone <federica.zanone@cern.ch>, Heidelberg University
21+
/// \author Antonio Palasciano <antonio.palasciano@cern.ch>, INFN Bari
2122

2223
#include <array>
2324
#include <memory>
@@ -108,8 +109,10 @@ struct HfFilter { // Main struct for HF triggers
108109

109110
// parameters for resonance triggers
110111
Configurable<LabeledArray<float>> cutsGammaK0sLambda{"cutsGammaK0sLambda", {cutsV0s[0], 1, 6, labelsEmpty, labelsColumnsV0s}, "Selections for V0s (gamma, K0s, Lambda) for D+V0 triggers"};
111-
Configurable<LabeledArray<float>> cutsPtDeltaMassCharmReso{"cutsPtDeltaMassCharmReso", {cutsCharmReso[0], 3, 11, labelsRowsDeltaMassCharmReso, labelsColumnsDeltaMassCharmReso}, "pt (GeV/c) and invariant-mass delta (GeV/c2) for charm hadron resonances"};
112+
Configurable<LabeledArray<float>> cutsPtDeltaMassCharmReso{"cutsPtDeltaMassCharmReso", {cutsCharmReso[0], 3, 13, labelsRowsDeltaMassCharmReso, labelsColumnsDeltaMassCharmReso}, "pt (GeV/c) and invariant-mass delta (GeV/c2) for charm hadron resonances"};
112113
Configurable<bool> keepAlsoWrongDmesLambdaPairs{"keepAlsoWrongDmesLambdaPairs", true, "flat go keep also wrong sign D+Lambda pairs"};
114+
Configurable<bool> keepAlsoWrongDmesProtonPairs{"keepAlsoWrongDmesProtonPairs", true, "flat go keep also wrong sign D0p pairs"};
115+
Configurable<bool> keepAlsoWrongDstarMesProtonPairs{"keepAlsoWrongDstarMesProtonPairs", true, "flat go keep also wrong sign D*0p pairs"};
113116

114117
// parameters for charm baryons to Xi bachelor
115118
Configurable<LabeledArray<float>> cutsXiCascades{"cutsXiCascades", {cutsCascades[0], 1, 8, labelsEmpty, labelsColumnsCascades}, "Selections for cascades (Xi) for Xi+bachelor triggers"};
@@ -170,7 +173,7 @@ struct HfFilter { // Main struct for HF triggers
170173
std::array<std::shared_ptr<TH1>, kNCharmParticles> hCharmProtonKstarDistr{};
171174
std::array<std::shared_ptr<TH1>, kNCharmParticles> hCharmDeuteronKstarDistr{};
172175
std::array<std::shared_ptr<TH2>, nTotBeautyParts> hMassVsPtB{};
173-
std::array<std::shared_ptr<TH2>, kNCharmParticles + 19> 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
176+
std::array<std::shared_ptr<TH2>, kNCharmParticles + 22> 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)
174177
std::array<std::shared_ptr<TH2>, 4> hPrDePID; // proton TPC, proton TOF, deuteron TPC, deuteron TOF
175178
std::array<std::shared_ptr<TH1>, kNCharmParticles> hBDTScoreBkg{};
176179
std::array<std::shared_ptr<TH1>, kNCharmParticles> hBDTScorePrompt{};
@@ -278,6 +281,12 @@ struct HfFilter { // Main struct for HF triggers
278281
hMassVsPtC[kNCharmParticles + 17] = registry.add<TH2>("fMassVsPtCharmBaryonToXiPiPi", "#it{M} vs. #it{p}_{T} distribution of triggered #Xi+#pi+#pi candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2D, {ptAxis, massAxisC[kNCharmParticles + 17]});
279282
// JPsi
280283
hMassVsPtC[kNCharmParticles + 18] = registry.add<TH2>("fMassVsPtJPsiToMuMu", "#it{M} vs. #it{p}_{T} distribution of triggered J/#psi to #mu#mu candidates;#it{p}_{T} (GeV/#it{c});#it{M} (GeV/#it{c}^{2});counts", HistType::kTH2D, {ptAxis, massAxisC[kNCharmParticles + 18]});
284+
// Lc resonances
285+
hMassVsPtC[kNCharmParticles + 19] = registry.add<TH2>("fMassVsPtCharmBaryonToD0P", "#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 + 19]});
286+
hMassVsPtC[kNCharmParticles + 20] = registry.add<TH2>("fMassVsPtCharmBaryonToD0PWrongSign", "#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 + 20]});
287+
// ThetaC
288+
hMassVsPtC[kNCharmParticles + 21] = registry.add<TH2>("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]});
289+
hMassVsPtC[kNCharmParticles + 22] = registry.add<TH2>("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]});
281290

282291
for (int iBeautyPart{0}; iBeautyPart < kNBeautyParticles; ++iBeautyPart) {
283292
hMassVsPtB[iBeautyPart] = registry.add<TH2>(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]});
@@ -376,7 +385,7 @@ struct HfFilter { // Main struct for HF triggers
376385

377386
bool keepEvent[kNtriggersHF]{false};
378387
if (!collision.sel8() || std::fabs(collision.posZ()) > 11.f) { // safety margin for Zvtx
379-
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[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]);
388+
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]);
380389
continue;
381390
}
382391

@@ -929,6 +938,140 @@ struct HfFilter { // Main struct for HF triggers
929938
}
930939
} // end V0 selection
931940

941+
// 2-prong (D0 or D*) with proton for Lc resonances and ThetaC (3100)
942+
if (!keepEvent[kPrCharm2P] && isD0SignalTagged && (TESTBIT(selD0InMass, 0) || TESTBIT(selD0InMass, 1))) {
943+
for (const auto& trackProtonId : trackIdsThisCollision) { // start loop over tracks selecting only protons
944+
auto trackProton = tracks.rawIteratorAt(trackProtonId.trackId());
945+
std::array<float, 3> pVecProton = trackProton.pVector();
946+
if (trackProton.globalIndex() == trackPos.globalIndex() || trackProton.globalIndex() == trackNeg.globalIndex()) {
947+
continue;
948+
}
949+
bool isProton = helper.isSelectedProton4CharmOrBeautyBaryons(trackProton);
950+
if (isProton) {
951+
if (!keepEvent[kPrCharm2P]) {
952+
// we first look for a D*+
953+
for (const auto& trackBachelorId : trackIdsThisCollision) { // start loop over tracks to find bachelor pion
954+
auto trackBachelor = tracks.rawIteratorAt(trackBachelorId.trackId());
955+
if (trackBachelor.globalIndex() == trackPos.globalIndex() || trackBachelor.globalIndex() == trackNeg.globalIndex() || trackBachelor.globalIndex() == trackProton.globalIndex()) {
956+
continue;
957+
}
958+
auto trackParBachelor = getTrackPar(trackBachelor);
959+
o2::gpu::gpustd::array<float, 2> dcaBachelor{trackBachelor.dcaXY(), trackBachelor.dcaZ()};
960+
std::array<float, 3> pVecBachelor = trackBachelor.pVector();
961+
if (trackBachelor.collisionId() != thisCollId) {
962+
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelor, 2.f, noMatCorr, &dcaBachelor);
963+
getPxPyPz(trackParBachelor, pVecBachelor);
964+
}
965+
int isTrackSelected = helper.isSelectedTrackForSoftPionOrBeauty<kPrCharm2P>(trackBachelor, trackParBachelor, dcaBachelor);
966+
if (TESTBIT(isTrackSelected, kSoftPion) && ((TESTBIT(selD0InMass, 0) && trackBachelor.sign() > 0) || (TESTBIT(selD0InMass, 1) && trackBachelor.sign() < 0))) {
967+
std::array<float, 2> massDausD0{massPi, massKa};
968+
auto massD0dau = massD0Cand;
969+
if (trackBachelor.sign() < 0) {
970+
massDausD0[0] = massKa;
971+
massDausD0[1] = massPi;
972+
massD0dau = massD0BarCand;
973+
}
974+
auto pVecDStarCand = RecoDecay::pVec(pVec2Prong, pVecBachelor);
975+
auto ptDStarCand = RecoDecay::pt(pVecDStarCand);
976+
double massDStarCand{-999.}, massDiffDstar{-999.};
977+
if (ptDStarCand > cutsPtDeltaMassCharmReso->get(2u, 0u)) {
978+
massDStarCand = RecoDecay::m(std::array{pVecPos, pVecNeg, pVecBachelor}, std::array{massDausD0[0], massDausD0[1], massPi});
979+
massDiffDstar = massDStarCand - massD0dau;
980+
if (cutsPtDeltaMassCharmReso->get(0u, 0u) <= massDiffDstar && massDiffDstar <= cutsPtDeltaMassCharmReso->get(1u, 0u)) {
981+
if (activateQA) { // probably this is not needed, since already performed for the Xic (duplicate)
982+
hMassVsPtC[kNCharmParticles]->Fill(ptDStarCand, massDiffDstar);
983+
}
984+
auto pVecReso2Prong = RecoDecay::pVec(pVecDStarCand, pVecProton);
985+
auto ptCand = RecoDecay::pt(pVecReso2Prong);
986+
if (ptCand > cutsPtDeltaMassCharmReso->get(2u, 12u)) {
987+
// build D*0p candidate with the possibility of storing also the other sign hyp.
988+
float massThetacCand{-999.}, massThetacBarCand{-999.};
989+
float massDiffThetacCand{-999.}, massDiffThetacBarCand{-999.};
990+
bool isRightSignThetaC{false}, isRightSignThetaCBar{false};
991+
if (TESTBIT(selD0InMass, 1)) { // Correct hyp: ThetaC -> pD*- -> D0bar\pi- (Equivalent to trackBachelor.sign() < 0)
992+
massThetacCand = RecoDecay::m(std::array{pVecPos, pVecNeg, pVecBachelor, pVecProton}, std::array{massDausD0[0], massDausD0[1], massPi, massProton});
993+
massDiffThetacCand = massThetacCand - massDStarCand;
994+
isRightSignThetaC = trackProton.sign() > 0; // right sign if proton
995+
}
996+
if (TESTBIT(selD0InMass, 0)) { // Correct hyp: ThetaCbar -> pD*+ -> pD0\pi+ (Equivalent to trackBachelor.sign() > 0)
997+
massThetacBarCand = RecoDecay::m(std::array{pVecPos, pVecNeg, pVecBachelor, pVecProton}, std::array{massDausD0[0], massDausD0[1], massPi, massProton});
998+
massDiffThetacBarCand = massThetacBarCand - massDStarCand;
999+
isRightSignThetaCBar = trackProton.sign() < 0; // right sign if antiproton
1000+
}
1001+
bool isGoodThetac = (cutsPtDeltaMassCharmReso->get(0u, 12u) < massDiffThetacCand && massDiffThetacCand < cutsPtDeltaMassCharmReso->get(1u, 12u));
1002+
bool isGoodThetacBar = (cutsPtDeltaMassCharmReso->get(0u, 12u) < massDiffThetacBarCand && massDiffThetacBarCand < cutsPtDeltaMassCharmReso->get(1u, 12u));
1003+
1004+
if (activateQA) {
1005+
if (isGoodThetac) {
1006+
if (isRightSignThetaC) {
1007+
hMassVsPtC[kNCharmParticles + 21]->Fill(ptCand, massDiffThetacCand);
1008+
} else if (!isRightSignThetaC && keepAlsoWrongDmesProtonPairs) {
1009+
hMassVsPtC[kNCharmParticles + 22]->Fill(ptCand, massDiffThetacBarCand);
1010+
}
1011+
}
1012+
if (isGoodThetacBar) {
1013+
if (isRightSignThetaCBar) {
1014+
hMassVsPtC[kNCharmParticles + 21]->Fill(ptCand, massDiffThetacCand);
1015+
} else if (!isRightSignThetaCBar && keepAlsoWrongDmesProtonPairs) {
1016+
hMassVsPtC[kNCharmParticles + 22]->Fill(ptCand, massDiffThetacBarCand);
1017+
}
1018+
}
1019+
}
1020+
if ((isGoodThetac && (isRightSignThetaC || keepAlsoWrongDstarMesProtonPairs)) || (isGoodThetacBar && (isRightSignThetaCBar || keepAlsoWrongDstarMesProtonPairs))) {
1021+
keepEvent[kPrCharm2P] = true;
1022+
break;
1023+
}
1024+
}
1025+
}
1026+
}
1027+
}
1028+
} // end bachelor pion for D*p pairs
1029+
// build D0p candidate with the possibility of storing also the other sign hyp.
1030+
float massLcStarCand{-999.}, massLcStarBarCand{-999.};
1031+
float massDiffLcStarCand{-999.}, massDiffLcStarBarCand{-999.};
1032+
bool isRightSignLcStar{false}, isRightSignLcStarBar{false};
1033+
auto pVecReso2Prong = RecoDecay::pVec(pVec2Prong, pVecProton);
1034+
auto ptCand = RecoDecay::pt(pVecReso2Prong);
1035+
if (ptCand > cutsPtDeltaMassCharmReso->get(2u, 11u)) {
1036+
if (TESTBIT(selD0InMass, 0)) {
1037+
massLcStarCand = RecoDecay::m(std::array{pVecPos, pVecNeg, pVecProton}, std::array{massPi, massKa, massProton});
1038+
massDiffLcStarCand = massLcStarCand - massD0Cand;
1039+
isRightSignLcStar = trackProton.sign() > 0; // right sign if proton
1040+
}
1041+
if (TESTBIT(selD0InMass, 1)) {
1042+
massLcStarBarCand = RecoDecay::m(std::array{pVecPos, pVecNeg, pVecProton}, std::array{massKa, massPi, massProton});
1043+
massDiffLcStarBarCand = massLcStarBarCand - massD0BarCand;
1044+
isRightSignLcStarBar = trackProton.sign() < 0; // right sign if antiproton
1045+
}
1046+
bool isGoodLcStar = (cutsPtDeltaMassCharmReso->get(0u, 11u) < massDiffLcStarCand && massDiffLcStarCand < cutsPtDeltaMassCharmReso->get(1u, 11u));
1047+
bool isGoodLcStarBar = (cutsPtDeltaMassCharmReso->get(0u, 11u) < massDiffLcStarBarCand && massDiffLcStarBarCand < cutsPtDeltaMassCharmReso->get(1u, 11u));
1048+
1049+
if (activateQA) {
1050+
if (isGoodLcStar) {
1051+
if (isRightSignLcStar) {
1052+
hMassVsPtC[kNCharmParticles + 19]->Fill(ptCand, massDiffLcStarCand);
1053+
} else if (!isRightSignLcStar && keepAlsoWrongDmesProtonPairs) {
1054+
hMassVsPtC[kNCharmParticles + 20]->Fill(ptCand, massDiffLcStarBarCand);
1055+
}
1056+
}
1057+
if (isGoodLcStarBar) {
1058+
if (isRightSignLcStarBar) {
1059+
hMassVsPtC[kNCharmParticles + 19]->Fill(ptCand, massDiffLcStarCand);
1060+
} else if (!isRightSignLcStarBar && keepAlsoWrongDmesProtonPairs) {
1061+
hMassVsPtC[kNCharmParticles + 20]->Fill(ptCand, massDiffLcStarBarCand);
1062+
}
1063+
}
1064+
}
1065+
if ((isGoodLcStar && (isRightSignLcStar || keepAlsoWrongDmesProtonPairs)) || (isGoodLcStarBar && (isRightSignLcStarBar || keepAlsoWrongDmesProtonPairs))) {
1066+
keepEvent[kPrCharm2P] = true;
1067+
break;
1068+
}
1069+
}
1070+
}
1071+
} // end proton loop
1072+
}
1073+
} // end Lc resonances via D0-proton decays
1074+
9321075
} // end loop over 2-prong candidates
9331076

9341077
std::vector<std::vector<int64_t>> indicesDau3Prong{};
@@ -1663,7 +1806,7 @@ struct HfFilter { // Main struct for HF triggers
16631806
}
16641807
}
16651808

1666-
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[kBtoJPsiKa], keepEvent[kBtoJPsiKstar], keepEvent[kBtoJPsiPhi], keepEvent[kBtoJPsiPrKa], keepEvent[kBtoJPsiPi]);
1809+
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]);
16671810

16681811
if (!std::accumulate(keepEvent, keepEvent + kNtriggersHF, 0)) {
16691812
hProcessedEvents->Fill(1);

0 commit comments

Comments
 (0)