Skip to content

Commit d33577d

Browse files
PWGHF: Jpsi to e+e- task and candidate selection for HF (#5085)
1 parent 257a822 commit d33577d

File tree

7 files changed

+424
-2
lines changed

7 files changed

+424
-2
lines changed

Analysis/DataModel/include/AnalysisDataModel/HFCandidateSelectionTables.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@ DECLARE_SOA_COLUMN(IsSelLcpiKp, isSelLcpiKp, int);
3131
DECLARE_SOA_TABLE(HFSelLcCandidate, "AOD", "HFSELLCCAND", hf_selcandidate_lc::IsSelLcpKpi, hf_selcandidate_lc::IsSelLcpiKp);
3232
} // namespace o2::aod
3333

34+
namespace o2::aod
35+
{
36+
namespace hf_selcandidate_jpsi
37+
{
38+
DECLARE_SOA_COLUMN(IsSelJpsiToEE, isSelJpsiToEE, int);
39+
} // namespace hf_selcandidate_jpsi
40+
DECLARE_SOA_TABLE(HFSelJpsiToEECandidate, "AOD", "HFSELJPSICAND", hf_selcandidate_jpsi::IsSelJpsiToEE);
41+
} // namespace o2::aod
3442
#endif // O2_ANALYSIS_HFCANDIDATESELECTIONTABLES_H_

Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,31 @@ auto CosThetaStarD0bar(const T& candidate)
204204
{
205205
return candidate.cosThetaStar(array{RecoDecay::getMassPDG(kKPlus), RecoDecay::getMassPDG(kPiPlus)}, RecoDecay::getMassPDG(421), 0);
206206
}
207+
208+
// Jpsi → e+e-
209+
template <typename T>
210+
auto CtJpsi(const T& candidate)
211+
{
212+
return candidate.ct(RecoDecay::getMassPDG(443));
213+
}
214+
215+
template <typename T>
216+
auto YJpsi(const T& candidate)
217+
{
218+
return candidate.y(RecoDecay::getMassPDG(443));
219+
}
220+
221+
template <typename T>
222+
auto EJpsi(const T& candidate)
223+
{
224+
return candidate.e(RecoDecay::getMassPDG(443));
225+
}
226+
227+
template <typename T>
228+
auto InvMassJpsiToEE(const T& candidate)
229+
{
230+
return candidate.m(array{RecoDecay::getMassPDG(kElectron), RecoDecay::getMassPDG(kElectron)});
231+
}
207232
} // namespace hf_cand_prong2
208233

209234
// general columns

Analysis/Tasks/PWGHF/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ o2_add_dpl_workflow(hf-lc-candidate-selector
4848
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
4949
COMPONENT_NAME Analysis)
5050

