Skip to content

Commit 7abe6f2

Browse files
committed
Add Bs workflow
1 parent 4fe199a commit 7abe6f2

11 files changed

+1610
-291
lines changed

PWGHF/Core/HfHelper.h

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,12 @@ class HfHelper
663663
return candidate.m(std::array{o2::constants::physics::MassDSBar, o2::constants::physics::MassPiPlus});
664664
}
665665

666+
template <typename T>
667+
auto invMassBsToJPsiPhi(const T& candidate)
668+
{
669+
return candidate.m(std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassKPlus});
670+
}
671+
666672
template <typename T>
667673
auto cosThetaStarBs(const T& candidate)
668674
{
@@ -879,7 +885,7 @@ class HfHelper
879885

880886
// Apply topological cuts as defined in SelectorCuts.h
881887
/// \param candBp B+ candidate
882-
/// \param cuts B+ candidate selection per pT bin"
888+
/// \param cuts B+ candidate selection per pT bin
883889
/// \param binsPt pT bin limits
884890
/// \return true if candidate passes all selections
885891
template <typename T1, typename T2, typename T3>
@@ -1064,6 +1070,114 @@ class HfHelper
10641070
return true;
10651071
}
10661072

1073+
// Apply topological cuts as defined in SelectorCuts.h
1074+
/// \param candBs Bs candidate
1075+
/// \param cuts Bs candidate selection per pT bin
1076+
/// \param binsPt pT bin limits
1077+
/// \return true if candidate passes all selections
1078+
template <typename T1, typename T2, typename T3, typename T4, typename T5>
1079+
bool selectionBsToJPsiPhiTopol(const T1& candBs, const T2& candKa0, const T3& candKa1, const T4& cuts, const T5& binsPt)
1080+
{
1081+
auto ptcandBs = candBs.pt();
1082+
auto mcandBs = invMassBsToJPsiPhi(candBs);
1083+
std::array<float, 3> pVecKa0 = {candKa0.px(), candKa0.py(), candKa0.pz()};
1084+
std::array<float, 3> pVecKa1 = {candKa1.px(), candKa1.py(), candKa1.pz()};
1085+
auto mcandPhi = RecoDecay::m(std::array{pVecKa0, pVecKa1}, std::array{o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus});
1086+
auto ptJPsi = RecoDecay::pt(candBs.pxProng0(), candBs.pyProng0());
1087+
auto candJPsi = candBs.jPsi();
1088+
float pseudoPropDecLen = candBs.decayLengthXY() * mcandBs / ptcandBs;
1089+
1090+
int pTBin = o2::analysis::findBin(binsPt, ptcandBs);
1091+
if (pTBin == -1) {
1092+
return false;
1093+
}
1094+
1095+
// Bs mass cut
1096+
if (std::abs(mcandBs - o2::constants::physics::MassBPlus) > cuts->get(pTBin, "m")) {
1097+
return false;
1098+
}
1099+
1100+
// kaon pt
1101+
if (candKa0.pt() < cuts->get(pTBin, "pT K") &&
1102+
candKa1.pt() < cuts->get(pTBin, "pT K")) {
1103+
return false;
1104+
}
1105+
1106+
// J/Psi pt
1107+
if (ptJPsi < cuts->get(pTBin, "pT J/Psi")) {
1108+
return false;
1109+
}
1110+
1111+
// phi mass
1112+
if (std::abs(mcandPhi - o2::constants::physics::MassPhi) < cuts->get(pTBin, "DeltaM phi")) {
1113+
return false;
1114+
}
1115+
1116+
// J/Psi mass
1117+
if (std::abs(candJPsi.m() - o2::constants::physics::MassJPsi) < cuts->get(pTBin, "DeltaM J/Psi")) {
1118+
return false;
1119+
}
1120+
1121+
// d0(J/Psi)xd0(phi)
1122+
if (candBs.impactParameterProduct() > cuts->get(pTBin, "B Imp. Par. Product")) {
1123+
return false;
1124+
}
1125+
1126+
// Bs Decay length
1127+
if (candBs.decayLength() < cuts->get(pTBin, "B decLen")) {
1128+
return false;
1129+
}
1130+
1131+
// Bs Decay length XY
1132+
if (candBs.decayLengthXY() < cuts->get(pTBin, "B decLenXY")) {
1133+
return false;
1134+
}
1135+
1136+
// Bs CPA cut
1137+
if (candBs.cpa() < cuts->get(pTBin, "CPA")) {
1138+
return false;
1139+
}
1140+
1141+
// Bs CPAXY cut
1142+
if (candBs.cpaXY() < cuts->get(pTBin, "CPAXY")) {
1143+
return false;
1144+
}
1145+
1146+
// d0 of phi
1147+
if (std::abs(candBs.impactParameter1()) < cuts->get(pTBin, "d0 phi")) {
1148+
return false;
1149+
}
1150+
1151+
// d0 of J/Psi
1152+
if (std::abs(candBs.impactParameter0()) < cuts->get(pTBin, "d0 J/Psi")) {
1153+
return false;
1154+
}
1155+
1156+
// B pseudoproper decay length
1157+
if (pseudoPropDecLen < cuts->get(pTBin, "B pseudoprop. decLen")) {
1158+
return false;
1159+
}
1160+
1161+
return true;
1162+
}
1163+
1164+
/// Apply PID selection
1165+
/// \param pidTrackKa PID status of trackKa (prong1 of B+ candidate)
1166+
/// \param acceptPIDNotApplicable switch to accept Status::NotApplicable
1167+
/// \return true if prong1 of B+ candidate passes all selections
1168+
template <typename T1 = int, typename T2 = bool>
1169+
bool selectionBsToJPsiPhiPid(const T1& pidTrackKa, const T2& acceptPIDNotApplicable)
1170+
{
1171+
if (!acceptPIDNotApplicable && pidTrackKa != TrackSelectorPID::Accepted) {
1172+
return false;
1173+
}
1174+
if (acceptPIDNotApplicable && pidTrackKa == TrackSelectorPID::Rejected) {
1175+
return false;
1176+
}
1177+
1178+
return true;
1179+
}
1180+
10671181
/// Apply topological cuts as defined in SelectorCuts.h
10681182
/// \param candLb Lb candidate
10691183
/// \param cuts Lb candidate selection per pT bin"
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file HfMlResponseBsToJPsiPhiReduced.h
13+
/// \brief Class to compute the ML response for Bs0 → J/Psi phi analysis selections in the reduced format
14+
/// \author Fabrizio Chinu <fabrizio.chinu@cern.ch>, Università degli Studi and INFN Torino
15+
16+
#ifndef PWGHF_CORE_HFMLRESPONSEBSTOJPSIPHIREDUCED_H_
17+
#define PWGHF_CORE_HFMLRESPONSEBSTOJPSIPHIREDUCED_H_
18+
19+
#include <map>
20+
#include <string>
21+
#include <vector>
22+
23+
#include "PWGHF/Core/HfMlResponse.h"
24+
#include "PWGHF/D2H/Utils/utilsRedDataFormat.h"
25+
26+
// Fill the map of available input features
27+
// the key is the feature's name (std::string)
28+
// the value is the corresponding value in EnumInputFeatures
29+
#define FILL_MAP_BS(FEATURE) \
30+
{ \
31+
#FEATURE, static_cast<uint8_t>(InputFeaturesBsToJPsiPhiReduced::FEATURE) \
32+
}
33+
34+
// Check if the index of mCachedIndices (index associated to a FEATURE)
35+
// matches the entry in EnumInputFeatures associated to this FEATURE
36+
// if so, the inputFeatures vector is filled with the FEATURE's value
37+
// by calling the corresponding GETTER from OBJECT
38+
#define CHECK_AND_FILL_VEC_BS_FULL(OBJECT, FEATURE, GETTER) \
39+
case static_cast<uint8_t>(InputFeaturesBsToJPsiPhiReduced::FEATURE): { \
40+
inputFeatures.emplace_back(OBJECT.GETTER()); \
41+
break; \
42+
}
43+
44+
// Check if the index of mCachedIndices (index associated to a FEATURE)
45+
// matches the entry in EnumInputFeatures associated to this FEATURE
46+
// if so, the inputFeatures vector is filled with the FEATURE's value
47+
// by calling the GETTER function taking OBJECT in argument
48+
#define CHECK_AND_FILL_VEC_BS_FUNC(OBJECT, FEATURE, GETTER) \
49+
case static_cast<uint8_t>(InputFeaturesBsToJPsiPhiReduced::FEATURE): { \
50+
inputFeatures.emplace_back(GETTER(OBJECT)); \
51+
break; \
52+
}
53+
54+
// Specific case of CHECK_AND_FILL_VEC_BS_FULL(OBJECT, FEATURE, GETTER)
55+
// where OBJECT is named candidate and FEATURE = GETTER
56+
#define CHECK_AND_FILL_VEC_BS(GETTER) \
57+
case static_cast<uint8_t>(InputFeaturesBsToJPsiPhiReduced::GETTER): { \
58+
inputFeatures.emplace_back(candidate.GETTER()); \
59+
break; \
60+
}
61+
62+
namespace o2::analysis
63+
{
64+
65+
enum class InputFeaturesBsToJPsiPhiReduced : uint8_t {
66+
ptProng0 = 0,
67+
ptProng1,
68+
impactParameter0,
69+
impactParameter1,
70+
impactParameterProduct,
71+
chi2PCA,
72+
decayLength,
73+
decayLengthXY,
74+
decayLengthNormalised,
75+
decayLengthXYNormalised,
76+
cpa,
77+
cpaXY,
78+
maxNormalisedDeltaIP,
79+
tpcNSigmaKa0,
80+
tofNSigmaKa0,
81+
tpcTofNSigmaKa0,
82+
tpcNSigmaKa1,
83+
tofNSigmaKa1,
84+
tpcTofNSigmaKa1
85+
};
86+
87+
template <typename TypeOutputScore = float>
88+
class HfMlResponseBsToJPsiPhiReduced : public HfMlResponse<TypeOutputScore>
89+
{
90+
public:
91+
/// Default constructor
92+
HfMlResponseBsToJPsiPhiReduced() = default;
93+
/// Default destructor
94+
virtual ~HfMlResponseBsToJPsiPhiReduced() = default;
95+
96+
/// Method to get the input features vector needed for ML inference
97+
/// \param candidate is the Bs candidate
98+
/// \param prong1 is the candidate's prong1
99+
/// \return inputFeatures vector
100+
template <typename T1, typename T2, typename T3>
101+
std::vector<float> getInputFeatures(T1 const& candidate,
102+
T2 const& prong1,
103+
T3 const& prong2)
104+
{
105+
std::vector<float> inputFeatures;
106+
107+
for (const auto& idx : MlResponse<TypeOutputScore>::mCachedIndices) {
108+
switch (idx) {
109+
CHECK_AND_FILL_VEC_BS(ptProng0);
110+
CHECK_AND_FILL_VEC_BS(ptProng1);
111+
CHECK_AND_FILL_VEC_BS(impactParameter0);
112+
CHECK_AND_FILL_VEC_BS(impactParameter1);
113+
CHECK_AND_FILL_VEC_BS(impactParameterProduct);
114+
CHECK_AND_FILL_VEC_BS(chi2PCA);
115+
CHECK_AND_FILL_VEC_BS(decayLength);
116+
CHECK_AND_FILL_VEC_BS(decayLengthXY);
117+
CHECK_AND_FILL_VEC_BS(decayLengthNormalised);
118+
CHECK_AND_FILL_VEC_BS(decayLengthXYNormalised);
119+
CHECK_AND_FILL_VEC_BS(cpa);
120+
CHECK_AND_FILL_VEC_BS(cpaXY);
121+
CHECK_AND_FILL_VEC_BS(maxNormalisedDeltaIP);
122+
// TPC PID variable
123+
CHECK_AND_FILL_VEC_BS_FULL(prong1, tpcNSigmaKa0, tpcNSigmaKa);
124+
// TOF PID variable
125+
CHECK_AND_FILL_VEC_BS_FULL(prong1, tofNSigmaKa0, tofNSigmaKa);
126+
// Combined PID variables
127+
CHECK_AND_FILL_VEC_BS_FUNC(prong1, tpcTofNSigmaKa0, o2::pid_tpc_tof_utils::getTpcTofNSigmaKa1);
128+
// TPC PID variable
129+
CHECK_AND_FILL_VEC_BS_FULL(prong2, tpcNSigmaKa1, tpcNSigmaKa);
130+
// TOF PID variable
131+
CHECK_AND_FILL_VEC_BS_FULL(prong2, tofNSigmaKa1, tofNSigmaKa);
132+
// Combined PID variables
133+
CHECK_AND_FILL_VEC_BS_FUNC(prong2, tpcTofNSigmaKa1, o2::pid_tpc_tof_utils::getTpcTofNSigmaKa1);
134+
}
135+
}
136+
137+
return inputFeatures;
138+
}
139+
140+
protected:
141+
/// Method to fill the map of available input features
142+
void setAvailableInputFeatures()
143+
{
144+
MlResponse<TypeOutputScore>::mAvailableInputFeatures = {
145+
FILL_MAP_BS(ptProng0),
146+
FILL_MAP_BS(ptProng1),
147+
FILL_MAP_BS(impactParameter0),
148+
FILL_MAP_BS(impactParameter1),
149+
FILL_MAP_BS(impactParameterProduct),
150+
FILL_MAP_BS(chi2PCA),
151+
FILL_MAP_BS(decayLength),
152+
FILL_MAP_BS(decayLengthXY),
153+
FILL_MAP_BS(decayLengthNormalised),
154+
FILL_MAP_BS(decayLengthXYNormalised),
155+
FILL_MAP_BS(cpa),
156+
FILL_MAP_BS(cpaXY),
157+
FILL_MAP_BS(maxNormalisedDeltaIP),
158+
// TPC PID variable
159+
FILL_MAP_BS(tpcNSigmaKa0),
160+
// TOF PID variable
161+
FILL_MAP_BS(tofNSigmaKa0),
162+
// Combined PID variable
163+
FILL_MAP_BS(tpcTofNSigmaKa0),
164+
// TPC PID variable
165+
FILL_MAP_BS(tpcNSigmaKa1),
166+
// TOF PID variable
167+
FILL_MAP_BS(tofNSigmaKa1),
168+
// Combined PID variable
169+
FILL_MAP_BS(tpcTofNSigmaKa1)};
170+
}
171+
};
172+
173+
} // namespace o2::analysis
174+
175+
#undef FILL_MAP_BS
176+
#undef CHECK_AND_FILL_VEC_BS_FULL
177+
#undef CHECK_AND_FILL_VEC_BS_FUNC
178+
#undef CHECK_AND_FILL_VEC_BS
179+
180+
#endif // PWGHF_CORE_HFMLRESPONSEBSTOJPSIPHIREDUCED_H_

