Skip to content

Commit 0cdb22b

Browse files
committed
[PWGHF] test pp channel for eta_c
1 parent 3f1700f commit 0cdb22b

File tree

5 files changed

+487
-0
lines changed

5 files changed

+487
-0
lines changed

PWGHF/D2H/DataModel/ReducedDataModel.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ DECLARE_SOA_COLUMN(TpcNClsCrossedRowsProngMin, tpcNClsCrossedRowsProngMin, int);
196196
DECLARE_SOA_COLUMN(TpcChi2NClProngMax, tpcChi2NClProngMax, float); //! maximum value of TPC chi2 for the decay daughter tracks
197197
DECLARE_SOA_COLUMN(PtProngMin, ptProngMin, float); //! minimum value of transverse momentum for the decay daughter tracks
198198
DECLARE_SOA_COLUMN(AbsEtaProngMin, absEtaProngMin, float); //! minimum value of absolute pseudorapidity for the decay daughter tracks
199+
DECLARE_SOA_COLUMN(TrackType, trackType, uint8_t); //! particle type according to PID selection (pion, kaon, proton)
199200

200201
// dynamic columns
201202
DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! transverse momentum
@@ -1653,6 +1654,19 @@ DECLARE_SOA_TABLE(HfMcRecRedResos, "AOD", "HFMCRECREDRESO", //! Reconstruction-l
16531654
hf_reso_cand_reduced::InvMassGen,
16541655
hf_cand_mc_flag::NTracksDecayed,
16551656
o2::soa::Marker<1>);
1657+
1658+
//! Table with selected tracks for Hc analysis
1659+
DECLARE_SOA_TABLE(HcSelTracks, "AOD", "HCSELTRACKS",
1660+
o2::soa::Index<>,
1661+
// Indices
1662+
hf_track_index_reduced::TrackId,
1663+
hf_track_index_reduced::HfRedCollisionId,
1664+
// Static
1665+
hf_track_vars_reduced::Px,
1666+
hf_track_vars_reduced::Py,
1667+
hf_track_vars_reduced::Pz,
1668+
hf_track_vars_reduced::Sign,
1669+
hf_track_vars_reduced::TrackType);
16561670
} // namespace aod
16571671

16581672
namespace soa

PWGHF/D2H/TableProducer/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ o2physics_add_dpl_workflow(data-creator-jpsi-had-reduced
9090
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils
9191
COMPONENT_NAME Analysis)
9292

93+
o2physics_add_dpl_workflow(data-creator-hidden-charm-reduced
94+
SOURCES dataCreatorHiddenCharmReduced.cxx
95+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils
96+
COMPONENT_NAME Analysis)
97+
9398
# Converters
9499