51+
o2_add_dpl_workflow(hf-jpsi-toee-candidate-selector
52+
SOURCES HFJpsiToEECandidateSelector.cxx
53+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
54+
COMPONENT_NAME Analysis)
55+
5156
o2_add_dpl_workflow(hf-task-d0
5257
SOURCES taskD0.cxx
5358
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
@@ -62,3 +67,8 @@ o2_add_dpl_workflow(hf-task-lc
6267
SOURCES taskLc.cxx
6368
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
6469
COMPONENT_NAME Analysis)
70+
71+
o2_add_dpl_workflow(hf-task-jpsi
72+
SOURCES taskJpsi.cxx
73+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing
74+
COMPONENT_NAME Analysis)

Analysis/Tasks/PWGHF/HFCandidateCreator2Prong.cxx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@ struct HFCandidateCreator2ProngMC {
162162
if (RecoDecay::getMatchedMCRec(particlesMC, std::move(arrayDaughters), 421, array{+kPiPlus, -kKPlus}, true, &sign) > -1) {
163163
result = sign * D0ToPiK;
164164
}
165+
// Jpsi → e+e-
166+
if (result == N2ProngDecays) {
167+
//Printf("Checking Jpsi → e+e-");
168+
if (RecoDecay::getMatchedMCRec(particlesMC, std::move(arrayDaughters), 443, array{+kElectron, -kElectron}, true, &sign) > -1) {
169+
result = sign * JpsiToEE;
170+
}
171+
}
165172

166173
rowMCMatchRec(result);
167174
}
@@ -176,6 +183,13 @@ struct HFCandidateCreator2ProngMC {
176183
if (RecoDecay::isMatchedMCGen(particlesMC, particle, 421, array{+kPiPlus, -kKPlus}, true, &sign)) {
177184
result = sign * D0ToPiK;
178185
}
186+
// Jpsi → e+e-
187+
if (result == N2ProngDecays) {
188+
//Printf("Checking Jpsi → e+e-");
189+
if (RecoDecay::isMatchedMCGen(particlesMC, particle, 443, array{+kElectron, -kElectron}, true, &sign)) {
190+
result = sign * JpsiToEE;
191+
}
192+
}
179193

180194
rowMCMatchGen(result);
181195
}
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// \file HFJpsiToEECandidateSelector.cxx
12+
/// \brief Jpsi selection task.
13+
/// \author Biao Zhang <biao.zhang@cern.ch>, CCNU
14+
/// \author Nima Zardoshti <nima.zardoshti@cern.ch>, CERN
15+
16+
#include "Framework/runDataProcessing.h"
17+
#include "Framework/AnalysisTask.h"
18+
#include "AnalysisDataModel/HFSecondaryVertex.h"
19+
#include "AnalysisDataModel/HFCandidateSelectionTables.h"
20+
using namespace o2;
21+
using namespace o2::framework;
22+
using namespace o2::aod::hf_cand_prong2;
23+
24+
static const int npTBins = 9;
25+
static const int nCutVars = 4;
26+
//temporary until 2D array in configurable is solved - then move to json
27+
// mass dcaxy dcaz pt_e
28+
constexpr double cuts[npTBins][nCutVars] =
29+
{{0.5, 0.2, 0.4, 1}, /* pt<0.5 */
30+
{0.5, 0.2, 0.4, 1}, /* 0.5<pt<1 */
31+
{0.5, 0.2, 0.4, 1}, /* 1<pt<2 */
32+
{0.5, 0.2, 0.4, 1}, /* 2<pt<3 */
33+
{0.5, 0.2, 0.4, 1}, /* 3<pt<4 */
34+
{0.5, 0.2, 0.4, 1}, /* 4<pt<5 */
35+
{0.5, 0.2, 0.4, 1}, /* 5<pt<7 */
36+
{0.5, 0.2, 0.4, 1}, /* 7<pt<10 */
37+
{0.5, 0.2, 0.4, 1}}; /* 10<pt<15 */
38+
39+
/// Struct for applying Jpsi selection cuts
40+
41+
struct HFJpsiToEECandidateSelector {
42+
43+
Produces<aod::HFSelJpsiToEECandidate> hfSelJpsiToEECandidate;
44+
45+
Configurable<double> d_pTCandMin{"d_pTCandMin", 0., "Lower bound of candidate pT"};
46+
Configurable<double> d_pTCandMax{"d_pTCandMax", 50., "Upper bound of candidate pT"};
47+
48+
Configurable<double> d_pidTPCMinpT{"d_pidTPCMinpT", 0.15, "Lower bound of track pT for TPC PID"};
49+
Configurable<double> d_pidTPCMaxpT{"d_pidTPCMaxpT", 10., "Upper bound of track pT for TPC PID"};
50+
51+
Configurable<double> d_TPCNClsFindablePIDCut{"d_TPCNClsFindablePIDCut", 70., "Lower bound of TPC findable clusters for good PID"};
52+
Configurable<double> d_nSigmaTPC{"d_nSigmaTPC", 3., "Nsigma cut on TPC only"};
53+
54+
/// Gets corresponding pT bin from cut file array
55+
/// \param candpT is the pT of the candidate
56+
/// \return corresponding bin number of array
57+
template <typename T>
58+
int getpTBin(T candpT)
59+
{
60+
double pTBins[npTBins + 1] = {0, 0.5, 1., 2., 3., 4., 5., 7., 10., 15.};
61+
if (candpT < pTBins[0] || candpT >= pTBins[npTBins]) {
62+
return -1;
63+
}
64+
for (int i = 0; i < npTBins; i++) {
65+
if (candpT < pTBins[i + 1]) {
66+
return i;
67+
}
68+
}
69+
return -1;
70+
}
71+
72+
/// Selection on goodness of daughter tracks
73+
/// \note should be applied at candidate selection
74+
/// \param track is daughter track
75+
/// \return true if track is good
76+
template <typename T>
77+
bool daughterSelection(const T& track)
78+
{
79+
if (track.charge() == 0) {
80+
return false;
81+
}
82+
if (track.tpcNClsFound() == 0) {
83+
return false; //is it clusters findable or found - need to check
84+
}
85+
return true;
86+
}
87+
88+
/// Conjugate independent toplogical cuts
89+
/// \param hfCandProng2 is candidate
90+
/// \param trackPositron is the track with the positron hypothesis
91+
/// \param trackElectron is the track with the electron hypothesis
92+
/// \return true if candidate passes all cuts
93+
template <typename T1, typename T2>
94+
bool selectionTopol(const T1& hfCandProng2, const T2& trackPositron, const T2& trackElectron)
95+
{
96+
auto candpT = hfCandProng2.pt();
97+
int pTBin = getpTBin(candpT);
98+
if (pTBin == -1) {
99+
return false;
100+
}
101+
102+
if (candpT < d_pTCandMin || candpT >= d_pTCandMax) {
103+
return false; //check that the candidate pT is within the analysis range
104+
}
105+
106+
if (TMath::Abs(InvMassJpsiToEE(hfCandProng2) - RecoDecay::getMassPDG(443)) > cuts[pTBin][0]) {
107+
return false;
108+
}
109+
110+
if ((trackElectron.pt() < cuts[pTBin][3]) || (trackPositron.pt() < cuts[pTBin][3])) {
111+
return false; //cut on daughter pT
112+
}
113+
if (TMath::Abs(trackElectron.dcaPrim0()) > cuts[pTBin][1] || TMath::Abs(trackPositron.dcaPrim0()) > cuts[pTBin][1]) {
114+
return false; //cut on daughter dca - need to add secondary vertex constraint here
115+
}
116+
if (TMath::Abs(trackElectron.dcaPrim1()) > cuts[pTBin][2] || TMath::Abs(trackPositron.dcaPrim1()) > cuts[pTBin][2]) {
117+
return false; //cut on daughter dca - need to add secondary vertex constraint here
118+
}
119+
120+
return true;
121+
}
122+
123+
/// Check if track is ok for TPC PID
124+
/// \param track is the track
125+
/// \note function to be expanded
126+
/// \return true if track is ok for TPC PID
127+
template <typename T>
128+
bool validTPCPID(const T& track)
129+
{
130+
if (TMath::Abs(track.pt()) < d_pidTPCMinpT || TMath::Abs(track.pt()) >= d_pidTPCMaxpT) {
131+
return false;
132+
}
133+
//if (track.TPCNClsFindable() < d_TPCNClsFindablePIDCut) return false;
134+
return true;
135+
}
136+
137+
/// Check if track is compatible with given TPC Nsigma cut for a given flavour hypothesis
138+
/// \param track is the track
139+
/// \param nPDG is the flavour hypothesis PDG number
140+
/// \param nSigmaCut is the nsigma threshold to test against
141+
/// \note nPDG=11 electron
142+
/// \return true if track satisfies TPC PID hypothesis for given Nsigma cut
143+
template <typename T>
144+
bool selectionPIDTPC(const T& track, int nSigmaCut)
145+
{
146+
return track.tpcNSigmaEl() < nSigmaCut;
147+
}
148+
149+
/// PID selection on daughter track
150+
/// \param track is the daughter track
151+
/// \param nPDG is the PDG code of the flavour hypothesis
152+
/// \note nPDG=11 electron
153+
/// \return 1 if successful PID match, 0 if successful PID rejection, -1 if no PID info
154+
template <typename T>
155+
int selectionPID(const T& track)
156+
{
157+
158+
if (validTPCPID(track)) {
159+
if (!selectionPIDTPC(track, d_nSigmaTPC)) {
160+
161+
return 0; //rejected by PID
162+
} else {
163+
return 1; //positive PID
164+
}
165+
} else {
166+
return -1; //no PID info
167+
}
168+
}
169+
void process(aod::HfCandProng2 const& hfCandProng2s, aod::BigTracksPID const& tracks)
170+
{
171+
172+
for (auto& hfCandProng2 : hfCandProng2s) { //looping over 2 prong candidates
173+
174+
auto trackPos = hfCandProng2.index0_as<aod::BigTracksPID>(); //positive daughter
175+
auto trackNeg = hfCandProng2.index1_as<aod::BigTracksPID>(); //negative daughter
176+
177+
if (!(hfCandProng2.hfflag() & 1 << JpsiToEE)) {
178+
hfSelJpsiToEECandidate(0);
179+
continue;
180+
}
181+
182+
// daughter track validity selection
183+
if (!daughterSelection(trackPos) || !daughterSelection(trackNeg)) {
184+
hfSelJpsiToEECandidate(0);
185+
continue;
186+
}
187+
188+
//implement filter bit 4 cut - should be done before this task at the track selection level
189+
//need to add special cuts (additional cuts on decay length and d0 norm)
190+
191+
if (!selectionTopol(hfCandProng2, trackPos, trackNeg)) {
192+
hfSelJpsiToEECandidate(0);
193+
continue;
194+
}
195+
196+
if (selectionPID(trackPos) == 0 || selectionPID(trackNeg) == 0) {
197+
hfSelJpsiToEECandidate(0);
198+
continue;
199+
}
200+
201+
hfSelJpsiToEECandidate(1);
202+
}
203+
}
204+
};
205+
206+
WorkflowSpec defineDataProcessing(ConfigContext const&)
207+
{
208+
return WorkflowSpec{
209+
adaptAnalysisTask<HFJpsiToEECandidateSelector>("hf-jpsi-toee-candidate-selector")};
210+
}

Analysis/Tasks/PWGHF/HFTrackIndexSkimsCreator.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ struct SelectTracks {
5555

5656
HistogramRegistry registry{
5757
"registry",
58-
{{"hpt_nocuts", "all tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 100.}}}},
58+
{{"hpt_nocuts", "all tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}},
5959
// 2-prong histograms
6060
{"hpt_cuts_2prong", "tracks selected for 2-prong vertexing;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 10.}}}},
6161
{"hdcatoprimxy_cuts_2prong", "tracks selected for 2-prong vertexing;DCAxy to prim. vtx. (cm);entries", {HistType::kTH1F, {{static_cast<int>(1.2 * dcatoprimxymax_2prong * 100), -1.2 * dcatoprimxymax_2prong, 1.2 * dcatoprimxymax_2prong}}}},
@@ -182,7 +182,7 @@ struct HFTrackIndexSkimsCreator {
182182
{"hNCand3Prong", "3-prong candidates preselected;# of candidates;entries", {HistType::kTH1F, {{5000, 0., 500000.}}}},
183183
{"hNCand3ProngVsNTracks", "3-prong candidates preselected;# of selected tracks;# of candidates;entries", {HistType::kTH2F, {{2500, 0., 25000.}, {5000, 0., 500000.}}}},
184184
{"hmassDPlusToPiKPi", "D+ candidates;inv. mass (#pi K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}},
185-
{"hmassLctoPKPi", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}},
185+
{"hmassLcToPKPi", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}},
186186
{"hmassDsToPiKK", "Ds candidates;inv. mass (K K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}}};
187187

188188
Filter filterSelectTracks = (aod::hf_seltrack::isSelProng > 0);

0 commit comments

Comments
 (0)