PWGHF/Core/SelectorCuts.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,62 @@ static const std::vector<std::string> labelsPt = {
10501050
static const std::vector<std::string> labelsCutVar = {"m", "CPA", "Chi2PCA", "d0 Ds", "d0 Pi", "pT Ds", "pT Pi", "Bs decLen", "Bs decLenXY", "Imp. Par. Product"};
10511051
} // namespace hf_cuts_bs_to_ds_pi
10521052

1053+
namespace hf_cuts_bs_to_jpsi_phi
1054+
{
1055+
static constexpr int NBinsPt = 12;
1056+
static constexpr int NCutVars = 13;
1057+
// default values for the pT bin edges (can be used to configure histogram axis)
1058+
// offset by 1 from the bin numbers in cuts array
1059+
constexpr double BinsPt[NBinsPt + 1] = {
1060+
0,
1061+
0.5,
1062+
1.0,
1063+
2.0,
1064+
3.0,
1065+
4.0,
1066+
5.0,
1067+
7.0,
1068+
10.0,
1069+
13.0,
1070+
16.0,
1071+
20.0,
1072+
24.0};
1073+
1074+
auto vecBinsPt = std::vector<double>{BinsPt, BinsPt + NBinsPt + 1};
1075+
1076+
// default values for the cuts
1077+
// DeltaM CPA d0JPsi d0K pTJPsi pTK BDecayLength BDecayLengthXY BIPProd DeltaMJPsi JPsiIPProd
1078+
constexpr double Cuts[NBinsPt][NCutVars] = {{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 0 < pt < 0.5 */
1079+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 0.5 < pt < 1 */
1080+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 1 < pt < 2 */
1081+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 2 < pt < 3 */
1082+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 3 < pt < 4 */
1083+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 4 < pt < 5 */
1084+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 5 < pt < 7 */
1085+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 7 < pt < 10 */
1086+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 10 < pt < 13 */
1087+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 13 < pt < 16 */
1088+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 16 < pt < 20 */
1089+
{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}}; /* 20 < pt < 24 */
1090+
// row labels
1091+
static const std::vector<std::string> labelsPt = {
1092+
"pT bin 0",
1093+
"pT bin 1",
1094+
"pT bin 2",
1095+
"pT bin 3",
1096+
"pT bin 4",
1097+
"pT bin 5",
1098+
"pT bin 6",
1099+
"pT bin 7",
1100+
"pT bin 8",
1101+
"pT bin 9",
1102+
"pT bin 10",
1103+
"pT bin 11"};
1104+
1105+
// column labels
1106+
static const std::vector<std::string> labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi", "d0 phi", "pT J/Psi", "pT K", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "DeltaM phi", "B pseudoprop. decLen"};
1107+
} // namespace hf_cuts_bs_to_jpsi_phi
1108+
10531109
namespace hf_cuts_bplus_to_d0_pi
10541110
{
10551111
static constexpr int NBinsPt = 12;

PWGHF/D2H/DataModel/ReducedDataModel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ DECLARE_SOA_TABLE(HfRedBsDsMls, "AOD", "HFREDBSDSML", //! Table with ML scores f
722722
o2::soa::Marker<1>);
723723

724724
using HfRedCandBs = soa::Join<HfCandBsExt, HfRedBsProngs>;
725+
using HfRedCandBsToJPsiPhi = soa::Join<HfCandBsExt, HfRedBs2JPsiDaus>;
725726

726727
namespace hf_cand_lb_reduced
727728
{

0 commit comments

Comments
 (0)