95100
o2physics_add_dpl_workflow(converter-reduced-3-prongs-ml
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
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 dataCreatorHiddenCharmReduced.cxx
13+
/// \brief Reduced data creator for hidden-charm analyses at midrapidity
14+
///
15+
/// \author A. Palasciano, <antonio.palasciano@cern.ch>, INFN Bari
16+
/// \author S. Politanò <stefano.politano@cern.ch>, CERN
17+
18+
#include "PWGHF/Core/CentralityEstimation.h"
19+
#include "PWGHF/Core/SelectorCuts.h"
20+
#include "PWGHF/D2H/DataModel/ReducedDataModel.h"
21+
#include "PWGHF/D2H/Utils/utilsRedDataFormat.h"
22+
#include "PWGHF/DataModel/AliasTables.h"
23+
#include "PWGHF/DataModel/CandidateSelectionTables.h"
24+
#include "PWGHF/DataModel/TrackIndexSkimmingTables.h"
25+
#include "PWGHF/Utils/utilsAnalysis.h"
26+
#include "PWGHF/Utils/utilsBfieldCCDB.h"
27+
#include "PWGHF/Utils/utilsEvSelHf.h"
28+
29+
#include "Common/Core/TPCVDriftManager.h"
30+
#include "Common/Core/ZorroSummary.h"
31+
#include "Common/DataModel/Centrality.h"
32+
#include "Common/DataModel/CollisionAssociationTables.h"
33+
#include "Common/DataModel/EventSelection.h"
34+
#include "Common/DataModel/PIDResponseTOF.h"
35+
#include "Common/DataModel/PIDResponseTPC.h"
36+
#include "Common/DataModel/TrackSelectionTables.h"
37+
38+
#include <CCDB/BasicCCDBManager.h>
39+
#include <CCDB/CcdbApi.h>
40+
#include <DetectorsBase/MatLayerCylSet.h>
41+
#include <DetectorsBase/Propagator.h>
42+
#include <Framework/AnalysisDataModel.h>
43+
#include <Framework/AnalysisTask.h>
44+
#include <Framework/Configurable.h>
45+
#include <Framework/DeviceSpec.h>
46+
#include <Framework/HistogramRegistry.h>
47+
#include <Framework/HistogramSpec.h>
48+
#include <Framework/InitContext.h>
49+
#include <Framework/Logger.h>
50+
#include <Framework/runDataProcessing.h>
51+
52+
#include <array>
53+
#include <cmath>
54+
#include <numeric>
55+
#include <string>
56+
#include <vector>
57+
58+
using namespace o2;
59+
using namespace o2::analysis;
60+
using namespace o2::aod;
61+
using namespace o2::framework;
62+
using namespace o2::framework::expressions;
63+
using namespace o2::hf_centrality;
64+
65+
enum TrackType : uint8_t {
66+
Pion = 0,
67+
Kaon,
68+
Proton
69+
};
70+
71+
struct HfDataCreatorHiddenCharmReduced {
72+
73+
Produces<aod::HfRedCollisions> hfReducedCollision;
74+
Produces<aod::HfOrigColCounts> hfCollisionCounter;
75+
Produces<aod::HcSelTracks> hfTrackLite;
76+
77+
struct : ConfigurableGroup {
78+
// track quality
79+
Configurable<bool> fillHistograms{"fillHistograms", true, "Fill proton QA histograms"};
80+
Configurable<bool> selectProtons{"selectProtons", true, "Select protons"};
81+
Configurable<int> itsNClsMin{"itsNClsMin", 5, "Minimum number of ITS clusters"};
82+
Configurable<int> tpcNClsFoundMin{"tpcNClsFoundMin", 50, "Minimum number of found TPC clusters"};
83+
Configurable<int> tpcNClsCrossedRowsMin{"tpcNClsCrossedRowsMin", 80, "Minimum number of crossed TPC rows"};
84+
Configurable<double> ptMinTrack{"ptMinTrack", 0.5, "Minimum proton-track pT"};
85+
Configurable<double> etaMaxTrack{"etaMaxTrack", 0.8, "Maximum proton-track |eta|"};
86+
Configurable<float> momForCombinedPid{"momForCombinedPid", 0.75f, "Momentum threshold above which combined TPC+TOF proton PID is used"};
87+
Configurable<std::vector<double>> binsPtTrack{"binsPtTrack", std::vector<double>{hf_cuts_single_track::vecBinsPtTrack}, "Track pT bin limits for DCA cuts"};
88+
Configurable<LabeledArray<double>> cutsTrack{"cutsTrack", {hf_cuts_single_track::CutsTrack[0], hf_cuts_single_track::NBinsPtTrack, hf_cuts_single_track::NCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track DCA selections per pT bin"};
89+
Configurable<float> maxNsigmaTofPi{"maxNsigmaTofPi", 2.f, "Maximum pion n-sigma in TOF for proton rejection"};
90+
Configurable<float> maxNsigmaTofKa{"maxNsigmaTofKa", 2.f, "Maximum kaon n-sigma in TOF for proton rejection"};
91+
Configurable<float> maxNsigmaCombinedPr{"maxNsigmaCombinedPr", 3.f, "Maximum combined proton n-sigma from TPC and TOF"};
92+
Configurable<float> maxNsigmaTpcPi{"maxNsigmaTpcPi", 2.f, "Maximum pion n-sigma in TPC for proton rejection"};
93+
Configurable<float> maxNsigmaTpcKa{"maxNsigmaTpcKa", 2.f, "Maximum kaon n-sigma in TPC for proton rejection"};
94+
Configurable<float> maxNsigmaTpcPr{"maxNsigmaTpcPr", 3.f, "Maximum proton n-sigma in TPC"};
95+
Configurable<bool> forceTOF{"forceTOF", false, "Require TOF PID information for proton selection"};
96+
} config;
97+
98+
// Configurable (others)
99+
Configurable<std::string> ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
100+
Configurable<std::string> ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"};
101+
Configurable<bool> doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"};
102+
Configurable<bool> rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"};
103+
Configurable<bool> rejectCollisionsWithBadEvSel{"rejectCollisionsWithBadEvSel", true, "flag to reject collisions with bad event selection"};
104+
105+
o2::hf_evsel::HfEventSelection hfEvSel;
106+
o2::hf_evsel::HfEventSelectionMc hfEvSelMc;
107+
108+
double bz{0.};
109+
int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc.
110+
111+
// material correction for track propagation
112+
o2::base::MatLayerCylSet* lut{};
113+
o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT;
114+
o2::aod::common::TPCVDriftManager vDriftMgr;
115+
o2::ccdb::CcdbApi ccdbApi;
116+
Service<o2::ccdb::BasicCCDBManager> ccdb{};
117+
118+
using BCsInfo = soa::Join<aod::BCs, aod::Timestamps, aod::BcSels>;
119+
using TracksWithPID = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>;
120+
121+
Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
122+
123+
HistogramRegistry registry{"registry"};
124+
OutputObj<ZorroSummary> zorroSummary{"zorroSummary"};
125+
126+
void init(InitContext& initContext)
127+
{
128+
// Configure CCDB access
129+
ccdb->setURL(ccdbUrl.value);
130+
ccdb->setCaching(true);
131+
ccdb->setLocalObjectValidityChecking();
132+
ccdb->setCreatedNotAfter(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
133+
ccdbApi.init(ccdbUrl);
134+
runNumber = 0;
135+
lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get<o2::base::MatLayerCylSet>("GLO/Param/MatLUT"));
136+
137+
if (config.fillHistograms) {
138+
const AxisSpec axisPt{360, 0., 36., "#it{p}_{T}^{proton} (GeV/#it{c})"};
139+
const AxisSpec axisEta{100, -1., 1., "#eta"};
140+
const AxisSpec axisDca{400, -2., 2., "DCA_{xy} to primary vertex (cm)"};
141+
const AxisSpec axisNSigma{100, -5., 5., "n#sigma"};
142+
143+
registry.add("hPzVtx", "Z position of primary vertex for selected tracks;z_{vtx} (cm);entries", {HistType::kTH1D, {AxisSpec{200, -20., 20., "z_{vtx} (cm)"}}});
144+
registry.add("hPtNoCuts", "All associated tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1D, {axisPt}});
145+
registry.add("hPtCutsProton", "Selected proton tracks;#it{p}_{T}^{track} (GeV/#it{c});entries", {HistType::kTH1D, {axisPt}});
146+
registry.add("hEtaCutsProton", "Selected proton tracks;#eta;entries", {HistType::kTH1D, {axisEta}});
147+
registry.add("hDCAToPrimXYVsPtCutsProton", "Selected proton tracks;#it{p}_{T}^{track} (GeV/#it{c});DCA_{xy} to primary vertex (cm)", {HistType::kTH2D, {axisPt, axisDca}});
148+
registry.add("hNSigmaTPCProton", "Selected proton tracks;#it{p}_{T}^{track} (GeV/#it{c});n#sigma_{TPC}", {HistType::kTH2D, {axisPt, axisNSigma}});
149+
registry.add("hNSigmaTOFProton", "Selected proton tracks;#it{p}_{T}^{track} (GeV/#it{c});n#sigma_{TOF}", {HistType::kTH2D, {axisPt, axisNSigma}});
150+
registry.add("hInvMass", "Invariant mass of selected proton with all other tracks in the event;#it{p}_{T}^{proton} (GeV/#it{c});invariant mass with other tracks (GeV/#it{c}^{2})", {HistType::kTH2D, {axisPt, AxisSpec{100, 2.85, 3.25, "invariant mass with other tracks (GeV/#it{c}^{2})"}}});
151+
}
152+
153+
// init HF event selection helper
154+
hfEvSel.init(registry, &zorroSummary);
155+
156+
const auto& workflows = initContext.services().get<RunningWorkflowInfo const>();
157+
for (const DeviceSpec& device : workflows.devices) {
158+
if (device.name == "hf-data-creator-charm-reso-to-d0-reduced") {
159+
// init HF event selection helper
160+
hfEvSelMc.init(device, registry);
161+
break;
162+
}
163+
}
164+
}
165+
166+
template <typename TTrack>
167+
bool isSelectedPid(TTrack const& track) const
168+
{
169+
const float momForCombinedPid = config.momForCombinedPid.value;
170+
const float maxNsigmaTpcPr = config.maxNsigmaTpcPr.value;
171+
const float maxNsigmaTpcPi = config.maxNsigmaTpcPi.value;
172+
const float maxNsigmaTpcKa = config.maxNsigmaTpcKa.value;
173+
const float maxNsigmaCombinedPr = config.maxNsigmaCombinedPr.value;
174+
const float maxNsigmaTofPi = config.maxNsigmaTofPi.value;
175+
const float maxNsigmaTofKa = config.maxNsigmaTofKa.value;
176+
const bool forceTOF = config.forceTOF.value;
177+
178+
const float mom = std::hypot(track.px(), track.py(), track.pz());
179+
const float nSigmaTPCPr = track.tpcNSigmaPr();
180+
const float nSigmaTPCPi = track.tpcNSigmaPi();
181+
const float nSigmaTPCKa = track.tpcNSigmaKa();
182+
const bool hasTOF = track.hasTOF();
183+
if (!hasTOF && forceTOF) {
184+
return false;
185+
}
186+
187+
bool isProton = false;
188+
bool rejectAsPion = false;
189+
bool rejectAsKaon = false;
190+
191+
if (mom < momForCombinedPid || !hasTOF) {
192+
isProton = std::abs(nSigmaTPCPr) < maxNsigmaTpcPr;
193+
rejectAsPion = std::abs(nSigmaTPCPi) < maxNsigmaTpcPi;
194+
rejectAsKaon = std::abs(nSigmaTPCKa) < maxNsigmaTpcKa;
195+
} else {
196+
const float nSigmaTOFPr = track.tofNSigmaPr();
197+
const float nSigmaTOFPi = track.tofNSigmaPi();
198+
const float nSigmaTOFKa = track.tofNSigmaKa();
199+
isProton = std::hypot(nSigmaTPCPr, nSigmaTOFPr) < maxNsigmaCombinedPr;
200+
rejectAsPion = std::hypot(nSigmaTPCPi, nSigmaTOFPi) < maxNsigmaTofPi;
201+
rejectAsKaon = std::hypot(nSigmaTPCKa, nSigmaTOFKa) < maxNsigmaTofKa;
202+
}
203+
return isProton && !rejectAsPion && !rejectAsKaon;
204+
}
205+
206+
template <typename TTrack>
207+
bool isSelectedTrack(TTrack const& track) const
208+
{
209+
const int tpcNClsFoundMin = config.tpcNClsFoundMin.value;
210+
const int tpcNClsCrossedRowsMin = config.tpcNClsCrossedRowsMin.value;
211+
const int itsNClsMin = config.itsNClsMin.value;
212+
const double etaMaxTrack = config.etaMaxTrack.value;
213+
const double ptMinTrack = config.ptMinTrack.value;
214+
215+
if (!track.isGlobalTrackWoDCA()) {
216+
return false;
217+
}
218+
if (track.tpcNClsFound() < tpcNClsFoundMin) {
219+
return false;
220+
}
221+
if (track.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) {
222+
return false;
223+
}
224+
if (track.itsNCls() < itsNClsMin) {
225+
return false;
226+
}
227+
if (std::abs(track.eta()) > etaMaxTrack) {
228+
return false;
229+
}
230+
if (track.pt() < ptMinTrack) {
231+
return false;
232+
}
233+
if (!isSelectedTrackDca(config.binsPtTrack, config.cutsTrack, track.pt(), track.dcaXY(), track.dcaZ())) {
234+
return false;
235+
}
236+
return isSelectedPid(track);
237+
}
238+
239+
void processEtaCTrack(soa::Join<aod::Collisions, aod::EvSels> const& collisions,
240+
aod::TrackAssoc const& trackIndices,
241+
TracksWithPID const& tracks,
242+
aod::BCsWithTimestamps const&)
243+
{
244+
hfTrackLite.reserve(tracks.size());
245+
246+
int zvtxColl{0};
247+
int sel8Coll{0};
248+
int zvtxAndSel8Coll{0};
249+
int zvtxAndSel8CollAndSoftTrig{0};
250+
int allSelColl{0};
251+
constexpr int NDaughtersCharmMeson = 2;
252+
for (const auto& collision : collisions) {
253+
const auto hfRejMap = o2::hf_evsel::getEvSel<true, o2::hf_centrality::CentralityEstimator::None, aod::BCsWithTimestamps>(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry);
254+
if (rejectCollisionsWithBadEvSel && hfRejMap != 0) {
255+
continue;
256+
}
257+
const auto thisCollId = collision.globalIndex();
258+
const auto trackIds = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId);
259+
if (config.fillHistograms) {
260+
registry.fill(HIST("hPzVtx"), collision.posZ());
261+
}
262+
std::vector<int> selectedTrackIds;
263+
for (const auto& trkId : trackIds) {
264+
auto trk = trkId.track_as<TracksWithPID>();
265+
if (config.fillHistograms) {
266+
registry.fill(HIST("hPtNoCuts"), trk.pt());
267+
}
268+
if (!isSelectedTrack(trk)) {
269+
continue;
270+
}
271+
std::array pVecProton{trk.pVector()};
272+
hfTrackLite(trk.globalIndex(), collision.globalIndex(), pVecProton[0], pVecProton[1], pVecProton[2], trk.sign(), static_cast<uint8_t>(TrackType::Proton));
273+
selectedTrackIds.push_back(trk.globalIndex());
274+
if (config.fillHistograms) {
275+
registry.fill(HIST("hPtCutsProton"), trk.pt());
276+
registry.fill(HIST("hEtaCutsProton"), trk.eta());
277+
registry.fill(HIST("hDCAToPrimXYVsPtCutsProton"), trk.pt(), trk.dcaXY());
278+
registry.fill(HIST("hNSigmaTPCProton"), trk.pt(), trk.tpcNSigmaPr());
279+
if (trk.hasTOF()) {
280+
registry.fill(HIST("hNSigmaTOFProton"), trk.pt(), trk.tofNSigmaPr());
281+
}
282+
}
283+
}
284+
if (selectedTrackIds.size() < nDaughtersCharmMeson) {
285+
continue;
286+
}
287+
hfReducedCollision(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz);
288+
for (size_t i = 0; i < selectedTrackIds.size(); ++i) {
289+
auto t1 = tracks.rawIteratorAt(selectedTrackIds[i]);
290+
std::array pVec1{t1.pVector()};
291+
for (size_t j = i + 1; j < selectedTrackIds.size(); ++j) {
292+
auto t2 = tracks.rawIteratorAt(selectedTrackIds[j]);
293+
if (t1.sign() * t2.sign() > 0) {
294+
continue;
295+
}
296+
std::array pVec2{t2.pVector()};
297+
float invMass = RecoDecay::m(std::array{pVec1, pVec2}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassProton});
298+
float ptEtac = RecoDecay::pt(RecoDecay::sumOfVec(pVec1, pVec2));
299+
if (config.fillHistograms) {
300+
registry.fill(HIST("hInvMass"), ptEtac, invMass);
301+
}
302+
}
303+
}
304+
}
305+
hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl);
306+
}
307+
308+
PROCESS_SWITCH(HfDataCreatorHiddenCharmReduced, processEtaCTrack, "EtaC -> p pbar reconstruction", true);
309+
};
310+
311+
// struct
312+
313+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
314+
{
315+
WorkflowSpec workflow{};
316+
workflow.push_back(adaptAnalysisTask<HfDataCreatorHiddenCharmReduced>(cfgc));
317+
return workflow;
318+
}

PWGHF/D2H/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,8 @@ o2physics_add_dpl_workflow(task-xic0-to-xi-pi
153153
SOURCES taskXic0ToXiPi.cxx
154154
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
155155
COMPONENT_NAME Analysis)
156+
157+
o2physics_add_dpl_workflow(task-hidden-charm
158+
SOURCES taskHiddenCharm.cxx
159+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
160+
COMPONENT_NAME Analysis)

0 commit comments

Comments
 (0)