Skip to content

Commit 80a2a6d

Browse files
authored
[PWGJE] Add Berkeley tree producer (#17666)
1 parent 7310599 commit 80a2a6d

2 files changed

Lines changed: 209 additions & 0 deletions

File tree

PWGJE/TableProducer/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ o2physics_add_dpl_workflow(slim-tables-producer
116116
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
117117
COMPONENT_NAME Analysis)
118118

119+
o2physics_add_dpl_workflow(berkeley-tree-producer
120+
SOURCES berkeleyTreeProducer.cxx
121+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
122+
COMPONENT_NAME Analysis)
123+
119124
o2physics_add_dpl_workflow(diff-wake-tree-producer
120125
SOURCES diffWakeTreeProducer.cxx
121126
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
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 berkeleyTreeProducer.cxx
13+
/// \brief Task to save MC events into the BerkeleyTree format
14+
/// \author Vassu Doomra <vdoomra@berkeley.edu>
15+
/// \author Tucker Hwang <mhwang@cern.ch>
16+
17+
#include "PWGJE/Core/JetDerivedDataUtilities.h"
18+
#include "PWGJE/DataModel/Jet.h"
19+
#include "PWGJE/DataModel/JetReducedData.h"
20+
21+
#include <Framework/AnalysisTask.h>
22+
#include <Framework/Configurable.h>
23+
#include <Framework/O2DatabasePDGPlugin.h>
24+
#include <Framework/runDataProcessing.h>
25+
26+
#include <cmath>
27+
#include <string>
28+
#include <vector>
29+
30+
using namespace o2;
31+
using namespace o2::framework;
32+
using namespace o2::framework::expressions;
33+
34+
namespace o2::aod
35+
{
36+
namespace berkeleytree
37+
{
38+
DECLARE_SOA_COLUMN(VtxZ, vtxZ, float);
39+
DECLARE_SOA_COLUMN(Weight, weight, float);
40+
DECLARE_SOA_COLUMN(PtHat, ptHat, float);
41+
DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float);
42+
DECLARE_SOA_COLUMN(Occupancy, occupancy, int);
43+
DECLARE_SOA_COLUMN(EventSel, eventSel, uint16_t);
44+
DECLARE_SOA_BITMAP_COLUMN(Rct, rct, 32);
45+
46+
DECLARE_SOA_COLUMN(DetPt, detPt, std::vector<float>);
47+
DECLARE_SOA_COLUMN(DetEta, detEta, std::vector<float>);
48+
DECLARE_SOA_COLUMN(DetPhi, detPhi, std::vector<float>);
49+
DECLARE_SOA_COLUMN(DetTrackSel, detTrackSel, std::vector<uint8_t>);
50+
DECLARE_SOA_COLUMN(DetMcId, detMcId, std::vector<int>);
51+
52+
DECLARE_SOA_COLUMN(GenPt, genPt, std::vector<float>);
53+
DECLARE_SOA_COLUMN(GenEta, genEta, std::vector<float>);
54+
DECLARE_SOA_COLUMN(GenPhi, genPhi, std::vector<float>);
55+
DECLARE_SOA_COLUMN(GenE, genE, std::vector<float>);
56+
DECLARE_SOA_COLUMN(GenCharge, genCharge, std::vector<int>);
57+
DECLARE_SOA_COLUMN(GenMcId, genMcId, std::vector<int64_t>);
58+
DECLARE_SOA_COLUMN(PdgId, pdgId, std::vector<int>);
59+
} // namespace berkeleytree
60+
61+
DECLARE_SOA_TABLE(BerkeleyTree, "AOD", "BERKELEYTREE",
62+
berkeleytree::VtxZ,
63+
berkeleytree::Weight,
64+
berkeleytree::PtHat,
65+
berkeleytree::Multiplicity,
66+
berkeleytree::EventSel,
67+
berkeleytree::Occupancy,
68+
berkeleytree::Rct,
69+
berkeleytree::DetPt,
70+
berkeleytree::DetEta,
71+
berkeleytree::DetPhi,
72+
berkeleytree::DetTrackSel,
73+
berkeleytree::DetMcId,
74+
berkeleytree::GenPt,
75+
berkeleytree::GenEta,
76+
berkeleytree::GenPhi,
77+
berkeleytree::GenE,
78+
berkeleytree::GenCharge,
79+
berkeleytree::GenMcId,
80+
berkeleytree::PdgId);
81+
} // namespace o2::aod
82+
83+
struct BerkeleyTreeProducer {
84+
Service<o2::framework::O2DatabasePDG> pdg;
85+
86+
Configurable<float> vertexZCut{"vertexZCut", 10.0f, "maximum Z vertex"};
87+
Configurable<float> etaMaxDet{"etaMaxDet", 0.9f, "maximum eta for det-level tracks"};
88+
Configurable<float> etaMaxGen{"etaMaxGen", 0.9f, "maximum eta for gen-level particles"};
89+
Configurable<float> ptMinDet{"ptMinDet", 0.15f, "minimum pt (GeV) for det-level tracks"};
90+
Configurable<float> ptMinGen{"ptMinGen", 0.15f, "minimum pt (GeV) for gen-level particles"};
91+
92+
Configurable<std::string> eventSelections{"eventSelections", "sel8", ""};
93+
Configurable<std::string> trackSelections{"trackSelections", "globalTracks", ""};
94+
Configurable<bool> skipMBGapEvents{"skipMBGapEvents", true, "skip MB gap events"};
95+
96+
Produces<aod::BerkeleyTree> tree;
97+
98+
std::vector<int> eventSelectionBits;
99+
int trackSelection = -1;
100+
101+
Preslice<aod::JMcParticles> particlesPerMcCollision = aod::jmcparticle::mcCollisionId;
102+
103+
bool isChargedParticle(int code)
104+
{
105+
const float chargeUnit = 3.;
106+
auto p = pdg->GetParticle(code);
107+
auto charge = 0.;
108+
if (p != nullptr) {
109+
charge = p->Charge();
110+
}
111+
return std::abs(charge) >= chargeUnit;
112+
}
113+
114+
int getCharge(int code)
115+
{
116+
auto p = pdg->GetParticle(code);
117+
if (!p) {
118+
LOG(fatal) << "Cannot find particle with PDG code " << code;
119+
return 0;
120+
}
121+
auto charge = p->Charge() / 3.0;
122+
return std::lround(charge);
123+
}
124+
125+
void init(InitContext const&)
126+
{
127+
eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(eventSelections);
128+
trackSelection = jetderiveddatautilities::initialiseTrackSelection(trackSelections);
129+
}
130+
131+
using JetParticlesWithOriginal = soa::Join<aod::JetParticles, aod::JMcParticlePIs>;
132+
void processMCJJ(aod::JetCollisionsMCD::iterator const& collision, aod::JetTracksMCD const& tracks, JetParticlesWithOriginal const& mcParticles, aod::JetMcCollisions const&)
133+
{
134+
// do not do any RCT selections, will be done on analysis level
135+
if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents, false, "", false, false))
136+
return;
137+
if (std::abs(collision.posZ()) > vertexZCut)
138+
return;
139+
140+
float weight = collision.has_mcCollision() ? collision.mcCollision().weight() : 1.f;
141+
float pthat = collision.has_mcCollision() ? collision.mcCollision().ptHard() : 1.f;
142+
143+
std::vector<float> detPt, detEta, detPhi;
144+
std::vector<uint8_t> detTrackSel;
145+
std::vector<int> detMcId; // track.mcParticleId() returns int/int32_t
146+
147+
std::vector<float> genPt, genEta, genPhi, genE;
148+
std::vector<int> genCharge, pdgId;
149+
std::vector<int64_t> genMcId; // mcParticle.globalIndex() returns long/int64_t
150+
151+
for (auto const& track : tracks) {
152+
if (!jetderiveddatautilities::selectTrack(track, trackSelection))
153+
continue;
154+
155+
if (std::fabs(track.eta()) > etaMaxDet)
156+
continue;
157+
if (track.pt() < ptMinDet)
158+
continue;
159+
160+
detPt.push_back(track.pt());
161+
detEta.push_back(track.eta());
162+
detPhi.push_back(track.phi());
163+
detTrackSel.push_back(track.trackSel());
164+
if (track.has_mcParticle())
165+
detMcId.push_back(track.mcParticleId());
166+
else
167+
detMcId.push_back(-1);
168+
}
169+
170+
int mcId = collision.has_mcCollision() ? collision.mcCollisionId() : -1;
171+
172+
if (mcId >= 0) {
173+
auto particles = mcParticles.sliceBy(particlesPerMcCollision, mcId);
174+
175+
for (auto const& p : particles) {
176+
if (!p.isPhysicalPrimary())
177+
continue;
178+
if (std::fabs(p.eta()) > etaMaxGen)
179+
continue;
180+
if (p.pt() < ptMinGen)
181+
continue;
182+
if (!isChargedParticle(p.pdgCode()))
183+
continue;
184+
185+
genPt.push_back(p.pt());
186+
genEta.push_back(p.eta());
187+
genPhi.push_back(p.phi());
188+
genE.push_back(p.e());
189+
genCharge.push_back(getCharge(p.pdgCode()));
190+
genMcId.push_back(p.globalIndex());
191+
pdgId.push_back(p.pdgCode());
192+
}
193+
}
194+
195+
tree(collision.posZ(), weight, pthat, collision.multFT0C(), collision.eventSel(), collision.trackOccupancyInTimeRange(), collision.rct_raw(), detPt, detEta, detPhi, detTrackSel, detMcId, genPt, genEta, genPhi, genE, genCharge, genMcId, pdgId);
196+
}
197+
198+
PROCESS_SWITCH(BerkeleyTreeProducer, processMCJJ, "MC processing for JJ simulations", false);
199+
};
200+
201+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
202+
{
203+
return WorkflowSpec{adaptAnalysisTask<BerkeleyTreeProducer>(cfgc)};
204+
}

0 commit comments

Comments
 (0)