Skip to content

Commit d4af649

Browse files
committed
First version of Bs workflow
1 parent b89c372 commit d4af649

8 files changed

Lines changed: 1224 additions & 0 deletions

File tree

PWGHF/Core/SelectorCuts.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ enum Code {
3232
kB0Bar = -511,
3333
kBPlus = 521,
3434
kBS = 531,
35+
kBSBar = -531,
3536
kD0 = 421,
3637
kD0Bar = -421,
3738
kDMinus = -411,
3839
kDPlus = 411,
3940
kDS = 431,
41+
kDSBar = -431,
4042
kDStar = 413,
4143
kChiC1 = 20443,
4244
kJPsi = 443,
@@ -697,6 +699,62 @@ static const std::vector<std::string> labelsPt = {
697699
static const std::vector<std::string> labelsCutVar = {"m", "CPA", "Chi2PCA", "d0 D", "d0 Pi", "pT D", "pT Pi", "B0 decLen", "B0 decLenXY", "Imp. Par. Product", "DeltaMD", "Cos ThetaStar"};
698700
} // namespace hf_cuts_b0_to_d_pi
699701

702+
namespace hf_cuts_bs_to_ds_pi
703+
{
704+
static constexpr int nBinsPt = 12;
705+
static constexpr int nCutVars = 12;
706+
// default values for the pT bin edges (can be used to configure histogram axis)
707+
// offset by 1 from the bin numbers in cuts array
708+
constexpr double binsPt[nBinsPt + 1] = {
709+
0,
710+
0.5,
711+
1.0,
712+
2.0,
713+
3.0,
714+
4.0,
715+
5.0,
716+
7.0,
717+
10.0,
718+
13.0,
719+
16.0,
720+
20.0,
721+
24.0};
722+
723+
auto vecBinsPt = std::vector<double>{binsPt, binsPt + nBinsPt + 1};
724+
725+
// default values for the cuts
726+
// DeltaM CPA chi2PCA d0D d0Pi pTD pTPi B0DecayLength B0DecayLengthXY IPProd DeltaMD CthetaStr
727+
constexpr double cuts[nBinsPt][nCutVars] = {{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 0 < pt < 0.5 */
728+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 0.5 < pt < 1 */
729+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 1 < pt < 2 */
730+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 2 < pt < 3 */
731+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 3 < pt < 4 */
732+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 4 < pt < 5 */
733+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 5 < pt < 7 */
734+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 7 < pt < 10 */
735+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 10 < pt < 13 */
736+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 13 < pt < 16 */
737+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}, /* 16 < pt < 20 */
738+
{1., 0.8, 1., 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.8}}; /* 20 < pt < 24 */
739+
// row labels
740+
static const std::vector<std::string> labelsPt = {
741+
"pT bin 0",
742+
"pT bin 1",
743+
"pT bin 2",
744+
"pT bin 3",
745+
"pT bin 4",
746+
"pT bin 5",
747+
"pT bin 6",
748+
"pT bin 7",
749+
"pT bin 8",
750+
"pT bin 9",
751+
"pT bin 10",
752+
"pT bin 11"};
753+
754+
// column labels
755+
static const std::vector<std::string> labelsCutVar = {"m", "CPA", "Chi2PCA", "d0 D", "d0 Pi", "pT D", "pT Pi", "B0 decLen", "B0 decLenXY", "Imp. Par. Product", "DeltaMD", "Cos ThetaStar"};
756+
} // namespace hf_cuts_bs_to_ds_pi
757+
700758
namespace hf_cuts_bplus_to_d0_pi
701759
{
702760
static constexpr int nBinsPt = 12;

PWGHF/D2H/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ o2physics_add_dpl_workflow(task-bplus-reduced
2929
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
3030
COMPONENT_NAME Analysis)
3131

32+
o2physics_add_dpl_workflow(task-bs
33+
SOURCES taskBs.cxx
34+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
35+
COMPONENT_NAME Analysis)
36+
3237
o2physics_add_dpl_workflow(task-d0
3338
SOURCES taskD0.cxx
3439
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore

PWGHF/D2H/Tasks/taskBs.cxx

Lines changed: 318 additions & 0 deletions
Large diffs are not rendered by default.

PWGHF/DataModel/CandidateReconstructionTables.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,107 @@ DECLARE_SOA_TABLE(HfCandB0McGen, "AOD", "HFCANDB0MCGEN",
18821882
hf_cand_b0::FlagMcMatchGen,
18831883
hf_cand_b0::OriginMcGen);
18841884

1885+
// specific Bs candidate properties
1886+
namespace hf_cand_bs
1887+
{
1888+
DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand3Prong, "_0"); // Ds index
1889+
// MC matching result:
1890+
DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level
1891+
DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // generator level
1892+
DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); // particle origin, reconstruction level
1893+
DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); // particle origin, generator level
1894+
DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level
1895+
1896+
// mapping of decay types
1897+
enum DecayType { BsToDsPi };
1898+
1899+
enum DecayTypeMc : uint8_t { BsToDsPiToKKPiPi = 0,
1900+
PartlyRecoDecay,
1901+
OtherDecay,
1902+
NDecayTypeMc};
1903+
// B0s(B0sbar) → Ds∓ π±
1904+
template <typename T>
1905+
auto ctBs(const T& candidate)
1906+
{
1907+
return candidate.ct(RecoDecay::getMassPDG(pdg::Code::kBS));
1908+
}
1909+
1910+
template <typename T>
1911+
auto yBs(const T& candidate)
1912+
{
1913+
return candidate.y(RecoDecay::getMassPDG(pdg::Code::kBS));
1914+
}
1915+
1916+
template <typename T>
1917+
auto eBs(const T& candidate)
1918+
{
1919+
return candidate.e(RecoDecay::getMassPDG(pdg::Code::kBS));
1920+
}
1921+
1922+
template <typename T>
1923+
auto invMassBsToDsPi(const T& candidate)
1924+
{
1925+
return candidate.m(array{RecoDecay::getMassPDG(pdg::Code::kDSBar), RecoDecay::getMassPDG(kPiPlus)});
1926+
}
1927+
1928+
template <typename T>
1929+
auto cosThetaStarBs(const T& candidate)
1930+
{
1931+
return candidate.cosThetaStar(array{RecoDecay::getMassPDG(pdg::Code::kDSBar), RecoDecay::getMassPDG(kPiPlus)}, RecoDecay::getMassPDG(pdg::Code::kBS), 1);
1932+
}
1933+
} // namespace hf_cand_bs
1934+
1935+
// declare dedicated Bs decay candidate table
1936+
DECLARE_SOA_TABLE(HfCandBsBase, "AOD", "HFCANDBSBASE",
1937+
// general columns
1938+
HFCAND_COLUMNS,
1939+
// 2-prong specific columns
1940+
hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0,
1941+
hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1,
1942+
hf_cand::ImpactParameter0, hf_cand::ImpactParameter1,
1943+
hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1,
1944+
hf_cand_bs::Prong0Id, hf_track_index::Prong1Id,
1945+
hf_track_index::HFflag,
1946+
/* dynamic columns */
1947+
hf_cand_2prong::M<hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1>,
1948+
hf_cand_2prong::M2<hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1>,
1949+
hf_cand_2prong::ImpactParameterProduct<hf_cand::ImpactParameter0, hf_cand::ImpactParameter1>,
1950+
hf_cand_2prong::CosThetaStar<hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1>,
1951+
hf_cand_2prong::ImpactParameterProngSqSum<hf_cand::ImpactParameter0, hf_cand::ImpactParameter1>,
1952+
/* dynamic columns that use candidate momentum components */
1953+
hf_cand::Pt<hf_cand_2prong::Px, hf_cand_2prong::Py>,
1954+
hf_cand::Pt2<hf_cand_2prong::Px, hf_cand_2prong::Py>,
1955+
hf_cand::P<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1956+
hf_cand::P2<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1957+
hf_cand::PVector<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1958+
hf_cand::CPA<collision::PosX, collision::PosY, collision::PosZ, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1959+
hf_cand::CPAXY<collision::PosX, collision::PosY, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand_2prong::Px, hf_cand_2prong::Py>,
1960+
hf_cand::Ct<collision::PosX, collision::PosY, collision::PosZ, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1961+
hf_cand::ImpactParameterXY<collision::PosX, collision::PosY, collision::PosZ, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1962+
hf_cand_2prong::MaxNormalisedDeltaIP<collision::PosX, collision::PosY, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ErrorDecayLengthXY, hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand::ImpactParameter0, hf_cand::ErrorImpactParameter0, hf_cand::ImpactParameter1, hf_cand::ErrorImpactParameter1, hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PxProng1, hf_cand::PyProng1>,
1963+
hf_cand::Eta<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1964+
hf_cand::Phi<hf_cand_2prong::Px, hf_cand_2prong::Py>,
1965+
hf_cand::Y<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1966+
hf_cand::E<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>,
1967+
hf_cand::E2<hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz>);
1968+
1969+
// extended table with expression columns that can be used as arguments of dynamic columns
1970+
DECLARE_SOA_EXTENDED_TABLE_USER(HfCandBsExt, HfCandBsBase, "HFCANDBSEXT",
1971+
hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz);
1972+
1973+
using HfCandBs = HfCandBsExt;
1974+
1975+
// table with results of reconstruction level MC matching
1976+
DECLARE_SOA_TABLE(HfCandBsMcRec, "AOD", "HFCANDBSMCREC",
1977+
hf_cand_bs::FlagMcMatchRec,
1978+
hf_cand_bs::OriginMcRec,
1979+
hf_cand_bs::DebugMcRec);
1980+
1981+
// table with results of generator level MC matching
1982+
DECLARE_SOA_TABLE(HfCandBsMcGen, "AOD", "HFCANDBSMCGEN",
1983+
hf_cand_bs::FlagMcMatchGen,
1984+
hf_cand_bs::OriginMcGen);
1985+
18851986
// specific Σc0,++ candidate properties
18861987
namespace hf_cand_sigmac
18871988
{

PWGHF/DataModel/CandidateSelectionTables.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,110 @@ bool selectionPID(const T1& pidTrackPi, const T2& acceptPIDNotApplicable)
296296
DECLARE_SOA_TABLE(HfSelB0ToDPi, "AOD", "HFSELB0", //!
297297
hf_sel_candidate_b0::IsSelB0ToDPi);
298298

299+
namespace hf_sel_candidate_bs
300+
{
301+
DECLARE_SOA_COLUMN(IsSelBsToDsPi, isSelBsToDsPi, int); //!
302+
303+
/// Apply topological cuts as defined in SelectorCuts.h
304+
/// \param candBs Bs candidate
305+
/// \param cuts Bs candidate selection per pT bin"
306+
/// \param binsPt pT bin limits
307+
/// \return true if candidate passes all selections
308+
template <typename T1, typename T2, typename T3>
309+
bool selectionTopol(const T1& candBs, const T2& cuts, const T3& binsPt)
310+
{
311+
auto ptCandBs = candBs.pt();
312+
auto ptDs = RecoDecay::pt(candBs.pxProng0(), candBs.pyProng0());
313+
auto ptPi = RecoDecay::pt(candBs.pxProng1(), candBs.pyProng1());
314+
315+
int pTBin = findBin(binsPt, ptCandBs);
316+
if (pTBin == -1) {
317+
// LOGF(info, "B0 topol selection failed at getpTBin");
318+
return false;
319+
}
320+
321+
// // check that the candidate pT is within the analysis range
322+
// if (ptCandBs < ptCandMin || ptCandBs >= ptCandMax) {
323+
// return false;
324+
// }
325+
326+
// Bs mass cut
327+
if (std::abs(o2::aod::hf_cand_bs::invMassBsToDsPi(candBs) - RecoDecay::getMassPDG(o2::analysis::pdg::Code::kBS)) > cuts->get(pTBin, "m")) {
328+
// Printf("Bs topol selection failed at mass diff check");
329+
return false;
330+
}
331+
332+
// pion pt
333+
if (ptPi < cuts->get(pTBin, "pT Pi")) {
334+
return false;
335+
}
336+
337+
// D- pt
338+
if (ptDs < cuts->get(pTBin, "pT Ds")) {
339+
return false;
340+
}
341+
342+
/*
343+
// D mass cut | already applied in candidateSelectorDplusToPiKPi.cxx
344+
if (std::abs(o2::aod::hf_cand_3prong::invMassDplusToPiKPi(hfCandD) - RecoDecay::getMassPDG(o2::analysis::pdg::Code::kDMinus)) > cuts->get(pTBin, "DeltaMD")) {
345+
return false;
346+
}
347+
*/
348+
349+
// Bs Decay length
350+
if (candBs.decayLength() < cuts->get(pTBin, "Bs decLen")) {
351+
return false;
352+
}
353+
354+
// Bs Decay length XY
355+
if (candBs.decayLengthXY() < cuts->get(pTBin, "Bs decLenXY")) {
356+
return false;
357+
}
358+
359+
// Bs chi2PCA cut
360+
if (candBs.chi2PCA() > cuts->get(pTBin, "Chi2PCA")) {
361+
return false;
362+
}
363+
364+
// Bs CPA cut
365+
if (candBs.cpa() < cuts->get(pTBin, "CPA")) {
366+
return false;
367+
}
368+
369+
// d0 of pi
370+
if (std::abs(candBs.impactParameter1()) < cuts->get(pTBin, "d0 Pi")) {
371+
return false;
372+
}
373+
374+
// d0 of Ds
375+
if (std::abs(candBs.impactParameter0()) < cuts->get(pTBin, "d0 Ds")) {
376+
return false;
377+
}
378+
379+
return true;
380+
}
381+
382+
/// Apply PID selection
383+
/// \param pidTrackPi PID status of trackPi (prong1 of Bs candidate)
384+
/// \param acceptPIDNotApplicable switch to accept Status::PIDNotApplicable
385+
/// \return true if prong1 of Bs candidate passes all selections
386+
template <typename T1 = int, typename T2 = bool>
387+
bool selectionPID(const T1& pidTrackPi, const T2& acceptPIDNotApplicable)
388+
{
389+
if (!acceptPIDNotApplicable && pidTrackPi != TrackSelectorPID::Status::PIDAccepted) {
390+
return false;
391+
}
392+
if (acceptPIDNotApplicable && pidTrackPi == TrackSelectorPID::Status::PIDRejected) {
393+
return false;
394+
}
395+
396+
return true;
397+
}
398+
399+
} // namespace hf_sel_candidate_bs
400+
DECLARE_SOA_TABLE(HfSelBsToDsPi, "AOD", "HFSELBS", //!
401+
hf_sel_candidate_bs::IsSelBsToDsPi);
402+
299403
namespace hf_sel_candidate_bplus
300404
{
301405
DECLARE_SOA_COLUMN(IsSelBplusToD0Pi, isSelBplusToD0Pi, int); //!

PWGHF/TableProducer/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ o2physics_add_dpl_workflow(candidate-creator-b0
3838
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter
3939
COMPONENT_NAME Analysis)
4040

41+
o2physics_add_dpl_workflow(candidate-creator-bs
42+
SOURCES candidateCreatorBs.cxx
43+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter
44+
COMPONENT_NAME Analysis)
45+
4146
o2physics_add_dpl_workflow(candidate-creator-bplus
4247
SOURCES candidateCreatorBplus.cxx
4348
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter
@@ -80,6 +85,11 @@ o2physics_add_dpl_workflow(candidate-selector-b0-to-d-pi
8085
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
8186
COMPONENT_NAME Analysis)
8287

88+
o2physics_add_dpl_workflow(candidate-selector-bs-to-ds-pi
89+
SOURCES candidateSelectorBsToDsPi.cxx
90+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
91+
COMPONENT_NAME Analysis)
92+
8393
o2physics_add_dpl_workflow(candidate-selector-bplus-to-d0-pi
8494
SOURCES candidateSelectorBplusToD0Pi.cxx
8595
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore

0 commit comments

Comments
 (0)