Skip to content

Commit 11f25f9

Browse files
authored
[PWGLF,Tutorial] Add LambdaMass to Resonance Table and New Table Combination Tutorial (#8986)
1 parent ec478c6 commit 11f25f9

File tree

5 files changed

+201
-0
lines changed

5 files changed

+201
-0
lines changed

PWGLF/DataModel/LFResonanceTables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ DECLARE_SOA_TABLE(ResoCascades, "AOD", "RESOCASCADES",
370370
cascdata::DCAXYCascToPV,
371371
cascdata::DCAZCascToPV,
372372
cascdata::Sign,
373+
resodaughter::MLambda,
373374
resodaughter::MXi,
374375
resodaughter::TransRadius,
375376
resodaughter::CascTransRadius,

PWGLF/TableProducer/Resonances/resonanceInitializer.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ struct ResonanceInitializer {
593593
casc.dcaXYCascToPV(),
594594
casc.dcaZCascToPV(),
595595
casc.sign(),
596+
casc.mLambda(),
596597
casc.mXi(),
597598
casc.v0radius(), casc.cascradius(), casc.x(), casc.y(), casc.z());
598599
if constexpr (isMC) {

PWGLF/TableProducer/Resonances/resonanceModuleInitializer.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ struct ResonanceDaughterInitializer {
10551055
casc.dcaXYCascToPV(),
10561056
casc.dcaZCascToPV(),
10571057
casc.sign(),
1058+
casc.mLambda(),
10581059
casc.mXi(),
10591060
casc.v0radius(), casc.cascradius(), casc.x(), casc.y(), casc.z());
10601061
if constexpr (isMC) {

Tutorials/PWGLF/Resonance/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,8 @@ o2physics_add_dpl_workflow(resonances-step6
4444
SOURCES resonances_step6.cxx
4545
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
4646
COMPONENT_NAME AnalysisTutorial)
47+
48+
o2physics_add_dpl_workflow(resonances-combine
49+
SOURCES resonancesCombine.cxx
50+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
51+
COMPONENT_NAME AnalysisTutorial)
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
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 resonancesCombine.cxx
13+
/// \brief Resonance combination tutorial
14+
/// \author Bong-Hwi Lim <bong-hwi.lim@cern.ch>
15+
/// \since 13/12/2024
16+
17+
#include <TLorentzVector.h>
18+
#include <TPDGCode.h>
19+
20+
#include "CommonConstants/PhysicsConstants.h"
21+
#include "Common/DataModel/Qvectors.h"
22+
#include "Common/Core/EventPlaneHelper.h"
23+
#include "Framework/AnalysisTask.h"
24+
#include "Framework/ASoAHelpers.h"
25+
#include "Framework/runDataProcessing.h"
26+
#include "PWGLF/DataModel/LFResonanceTables.h"
27+
28+
using namespace o2;
29+
using namespace o2::framework;
30+
using namespace o2::framework::expressions;
31+
32+
// Extract STEP
33+
// Combine Resonance tables into other O2 tables
34+
struct ResonanceCombine {
35+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
36+
37+
// Configurable for number of bins
38+
Configurable<int> nBins{"nBins", 100, "N bins in all histos"};
39+
// Configurable for min pT cut
40+
Configurable<double> cMinPtcut{"cMinPtcut", 0.15, "Track minium pt cut"};
41+
// Configurable for event plane
42+
Configurable<int> cfgEvtPl{"cfgEvtPl", 40500, "Configuration of three subsystems for the event plane and its resolution, 10000*RefA + 100*RefB + S, where FT0C:0, FT0A:1, FT0M:2, FV0A:3, BPos:5, BNeg:6"};
43+
44+
// Track selection
45+
// primary track condition
46+
Configurable<bool> cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"};
47+
Configurable<bool> cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"};
48+
Configurable<bool> cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"};
49+
// DCA Selections
50+
// DCAr to PV
51+
Configurable<double> cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"};
52+
// DCAz to PV
53+
Configurable<double> cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"};
54+
Configurable<double> cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"};
55+
56+
// PID selection
57+
Configurable<float> nSigmaCutTPC{"nSigmaCutTPC", 3.0, "Value of the TPC Nsigma cut"};
58+
Configurable<float> nSigmaCutTOF{"nSigmaCutTOF", 3.0, "Value of the TOF Nsigma cut"};
59+
60+
double massKa = o2::constants::physics::MassKPlus;
61+
62+
EventPlaneHelper helperEP;
63+
int evtPlRefAId = static_cast<int>(cfgEvtPl / 10000);
64+
int evtPlRefBId = static_cast<int>((cfgEvtPl - evtPlRefAId * 10000) / 100);
65+
int evtPlDetId = cfgEvtPl - evtPlRefAId * 10000 - evtPlRefBId * 100;
66+
67+
void init(o2::framework::InitContext&)
68+
{
69+
histos.add("hVertexZ", "hVertexZ", HistType::kTH1F, {{nBins, -15., 15.}});
70+
histos.add("hMultiplicityPercent", "Multiplicity Percentile", kTH1F, {{120, 0.0f, 120.0f}});
71+
histos.add("hEvtPl", "Event Plane", kTH1F, {{100, -1.0f, 1.0f}});
72+
histos.add("hEta", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}});
73+
histos.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}});
74+
histos.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}});
75+
histos.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH1F, {{100, -10.0f, 10.0f}});
76+
histos.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH1F, {{100, -10.0f, 10.0f}});
77+
histos.add("hTiemResolutionTOF", "TOF time resolution", kTH1F, {{100, -10.0f, 10.0f}});
78+
histos.add("h1PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH1F, {{300, 0.9, 1.2}});
79+
histos.add("h1PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH1F, {{300, 0.9, 1.2}});
80+
histos.add("h1PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH1F, {{300, 0.9, 1.2}});
81+
histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}});
82+
histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}});
83+
histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{120, 0.0f, 120.0f}, {100, 0.0f, 10.0f}, {300, 0.9, 1.2}});
84+
85+
LOG(info) << "Size of the histograms in resonance tutorial with table combination:";
86+
histos.print();
87+
}
88+
89+
template <typename TrackType>
90+
bool trackCut(const TrackType track)
91+
{
92+
if (std::abs(track.pt()) < cMinPtcut)
93+
return false;
94+
if (std::abs(track.dcaXY()) > cMaxDCArToPVcut)
95+
return false;
96+
if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut)
97+
return false;
98+
if (cfgPrimaryTrack && !track.isPrimaryTrack())
99+
return false;
100+
if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA())
101+
return false;
102+
if (cfgPVContributor && !track.isPVContributor())
103+
return false;
104+
return true;
105+
}
106+
107+
template <typename T>
108+
bool selectionPID(const T& candidate)
109+
{
110+
bool tpcPass = std::abs(candidate.tpcNSigmaKa()) < nSigmaCutTPC;
111+
bool tofPass = (candidate.hasTOF()) ? std::abs(candidate.tofNSigmaKa()) < nSigmaCutTOF : true;
112+
if (tpcPass && tofPass) {
113+
return true;
114+
}
115+
return false;
116+
}
117+
118+
double rapidity, mass, pT, paircharge;
119+
TLorentzVector daughter1, daughter2, mother;
120+
template <bool IsMC, bool IsMix, typename CollisionType, typename TracksType>
121+
void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2)
122+
{
123+
auto multiplicity = collision.template collision_as<aod::ResoCollisions>().cent();
124+
for (auto const& track1 : dTracks1) {
125+
auto track1Reso = track1.template track_as<aod::ResoTracks>();
126+
auto track1FullPidExt = track1.template track_as<aod::Reso2TracksPIDExt>();
127+
if (!trackCut(track1Reso) || !selectionPID(track1Reso)) {
128+
continue;
129+
}
130+
histos.fill(HIST("hEta"), track1Reso.eta());
131+
histos.fill(HIST("hDcaxy"), track1Reso.dcaXY());
132+
histos.fill(HIST("hDcaz"), track1Reso.dcaZ());
133+
histos.fill(HIST("hNsigmaKaonTPC"), track1Reso.tpcNSigmaKa());
134+
if (track1Reso.hasTOF()) {
135+
histos.fill(HIST("hNsigmaKaonTOF"), track1Reso.tofNSigmaKa());
136+
histos.fill(HIST("hTiemResolutionTOF"), track1FullPidExt.trackTimeRes()); // TOF time resolution is not in the ResoTracks table (Important)
137+
}
138+
for (auto const& track2 : dTracks2) {
139+
auto track2Reso = track2.template track_as<aod::ResoTracks>();
140+
// auto track2FullPidExt = track2.template track_as<aod::Reso2TracksPIDExt>();
141+
142+
if (!trackCut(track2Reso) || !selectionPID(track2Reso)) {
143+
continue;
144+
}
145+
if (track2Reso.index() <= track1Reso.index()) {
146+
continue;
147+
}
148+
daughter1.SetXYZM(track1Reso.px(), track1Reso.py(), track1Reso.pz(), massKa);
149+
daughter2.SetXYZM(track2Reso.px(), track2Reso.py(), track2Reso.pz(), massKa);
150+
mother = daughter1 + daughter2;
151+
mass = mother.M();
152+
pT = mother.Pt();
153+
rapidity = mother.Rapidity();
154+
paircharge = track1Reso.sign() * track2Reso.sign();
155+
156+
if (std::abs(rapidity) > 0.5)
157+
continue;
158+
159+
if (paircharge < 0) {
160+
histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass);
161+
histos.fill(HIST("h1PhiInvMassUnlikeSign"), mass);
162+
} else {
163+
if (track1Reso.sign() > 0 && track2Reso.sign() > 0) {
164+
histos.fill(HIST("h3PhiInvMassLikeSignPP"), multiplicity, pT, mass);
165+
histos.fill(HIST("h1PhiInvMassLikeSignPP"), mass);
166+
} else {
167+
histos.fill(HIST("h3PhiInvMassLikeSignMM"), multiplicity, pT, mass);
168+
histos.fill(HIST("h1PhiInvMassLikeSignMM"), mass);
169+
}
170+
}
171+
}
172+
}
173+
}
174+
175+
void process(soa::Join<aod::ResoCollisions, aod::Qvectors>::iterator const& collision, soa::Join<aod::ResoTracks, aod::Reso2TracksPIDExt> const& resotracks)
176+
{
177+
histos.fill(HIST("hVertexZ"), collision.posZ());
178+
// Both resoCollisions and Qvectors have the same cent column, so we have to use "_as" to access it
179+
// Similarly, we can use "_as" to access the Qvectors table or other tables
180+
histos.fill(HIST("hMultiplicityPercent"), collision.collision_as<aod::ResoCollisions>().cent());
181+
// Event plane
182+
auto collisionQvec = collision.template collision_as<aod::Qvectors>(); // Qvectors table is not in the ResoCollisions table (Important)
183+
auto evtPl = -999.0;
184+
if (collisionQvec.qvecAmp()[evtPlDetId] > 1e-8)
185+
evtPl = helperEP.GetEventPlane(collisionQvec.qvecRe()[evtPlDetId * 4 + 3], collisionQvec.qvecIm()[evtPlDetId * 4 + 3], 2);
186+
if (evtPl > -999.0)
187+
histos.fill(HIST("hEvtPl"), evtPl);
188+
189+
fillHistograms<false, false>(collision, resotracks, resotracks);
190+
}
191+
};
192+
193+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask<ResonanceCombine>(cfgc)}; }

0 commit comments

Comments
 (0)