Skip to content

Commit 041560b

Browse files
committed
A3: add qa tasks
1 parent c17c8eb commit 041560b

File tree

3 files changed

+197
-1
lines changed

3 files changed

+197
-1
lines changed

ALICE3/Tasks/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(alice3-pid-ftof-qa
3939
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
4040
COMPONENT_NAME Analysis)
4141

42+
o2physics_add_dpl_workflow(alice3-pid-separation-power
43+
SOURCES pidSeparationPower.cxx
44+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
45+
COMPONENT_NAME Analysis)
46+
4247
o2physics_add_dpl_workflow(alice3-cdeuteron
4348
SOURCES alice3-cdeuteron.cxx
4449
PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore
@@ -52,4 +57,9 @@ o2physics_add_dpl_workflow(alice3-dilepton
5257
o2physics_add_dpl_workflow(alice3-taskcorrelationddbar
5358
SOURCES alice3-taskcorrelationDDbar.cxx
5459
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
55-
COMPONENT_NAME Analysis)
60+
COMPONENT_NAME Analysis)
61+
62+
o2physics_add_dpl_workflow(alice3-efficiency
63+
SOURCES alice3Efficiency.cxx
64+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
65+
COMPONENT_NAME Analysis)

ALICE3/Tasks/alice3Efficiency.cxx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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 alice3Efficiency.cxx
13+
///
14+
/// \brief This task produces the efficiency
15+
///
16+
/// \author Nicolò Jacazio, Universita del Piemonte Orientale (IT)
17+
/// \since May 27, 2025
18+
///
19+
20+
#include <map>
21+
#include <vector>
22+
23+
#include "Framework/AnalysisTask.h"
24+
#include "Framework/runDataProcessing.h"
25+
#include "Framework/HistogramRegistry.h"
26+
#include "Framework/ConfigParamRegistry.h"
27+
#include "TEfficiency.h"
28+
#include "THashList.h"
29+
30+
using namespace o2;
31+
using namespace o2::framework;
32+
std::map<int, TEfficiency*> effVsPt;
33+
34+
struct alice3Efficiency {
35+
Configurable<std::vector<int>> pdgCodes{"pdgCodes", {211}, "List of PDG codes to consider for efficiency calculation"};
36+
OutputObj<THashList> outList{"output"};
37+
void init(o2::framework::InitContext&)
38+
{
39+
outList.setObject(new THashList);
40+
for (auto pdg : pdgCodes.value) {
41+
effVsPt[pdg] = new TEfficiency(Form("efficiency_pdg%d", pdg),
42+
Form("Efficiency for PDG %d; p_{T} (GeV/c); Efficiency", pdg),
43+
100, 0, 10);
44+
outList->Add(effVsPt[pdg]);
45+
}
46+
}
47+
48+
void process(soa::Join<aod::Tracks, o2::aod::McTrackLabels> const& tracks,
49+
aod::McParticles const& mcParticles)
50+
{
51+
std::map<int, std::vector<int64_t>> pdgIndices;
52+
for (auto& mc : mcParticles) {
53+
if (effVsPt.find(mc.pdgCode()) == effVsPt.end()) {
54+
continue;
55+
}
56+
pdgIndices[mc.pdgCode()].push_back(mc.globalIndex());
57+
}
58+
for (const auto& track : tracks) {
59+
if (!track.has_mcParticle()) {
60+
continue;
61+
}
62+
const auto& mcParticle = track.mcParticle();
63+
// Check that the PDG is in the list of PDGs
64+
if (pdgIndices.find(mcParticle.pdgCode()) == pdgIndices.end()) {
65+
continue;
66+
}
67+
68+
std::vector<int64_t>& indices = pdgIndices[mcParticle.pdgCode()];
69+
// Fill efficiency histogram
70+
auto& eff = effVsPt[mcParticle.pdgCode()];
71+
const bool found = std::find(indices.begin(), indices.end(), track.globalIndex()) != indices.end();
72+
eff->Fill(track.pt(), found);
73+
}
74+
}
75+
};
76+
77+
WorkflowSpec defineDataProcessing(ConfigContext const& ctx)
78+
{
79+
return WorkflowSpec{adaptAnalysisTask<alice3Efficiency>(ctx)};
80+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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 pidSeparationPower.cxx
13+
///
14+
/// \brief This task produces the separation power of the ALICE3 detector
15+
///
16+
/// \author Nicolò Jacazio, Universita del Piemonte Orientale (IT)
17+
/// \since May 13, 2025
18+
///
19+
20+
#include <utility>
21+
#include <map>
22+
#include <string>
23+
#include <vector>
24+
25+
#include "Framework/AnalysisDataModel.h"
26+
#include "Framework/AnalysisTask.h"
27+
#include "Framework/runDataProcessing.h"
28+
#include "Framework/RunningWorkflowInfo.h"
29+
#include "Framework/HistogramRegistry.h"
30+
#include "TProfile2D.h"
31+
#include "THashList.h"
32+
#include "ALICE3/DataModel/OTFTOF.h"
33+
#include "ALICE3/DataModel/OTFRICH.h"
34+
35+
using namespace o2;
36+
using namespace o2::framework;
37+
38+
std::array<TProfile2D*, 5> separationInnerTOF;
39+
std::array<TProfile2D*, 5> separationOuterTOF;
40+
std::array<TProfile2D*, 5> separationRICH;
41+
struct pidSeparationPower {
42+
43+
ConfigurableAxis etaAxis{"etaAxis", {100, -1.f, 1.f}, "Binning in eta"};
44+
HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject};
45+
OutputObj<THashList> listSeparation{"separationPower"};
46+
void init(o2::framework::InitContext&)
47+
{
48+
listSeparation.setObject(new THashList);
49+
for (int i = 0; i < 5; i++) {
50+
auto createEfficiency = [&](const char* name, const char* title) {
51+
TProfile2D* eff = new TProfile2D(Form("%s_%d", name, i),
52+
Form("%s_%d;%s", title, i, "#it{p}_{T} (GeV/#it{c});#it{#eta}"),
53+
100, 0.f, 10.f,
54+
100, 0.f, 10.f);
55+
listSeparation->Add(eff);
56+
return eff;
57+
};
58+
separationInnerTOF[i] = createEfficiency("separationInnerTOF", "separationInnerTOF");
59+
separationOuterTOF[i] = createEfficiency("separationOuterTOF", "separationOuterTOF");
60+
separationRICH[i] = createEfficiency("separationRICH", "separationRICH");
61+
}
62+
}
63+
64+
void process(soa::Join<aod::Collisions, aod::McCollisionLabels>::iterator const& /*collision*/,
65+
soa::Join<aod::Tracks, aod::TracksCov, aod::McTrackLabels, aod::UpgradeTofMC, aod::UpgradeTof> const& tracks,
66+
aod::McParticles const&,
67+
aod::McCollisions const&)
68+
{
69+
for (const auto& track : tracks) {
70+
if (!track.has_mcParticle()) {
71+
continue;
72+
}
73+
// Check that all the nsigmas are numbers (sanity check)
74+
for (int i = 0; i < 5; i++) {
75+
if (std::isnan(track.nSigmaInnerTOF(i)) || std::isnan(track.nSigmaOuterTOF(i))) {
76+
LOG(fatal) << "Unrecognized nsigma for " << i << " " << track.nSigmaInnerTOF(i) << " " << track.nSigmaOuterTOF(i);
77+
}
78+
}
79+
80+
const auto& mcParticle = track.mcParticle();
81+
// Separation electron pion
82+
switch (std::abs(mcParticle.pdgCode())) {
83+
{
84+
case 211: // electron-pion separation
85+
separationInnerTOF[0]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(0));
86+
separationOuterTOF[0]->Fill(track.pt(), track.eta(), track.nSigmaOuterTOF(0));
87+
// separationRICH[0]->Fill(track.pt(), track.eta(), track.nSigmaElectronRich() );
88+
break;
89+
case 321: // pion-kaon separation
90+
separationInnerTOF[1]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(1));
91+
separationOuterTOF[1]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(1));
92+
// separationRICH[1]->Fill(track.pt(), track.eta(), track.nSigmaPionRich() );
93+
break;
94+
case 2212: // kaon-proton separation
95+
separationInnerTOF[2]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(2));
96+
separationOuterTOF[2]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(2));
97+
// separationRICH[2]->Fill((track.nSigmaKaonRich() > 3.f), track.pt(), track.eta());
98+
default:
99+
break;
100+
}
101+
}
102+
}
103+
}
104+
};
105+
106+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask<pidSeparationPower>(cfgc)}; }

0 commit comments

Comments
 (0)