Skip to content

Commit 369781d

Browse files
authored
Prototype version of Resonance Package (#1073)
* Update version of Resonance Package
1 parent 912b5f7 commit 369781d

6 files changed

Lines changed: 660 additions & 1 deletion

File tree

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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 LFResonanceTables.h
13+
/// \brief Definitions of tables of resonance decay candidates
14+
///
15+
/// Inspired by StrangenessTables.h, FemtoDerived.h
16+
///
17+
/// \author Bong-Hwi Lim <bong-hwi.lim@cern.ch>
18+
19+
#ifndef O2_ANALYSIS_LFRESONANCETABLES_H_
20+
#define O2_ANALYSIS_LFRESONANCETABLES_H_
21+
22+
#include <cmath>
23+
24+
#include "Common/DataModel/PIDResponse.h"
25+
#include "Common/Core/RecoDecay.h"
26+
#include "Common/DataModel/TrackSelectionTables.h"
27+
#include "Framework/AnalysisDataModel.h"
28+
29+
namespace o2::aod
30+
{
31+
/// Resonance Collisions
32+
namespace resocollision
33+
{
34+
DECLARE_SOA_COLUMN(MultV0M, multV0M, float); //! V0M multiplicity
35+
DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event
36+
} // namespace resocollision
37+
DECLARE_SOA_TABLE(ResoCollisions, "AOD", "RESOCOL",
38+
o2::soa::Index<>,
39+
o2::aod::collision::PosX,
40+
o2::aod::collision::PosY,
41+
o2::aod::collision::PosZ,
42+
resocollision::MultV0M,
43+
resocollision::Sphericity,
44+
timestamp::Timestamp);
45+
using ResoCollision = ResoCollisions::iterator;
46+
47+
// Resonance Daughters
48+
// inspired from PWGCF/DataModel/FemtoDerived.h
49+
namespace resodaughter
50+
{
51+
/// Distinuishes the different daughter types
52+
enum DaughterType {
53+
kTrack, //! Track
54+
kV0, //! V0
55+
kCascade, //! Cascade
56+
kNDaughterTypes //! Number of Daughter types
57+
};
58+
static constexpr std::string_view DaughterTypeName[kNDaughterTypes] = {"Tracks", "V0", "Cascade"}; //! Naming of the different particle types
59+
60+
enum PDGtype {
61+
kPion = BIT(0),
62+
kKaon = BIT(1),
63+
kProton = BIT(2),
64+
kHasTOF = BIT(6) // Save hasTOF info for TOF selection
65+
};
66+
67+
#define requireTPCPIDCutInFilter(mask) ((aod::resodaughter::tpcPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask)
68+
#define requireTOFPIDCutInFilter(mask) (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) != (uint8_t)aod::resodaughter::kHasTOF) || (((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::mask) == (uint8_t)aod::resodaughter::mask) && ((aod::resodaughter::tofPIDselectionFlag & (uint8_t)aod::resodaughter::kHasTOF) == (uint8_t)aod::resodaughter::kHasTOF)))
69+
#define requireTPCPIDPionCutInFilter() requireTPCPIDCutInFilter(PDGtype::kPion)
70+
#define requireTPCPIDKaonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kKaon)
71+
#define requireTPCPIDProtonCutInFilter() requireTPCPIDCutInFilter(PDGtype::kProton)
72+
#define requireTOFPIDPionCutInFilter() requireTOFPIDCutInFilter(PDGtype::kPion)
73+
#define requireTOFPIDKaonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kKaon)
74+
#define requireTOFPIDProtonCutInFilter() requireTOFPIDCutInFilter(PDGtype::kProton)
75+
76+
DECLARE_SOA_INDEX_COLUMN(ResoCollision, resoCollision);
77+
DECLARE_SOA_COLUMN(Pt, pt, float); //! p_T (GeV/c)
78+
DECLARE_SOA_COLUMN(Px, px, float); //! p_x (GeV/c)
79+
DECLARE_SOA_COLUMN(Py, py, float); //! p_y (GeV/c)
80+
DECLARE_SOA_COLUMN(Pz, pz, float); //! p_z (GeV/c)
81+
DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta
82+
DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi
83+
DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to resodaughter::ParticleType
84+
DECLARE_SOA_COLUMN(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA)
85+
DECLARE_SOA_COLUMN(Indices, indices, int[2]); //! Field for the track indices to remove auto-correlations
86+
DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the track charge
87+
DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! Number of TPC crossed rows
88+
DECLARE_SOA_COLUMN(TPCPIDselectionFlag, tpcPIDselectionFlag, uint8_t); //! TPC PID selection
89+
DECLARE_SOA_COLUMN(TOFPIDselectionFlag, tofPIDselectionFlag, uint8_t); //! TOF PID selection
90+
DECLARE_SOA_COLUMN(DaughDCA, daughDCA, float); //! DCA between daughters
91+
DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda
92+
DECLARE_SOA_COLUMN(MAntiLambda, mAntiLambda, float); //! The invariant mass of V0 candidate, assuming antilambda
93+
DECLARE_SOA_COLUMN(TransRadius, transRadius, float); //! Transverse radius of the decay vertex
94+
DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex
95+
DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex
96+
DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex
97+
} // namespace resodaughter
98+
DECLARE_SOA_TABLE(ResoDaughters, "AOD", "RESODAUGHTERS",
99+
o2::soa::Index<>,
100+
resodaughter::ResoCollisionId,
101+
resodaughter::Pt,
102+
resodaughter::Px,
103+
resodaughter::Py,
104+
resodaughter::Pz,
105+
resodaughter::Eta,
106+
resodaughter::Phi,
107+
resodaughter::PartType,
108+
resodaughter::TempFitVar,
109+
resodaughter::Indices,
110+
resodaughter::Sign,
111+
resodaughter::TPCNClsCrossedRows,
112+
o2::aod::track::DcaXY,
113+
o2::aod::track::DcaZ,
114+
o2::aod::track::X,
115+
o2::aod::track::Alpha,
116+
resodaughter::TPCPIDselectionFlag,
117+
resodaughter::TOFPIDselectionFlag,
118+
o2::aod::pidtpc::TPCNSigmaPi,
119+
o2::aod::pidtpc::TPCNSigmaKa,
120+
o2::aod::pidtpc::TPCNSigmaPr,
121+
o2::aod::pidtof::TOFNSigmaPi,
122+
o2::aod::pidtof::TOFNSigmaKa,
123+
o2::aod::pidtof::TOFNSigmaPr,
124+
resodaughter::DaughDCA,
125+
resodaughter::MLambda,
126+
resodaughter::MAntiLambda,
127+
resodaughter::TransRadius,
128+
resodaughter::DecayVtxX,
129+
resodaughter::DecayVtxY,
130+
resodaughter::DecayVtxZ);
131+
using ResoDaughter = ResoDaughters::iterator;
132+
133+
using Reso2TracksExt = soa::Join<aod::FullTracks, aod::TracksExtra, aod::TracksDCA>;
134+
using Reso2TracksMC = soa::Join<aod::FullTracks, McTrackLabels>;
135+
using Reso2TracksPID = soa::Join<aod::FullTracks, aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr, aod::pidTOFPi, aod::pidTOFKa, aod::pidTOFPr>;
136+
using Reso2TracksPIDExt = soa::Join<Reso2TracksPID, aod::TracksExtra, aod::TracksDCA>;
137+
138+
} // namespace o2::aod
139+
#endif // O2_ANALYSIS_LFRESONANCETABLES_H_

PWGLF/TableProducer/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,10 @@ o2physics_add_dpl_workflow(cascadefinder
3131

3232
o2physics_add_dpl_workflow(nucleustreecreator
3333
SOURCES LFTreeCreatorNuclei.cxx
34-
PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore
34+
PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore
35+
COMPONENT_NAME Analysis)
36+
37+
o2physics_add_dpl_workflow(reso2initializer
38+
SOURCES LFResonanceInitializer.cxx
39+
PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::DetectorsVertexing
3540
COMPONENT_NAME Analysis)
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
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 LFResonanceInitializer.cxx
13+
/// \brief Initializes variables for the resonance candidate producers
14+
///
15+
///
16+
/// \author Bong-Hwi Lim <bong-hwi.lim@cern.ch>
17+
18+
#include "Common/DataModel/PIDResponse.h"
19+
#include "Common/Core/TrackSelection.h"
20+
#include "Common/DataModel/Centrality.h"
21+
#include "Common/DataModel/Multiplicity.h"
22+
#include "Common/Core/trackUtilities.h"
23+
#include "Common/DataModel/EventSelection.h"
24+
#include "Common/DataModel/StrangenessTables.h"
25+
#include "Common/DataModel/TrackSelectionTables.h"
26+
#include "Framework/ASoAHelpers.h"
27+
#include "Framework/AnalysisDataModel.h"
28+
#include "Framework/AnalysisTask.h"
29+
#include "Framework/runDataProcessing.h"
30+
#include "PWGLF/DataModel/LFResonanceTables.h"
31+
#include "PWGLF/Utils/collisionCuts.h"
32+
#include "ReconstructionDataFormats/Track.h"
33+
34+
using namespace o2;
35+
using namespace o2::framework;
36+
using namespace o2::framework::expressions;
37+
using namespace o2::soa;
38+
39+
/// Initializer for the resonance candidate producers
40+
struct reso2initializer {
41+
42+
Produces<aod::ResoCollisions> resoCollisions;
43+
Produces<aod::ResoDaughters> reso2tracks;
44+
45+
// Configurables
46+
Configurable<bool> ConfIsRun3{"ConfIsRun3", false, "Running on Pilot beam"}; // Choose if running on converted data or pilot beam
47+
Configurable<bool> ConfStoreV0{"ConfStoreV0", true, "True: store V0s"};
48+
49+
/// Event cuts
50+
o2::analysis::CollisonCuts colCuts;
51+
Configurable<float> ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"};
52+
Configurable<bool> ConfEvtTriggerCheck{"ConfEvtTriggerCheck", true, "Evt sel: check for trigger"};
53+
Configurable<int> ConfEvtTriggerSel{"ConfEvtTriggerSel", kINT7, "Evt sel: trigger"};
54+
Configurable<bool> ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"};
55+
56+
// Pre-selection cuts
57+
Configurable<float> cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"};
58+
Configurable<float> pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 5.0f, "TPC and TOF PID cut (loose, improve performance)"};
59+
Configurable<int> mincrossedrows{"mincrossedrows", 70, "min crossed rows"};
60+
Configurable<int> isRun2{"isRun2", 0, "if Run2: demand TPC refit"};
61+
62+
/// DCA Selections for V0
63+
// DCAr to PV
64+
Configurable<double> cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.05, "Track DCAr cut to PV Maximum"};
65+
Configurable<double> cMinV0PosDCArToPVcut{"cMinV0PosDCArToPVcut", 0.05f, "V0 Positive Track DCAr cut to PV Minimum"}; // Pre-selection
66+
Configurable<double> cMinV0NegDCArToPVcut{"cMinV0NegDCArToPVcut", 0.05f, "V0 Negative Track DCAr cut to PV Minimum"}; // Pre-selection
67+
// DCAz to PV
68+
Configurable<double> cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"};
69+
Configurable<double> cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"};
70+
71+
Configurable<double> cMinV0Radius{"cMinV0Radius", 5.0, "Minimum V0 radius from PV"};
72+
Configurable<double> cMaxV0Radius{"cMaxV0Radius", 200.0, "Maximum V0 radius from PV"};
73+
Configurable<double> cMinV0CosPA{"cMinV0CosPA", 0.995, "Minimum V0 CosPA to PV"};
74+
75+
HistogramRegistry qaRegistry{"QAHistos", {
76+
{"hGoodTrackIndices", "hGoodTrackIndices", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}},
77+
{"hGoodV0Indices", "hGoodV0Indices", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}},
78+
},
79+
OutputObjHandlingPolicy::QAObject};
80+
81+
// Pre-filters for efficient process
82+
// Filter tofPIDFilter = aod::track::tofExpMom < 0.f || ((aod::track::tofExpMom > 0.f) && ((nabs(aod::pidtof::tofNSigmaPi) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < pidnSigmaPreSelectionCut))); // TOF
83+
Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < pidnSigmaPreSelectionCut; // TPC
84+
Filter trackFilter = nabs(aod::track::eta) < cfgCutEta; // Eta cut
85+
Filter trackCutFilter = requireGlobalTrackInFilter(); // Global track cuts
86+
87+
void init(InitContext&)
88+
{
89+
colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3);
90+
colCuts.init(&qaRegistry);
91+
}
92+
93+
void process(const soa::Join<o2::aod::Collisions, o2::aod::EvSels, aod::Mults>::iterator& collision,
94+
soa::Filtered<aod::Reso2TracksPIDExt> const& tracks, o2::aod::V0Datas const& V0s, aod::BCsWithTimestamps const&)
95+
{
96+
auto bc = collision.bc_as<aod::BCsWithTimestamps>(); /// adding timestamp to access magnetic field later
97+
// Default event selection
98+
if (!colCuts.isSelected(collision))
99+
return;
100+
colCuts.fillQA(collision);
101+
102+
if (ConfIsRun3) {
103+
resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFT0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp());
104+
} else {
105+
resoCollisions(collision.posX(), collision.posY(), collision.posZ(), collision.multFV0M(), colCuts.computeSphericity(collision, tracks), bc.timestamp());
106+
}
107+
108+
int childIDs[2] = {0, 0}; // these IDs are necessary to keep track of the children
109+
// Loop over tracks
110+
for (auto& track : tracks) {
111+
// Tracks are already filtered by the pre-filters
112+
qaRegistry.fill(HIST("hGoodTrackIndices"), 0.5);
113+
114+
// Add PID selection criteria here
115+
uint8_t tpcPIDselections = 0;
116+
uint8_t tofPIDselections = 0;
117+
// TPC PID
118+
if (std::abs(track.tpcNSigmaPi()) < pidnSigmaPreSelectionCut)
119+
tpcPIDselections |= aod::resodaughter::PDGtype::kPion;
120+
if (std::abs(track.tpcNSigmaKa()) < pidnSigmaPreSelectionCut)
121+
tpcPIDselections |= aod::resodaughter::PDGtype::kKaon;
122+
if (std::abs(track.tpcNSigmaPr()) < pidnSigmaPreSelectionCut)
123+
tpcPIDselections |= aod::resodaughter::PDGtype::kProton;
124+
// TOF PID
125+
if (track.hasTOF()) {
126+
tofPIDselections |= aod::resodaughter::PDGtype::kHasTOF;
127+
if (std::abs(track.tofNSigmaPi()) < pidnSigmaPreSelectionCut)
128+
tofPIDselections |= aod::resodaughter::PDGtype::kPion;
129+
if (std::abs(track.tofNSigmaKa()) < pidnSigmaPreSelectionCut)
130+
tofPIDselections |= aod::resodaughter::PDGtype::kKaon;
131+
if (std::abs(track.tofNSigmaPr()) < pidnSigmaPreSelectionCut)
132+
tofPIDselections |= aod::resodaughter::PDGtype::kProton;
133+
}
134+
135+
reso2tracks(resoCollisions.lastIndex(),
136+
track.pt(),
137+
track.px(),
138+
track.py(),
139+
track.pz(),
140+
track.eta(),
141+
track.phi(),
142+
aod::resodaughter::DaughterType::kTrack,
143+
track.dcaXY(),
144+
childIDs,
145+
track.sign(),
146+
(uint8_t)track.tpcNClsCrossedRows(),
147+
track.dcaXY(),
148+
track.dcaZ(),
149+
track.x(),
150+
track.alpha(),
151+
tpcPIDselections,
152+
tofPIDselections,
153+
track.tpcNSigmaPi(),
154+
track.tpcNSigmaKa(),
155+
track.tpcNSigmaPr(),
156+
track.tofNSigmaPi(),
157+
track.tofNSigmaKa(),
158+
track.tofNSigmaPr(),
159+
0, 0, 0,
160+
0, 0, 0, 0);
161+
}
162+
/// V0s
163+
if (ConfStoreV0) {
164+
for (auto& v0 : V0s) {
165+
qaRegistry.fill(HIST("hGoodV0Indices"), 0.5);
166+
auto postrack = v0.posTrack_as<aod::Reso2TracksPIDExt>();
167+
auto negtrack = v0.negTrack_as<aod::Reso2TracksPIDExt>();
168+
169+
if (postrack.tpcNClsCrossedRows() < mincrossedrows)
170+
continue;
171+
if (negtrack.tpcNClsCrossedRows() < mincrossedrows)
172+
continue;
173+
qaRegistry.fill(HIST("hGoodV0Indices"), 1.5);
174+
175+
if (fabs(postrack.dcaXY()) < cMinV0PosDCArToPVcut)
176+
continue;
177+
if (fabs(negtrack.dcaXY()) < cMinV0NegDCArToPVcut)
178+
continue;
179+
qaRegistry.fill(HIST("hGoodV0Indices"), 2.5);
180+
181+
if ((v0.v0radius() > cMaxV0Radius) || (v0.v0radius() < cMinV0Radius))
182+
continue;
183+
qaRegistry.fill(HIST("hGoodV0Indices"), 3.5);
184+
if (v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cMinV0CosPA)
185+
continue;
186+
qaRegistry.fill(HIST("hGoodV0Indices"), 4.5);
187+
childIDs[0] = v0.posTrackId();
188+
childIDs[1] = v0.negTrackId();
189+
reso2tracks(resoCollisions.lastIndex(),
190+
v0.pt(),
191+
v0.px(),
192+
v0.py(),
193+
v0.pz(),
194+
v0.eta(),
195+
v0.phi(),
196+
aod::resodaughter::DaughterType::kV0,
197+
v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()),
198+
childIDs,
199+
0,
200+
0,
201+
v0.v0cosPA(collision.posX(), collision.posY(), collision.posZ()),
202+
0,
203+
v0.x(), 0, 0, 0, 0, 0, 0, 0, 0, 0,
204+
v0.dcaV0daughters(), v0.mLambda(), v0.mAntiLambda(),
205+
v0.v0radius(), v0.x(), v0.y(), v0.z());
206+
}
207+
}
208+
}
209+
};
210+
211+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
212+
{
213+
return WorkflowSpec{
214+
adaptAnalysisTask<reso2initializer>(cfgc, TaskName{"lf-reso2initializer"}),
215+
};
216+
}

PWGLF/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,9 @@ o2physics_add_dpl_workflow(track-checks
9797
o2physics_add_dpl_workflow(rsnanalysis
9898
SOURCES rsnanalysis.cxx
9999
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase
100+
COMPONENT_NAME Analysis)
101+
102+
o2physics_add_dpl_workflow(phianalysis
103+
SOURCES phianalysis.cxx
104+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase
100105
COMPONENT_NAME Analysis)

0 commit comments

Comments
 (0)