Skip to content

Commit 4b5c80b

Browse files
fchinualibuild
andauthored
[PWGHF] Add task for correlating multiplicity with generated dN/deta (#8474)
Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent fdb776d commit 4b5c80b

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

PWGHF/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(task-mc-validation
3939
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils
4040
COMPONENT_NAME Analysis)
4141

42+
o2physics_add_dpl_workflow(task-multiplicity-estimator-correlation
43+
SOURCES taskMultiplicityEstimatorCorrelation.cxx
44+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
45+
COMPONENT_NAME Analysis)
46+
4247
# o2physics_add_dpl_workflow(task-sel-optimisation
4348
# SOURCES taskSelOptimisation.cxx
4449
# PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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 taskMultiplicityEstimatorCorrelation.cxx
13+
/// \brief Task for correlating the multiplicity estimator with generated dN/deta
14+
///
15+
/// \author Fabrizio Chinu <fabrizio.chinu@cern.ch>, Università and INFN Torino
16+
17+
#include <string>
18+
#include <vector>
19+
#include <array>
20+
21+
#include "TPDGCode.h"
22+
#include "Framework/AnalysisTask.h"
23+
#include "Framework/HistogramRegistry.h"
24+
#include "Framework/runDataProcessing.h"
25+
#include "Framework/StaticFor.h"
26+
#include "Common/DataModel/Multiplicity.h"
27+
28+
using namespace o2;
29+
using namespace o2::framework;
30+
using namespace o2::framework::expressions;
31+
32+
struct HfTaskMultiplicityEstimatorCorrelation {
33+
HistogramRegistry registry{"registry", {}};
34+
static constexpr int8_t nEstimators = 8;
35+
static constexpr std::array<std::string_view, nEstimators> estimatorsNames = {"FV0A", "FT0A", "FT0C", "FT0M", "FDDA", "FDDC", "FDDM", "NTPV"};
36+
37+
std::vector<unsigned> consideredParticles = {
38+
kElectron,
39+
kMuonMinus,
40+
kPiPlus,
41+
kKPlus,
42+
kProton};
43+
44+
ConfigurableAxis axisFV0A = {"axisFV0A", {100, 0., 20000.}, "axis for FV0A estimator"};
45+
ConfigurableAxis axisFT0A = {"axisFT0A", {100, 0., 10000.}, "axis for FT0A estimator"};
46+
ConfigurableAxis axisFT0C = {"axisFT0C", {100, 0., 5000.}, "axis for FT0C estimator"};
47+
ConfigurableAxis axisFT0M = {"axisFT0M", {100, 0., 10000.}, "axis for FT0M estimator"};
48+
ConfigurableAxis axisFDDA = {"axisFDDA", {100, 0., 20000.}, "axis for FDDA estimator"};
49+
ConfigurableAxis axisFDDC = {"axisFDDC", {100, 0., 5000.}, "axis for FDDC estimator"};
50+
ConfigurableAxis axisFDDM = {"axisFDDM", {100, 0., 20000.}, "axis for FDDM estimator"};
51+
ConfigurableAxis axisNTPV = {"axisNTPV", {100, 0., 100.}, "axis for NTPV estimator"};
52+
ConfigurableAxis axisdNdEta = {"axisdNdEta", {100, 0., 100.}, "axis for dN/deta"};
53+
54+
std::vector<ConfigurableAxis*> estimatorsAxes = {&axisFV0A, &axisFT0A, &axisFT0C, &axisFT0M, &axisFDDA, &axisFDDC, &axisFDDM, &axisNTPV};
55+
56+
Preslice<aod::McParticles> particlesPerCollision = o2::aod::mcparticle::mcCollisionId;
57+
PresliceUnsorted<aod::McCollisionLabels> colPerMcCollision = aod::mccollisionlabel::mcCollisionId;
58+
59+
using CollisionsWithMult = soa::Join<aod::Collisions, aod::PVMults, aod::MultZeqs, aod::EvSels, aod::McCollisionLabels>;
60+
61+
void init(InitContext&)
62+
{
63+
for (int8_t i = 0; i < nEstimators; i++) {
64+
registry.add<TH2>(("etaPFive/" + std::string(estimatorsNames[i]) + "VsdNdeta").c_str(), (std::string(estimatorsNames[i]) + "VsdNdeta;" + std::string(estimatorsNames[i]) + ";<dN_{ch}/d#eta>").c_str(), HistType::kTH2F, {*(estimatorsAxes[i]), axisdNdEta});
65+
registry.add<TH2>(("etaOne/" + std::string(estimatorsNames[i]) + "VsdNdeta").c_str(), (std::string(estimatorsNames[i]) + "VsdNdeta;" + std::string(estimatorsNames[i]) + ";<dN_{ch}/d#eta>").c_str(), HistType::kTH2F, {*(estimatorsAxes[i]), axisdNdEta});
66+
}
67+
}
68+
69+
void process(CollisionsWithMult const& collisions,
70+
aod::McCollisions const& mcCollisions,
71+
aod::McParticles const& particles,
72+
soa::Join<aod::BCs, aod::Timestamps> const&)
73+
{
74+
for (auto const& collision : mcCollisions) {
75+
76+
// Get multiplicity for the reconstructed collision with the highest number of contributors
77+
unsigned maxNumContrib = 0;
78+
CollisionsWithMult::iterator collisionMaxNumContrib;
79+
const auto& recoCollsPerMcColl = collisions.sliceBy(colPerMcCollision, collision.globalIndex());
80+
for (const auto& recCol : recoCollsPerMcColl) {
81+
if (recCol.numContrib() > maxNumContrib) {
82+
maxNumContrib = recCol.numContrib();
83+
collisionMaxNumContrib = recCol;
84+
}
85+
}
86+
std::vector<float> multiplicity = {
87+
collisionMaxNumContrib.multZeqFV0A(),
88+
collisionMaxNumContrib.multZeqFT0A(),
89+
collisionMaxNumContrib.multZeqFT0C(),
90+
collisionMaxNumContrib.multZeqFT0A() + collisionMaxNumContrib.multZeqFT0C(),
91+
collisionMaxNumContrib.multZeqFDDA(),
92+
collisionMaxNumContrib.multZeqFDDC(),
93+
collisionMaxNumContrib.multZeqFDDA() + collisionMaxNumContrib.multZeqFDDC(),
94+
collisionMaxNumContrib.multZeqNTracksPV()};
95+
96+
// Get the dN/deta for the generated collision
97+
unsigned nChargedInEtaFive = 0;
98+
unsigned nChargedInEtaOne = 0;
99+
const auto& particlesPerMcColl = particles.sliceBy(particlesPerCollision, collision.globalIndex());
100+
for (auto const& particle : particlesPerMcColl) {
101+
if (particle.isPhysicalPrimary()) {
102+
bool isCharged = false;
103+
for (auto const& consideredParticle : consideredParticles) {
104+
if (std::abs(particle.pdgCode()) == consideredParticle) {
105+
isCharged = true;
106+
break;
107+
}
108+
}
109+
if (!isCharged) {
110+
continue;
111+
}
112+
if (std::abs(particle.eta()) < 0.5) {
113+
nChargedInEtaFive++;
114+
}
115+
if (std::abs(particle.eta()) < 1.0) {
116+
nChargedInEtaOne++;
117+
}
118+
}
119+
}
120+
121+
float dNdetaFive = nChargedInEtaFive;
122+
float dNdetaOne = nChargedInEtaOne / 2.0;
123+
for (int i = 0; i < nEstimators; i++) {
124+
static_for<0, nEstimators - 1>([&](auto j) {
125+
constexpr int index = j.value;
126+
registry.fill(HIST("etaPFive/") + HIST(estimatorsNames[index]) + HIST("VsdNdeta"), multiplicity[index], dNdetaFive);
127+
registry.fill(HIST("etaOne/") + HIST(estimatorsNames[index]) + HIST("VsdNdeta"), multiplicity[index], dNdetaOne);
128+
});
129+
}
130+
}
131+
}
132+
};
133+
134+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
135+
{
136+
return WorkflowSpec{adaptAnalysisTask<HfTaskMultiplicityEstimatorCorrelation>(cfgc)};
137+
}

0 commit comments

Comments
 (0)