Skip to content

Commit 36265d4

Browse files
committed
Update TPC QA
- Use common utilities - Add track cuts in QA - Add event cuts in QA - Extend available QA plots
1 parent d0b9f48 commit 36265d4

3 files changed

Lines changed: 311 additions & 128 deletions

File tree

Common/Core/TableHelper.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
///
13+
/// \file TableHelper.h
14+
/// \author Nicolò Jacazio nicolo.jacazio@cern.ch
15+
/// \brief Base of utilities to build advanced tasks
16+
///
17+
18+
#include "Framework/InitContext.h"
19+
#include "Framework/RunningWorkflowInfo.h"
20+
#include <string>
21+
22+
/// Function to check if a table is required in a workflow
23+
bool isTableRequiredInWorkflow(o2::framework::InitContext& initContext, const std::string table)
24+
{
25+
auto& workflows = initContext.services().get<o2::framework::RunningWorkflowInfo const>();
26+
for (auto device : workflows.devices) {
27+
for (auto input : device.inputs) {
28+
if (input.matcher.binding == table) {
29+
return true;
30+
}
31+
}
32+
}
33+
return false;
34+
}

Common/TableProducer/PID/pidTPC.cxx

Lines changed: 132 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
///
1313
/// \file pidTPC.cxx
14-
/// \author Nicolo' Jacazio
14+
/// \author Nicolò Jacazio
1515
/// \brief Task to produce PID tables for TPC split for each particle with only the Nsigma information.
1616
/// Only the tables for the mass hypotheses requested are filled, the others are sent empty.
1717
///
@@ -25,6 +25,8 @@
2525
#include "Common/Core/PID/PIDResponse.h"
2626
#include "Common/Core/PID/PIDTPC.h"
2727
#include "Common/DataModel/TrackSelectionTables.h"
28+
#include "Common/DataModel/EventSelection.h"
29+
#include "TableHelper.h"
2830

2931
using namespace o2;
3032
using namespace o2::framework;
@@ -40,6 +42,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
4042

4143
#include "Framework/runDataProcessing.h"
4244

45+
/// Task to produce the TPC response table
4346
struct tpcPid {
4447
using Trks = soa::Join<aod::Tracks, aod::TracksExtra>;
4548
using Coll = aod::Collisions;
@@ -76,34 +79,31 @@ struct tpcPid {
7679
void init(o2::framework::InitContext& initContext)
7780
{
7881
// Checking the tables are requested in the workflow and enabling them
79-
auto& workflows = initContext.services().get<RunningWorkflowInfo const>();
80-
for (DeviceSpec device : workflows.devices) {
81-
for (auto input : device.inputs) {
82-
auto enableFlag = [&input](const std::string particle, Configurable<int>& flag) {
83-
const std::string table = "pidTPC" + particle;
84-
if (input.matcher.binding == table) {
85-
if (flag < 0) {
86-
flag.value = 1;
87-
LOG(info) << "Auto-enabling table: " + table;
88-
} else if (flag > 0) {
89-
flag.value = 1;
90-
LOG(info) << "Table enabled: " + table;
91-
} else {
92-
LOG(info) << "Table disabled: " + table;
93-
}
94-
}
95-
};
96-
enableFlag("El", pidEl);
97-
enableFlag("Mu", pidMu);
98-
enableFlag("Pi", pidPi);
99-
enableFlag("Ka", pidKa);
100-
enableFlag("Pr", pidPr);
101-
enableFlag("De", pidDe);
102-
enableFlag("Tr", pidTr);
103-
enableFlag("He", pidHe);
104-
enableFlag("Al", pidAl);
82+
auto enableFlag = [&](const std::string particle, Configurable<int>& flag) {
83+
const std::string table = "pidTPC" + particle;
84+
if (isTableRequiredInWorkflow(initContext, table)) {
85+
if (flag < 0) {
86+
flag.value = 1;
87+
LOG(info) << "Auto-enabling table: " + table;
88+
} else if (flag > 0) {
89+
flag.value = 1;
90+
LOG(info) << "Table enabled: " + table;
91+
} else {
92+
LOG(info) << "Table disabled: " + table;
93+
}
10594
}
106-
}
95+
};
96+
97+
enableFlag("El", pidEl);
98+
enableFlag("Mu", pidMu);
99+
enableFlag("Pi", pidPi);
100+
enableFlag("Ka", pidKa);
101+
enableFlag("Pr", pidPr);
102+
enableFlag("De", pidDe);
103+
enableFlag("Tr", pidTr);
104+
enableFlag("He", pidHe);
105+
enableFlag("Al", pidAl);
106+
107107
// Getting the parametrization parameters
108108
ccdb->setURL(url.value);
109109
ccdb->setTimestamp(timestamp.value);
@@ -172,12 +172,23 @@ struct tpcPid {
172172
}
173173
};
174174

175+
/// Task to produce the TPC QA plots
175176
struct tpcPidQa {
176177
static constexpr int Np = 9;
177178
static constexpr const char* pT[Np] = {"e", "#mu", "#pi", "K", "p", "d", "t", "^{3}He", "#alpha"};
178179
static constexpr std::string_view hnsigma[Np] = {"nsigma/El", "nsigma/Mu", "nsigma/Pi",
179180
"nsigma/Ka", "nsigma/Pr", "nsigma/De",
180181
"nsigma/Tr", "nsigma/He", "nsigma/Al"};
182+
static constexpr std::string_view hnsigmapt[Np] = {"nsigmapt/El", "nsigmapt/Mu", "nsigmapt/Pi",
183+
"nsigmapt/Ka", "nsigmapt/Pr", "nsigmapt/De",
184+
"nsigmapt/Tr", "nsigmapt/He", "nsigmapt/Al"};
185+
static constexpr std::string_view hnsigmapospt[Np] = {"nsigmapospt/El", "nsigmapospt/Mu", "nsigmapospt/Pi",
186+
"nsigmapospt/Ka", "nsigmapospt/Pr", "nsigmapospt/De",
187+
"nsigmapospt/Tr", "nsigmapospt/He", "nsigmapospt/Al"};
188+
static constexpr std::string_view hnsigmanegpt[Np] = {"nsigmanegpt/El", "nsigmanegpt/Mu", "nsigmanegpt/Pi",
189+
"nsigmanegpt/Ka", "nsigmanegpt/Pr", "nsigmanegpt/De",
190+
"nsigmanegpt/Tr", "nsigmanegpt/He", "nsigmanegpt/Al"};
191+
181192
HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::QAObject};
182193

183194
Configurable<int> logAxis{"logAxis", 0, "Flag to use a log momentum axis"};
@@ -187,73 +198,131 @@ struct tpcPidQa {
187198
Configurable<int> nBinsNSigma{"nBinsNSigma", 200, "Number of bins for the NSigma"};
188199
Configurable<float> minNSigma{"minNSigma", -10.f, "Minimum NSigma in range"};
189200
Configurable<float> maxNSigma{"maxNSigma", 10.f, "Maximum NSigma in range"};
201+
Configurable<int> applyEvSel{"applyEvSel", 0, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"};
202+
Configurable<bool> applyTrackCut{"applyTrackCut", false, "Flag to apply standard track cuts"};
203+
Configurable<bool> applyRapidityCut{"applyRapidityCut", false, "Flag to apply rapidity cut"};
190204

191205
template <uint8_t i>
192-
void addParticleHistos()
206+
void addParticleHistos(const AxisSpec& pAxis, const AxisSpec& ptAxis)
193207
{
194-
AxisSpec pAxis{nBinsP, minP, maxP, "#it{p} (GeV/#it{c})"};
195-
if (logAxis) {
196-
pAxis.makeLogaritmic();
197-
}
198-
const AxisSpec nSigmaAxis{nBinsNSigma, minNSigma, maxNSigma, Form("N_{#sigma}^{TPC}(%s)", pT[i])};
199-
200208
// NSigma
209+
const AxisSpec nSigmaAxis{nBinsNSigma, minNSigma, maxNSigma, Form("N_{#sigma}^{TPC}(%s)", pT[i])};
201210
histos.add(hnsigma[i].data(), Form("N_{#sigma}^{TPC}(%s)", pT[i]), kTH2F, {pAxis, nSigmaAxis});
211+
histos.add(hnsigmapt[i].data(), Form("N_{#sigma}^{TPC}(%s)", pT[i]), kTH2F, {ptAxis, nSigmaAxis});
212+
histos.add(hnsigmapospt[i].data(), Form("N_{#sigma}^{TPC}(%s)", pT[i]), kTH2F, {ptAxis, nSigmaAxis});
213+
histos.add(hnsigmanegpt[i].data(), Form("N_{#sigma}^{TPC}(%s)", pT[i]), kTH2F, {ptAxis, nSigmaAxis});
202214
}
203215

204216
void init(o2::framework::InitContext&)
205217
{
206-
218+
const AxisSpec multAxis{1000, 0.f, 1000.f, "Track multiplicity"};
219+
const AxisSpec vtxZAxis{100, -20, 20, "Vtx_{z} (cm)"};
220+
const AxisSpec pAxisPosNeg{nBinsP, -maxP, maxP, "Signed #it{p} (GeV/#it{c})"};
207221
AxisSpec pAxis{nBinsP, minP, maxP, "#it{p} (GeV/#it{c})"};
222+
AxisSpec ptAxis{nBinsP, minP, maxP, "#it{p}_{T} (GeV/#it{c})"};
208223
if (logAxis) {
224+
ptAxis.makeLogaritmic();
209225
pAxis.makeLogaritmic();
210226
}
211-
const AxisSpec vtxZAxis{100, -20, 20, "Vtx_{z} (cm)"};
212227
const AxisSpec dedxAxis{1000, 0, 1000, "d#it{E}/d#it{x} A.U."};
213228

214229
// Event properties
230+
auto h = histos.add<TH1>("event/evsel", "", kTH1F, {{10, 0.5, 10.5, "Ev. Sel."}});
231+
h->GetXaxis()->SetBinLabel(1, "Events read");
232+
h->GetXaxis()->SetBinLabel(2, "Passed ev. sel.");
233+
h->GetXaxis()->SetBinLabel(3, "Passed mult.");
234+
h->GetXaxis()->SetBinLabel(4, "Passed vtx Z");
235+
215236
histos.add("event/vertexz", "", kTH1F, {vtxZAxis});
237+
histos.add("event/multiplicity", "", kTH1F, {multAxis});
216238
histos.add("event/tpcsignal", "", kTH2F, {pAxis, dedxAxis});
239+
histos.add("event/signedtpcsignal", "", kTH2F, {pAxisPosNeg, dedxAxis});
217240

218-
addParticleHistos<0>();
219-
addParticleHistos<1>();
220-
addParticleHistos<2>();
221-
addParticleHistos<3>();
222-
addParticleHistos<4>();
223-
addParticleHistos<5>();
224-
addParticleHistos<6>();
225-
addParticleHistos<7>();
226-
addParticleHistos<8>();
241+
addParticleHistos<0>(pAxis, ptAxis);
242+
addParticleHistos<1>(pAxis, ptAxis);
243+
addParticleHistos<2>(pAxis, ptAxis);
244+
addParticleHistos<3>(pAxis, ptAxis);
245+
addParticleHistos<4>(pAxis, ptAxis);
246+
addParticleHistos<5>(pAxis, ptAxis);
247+
addParticleHistos<6>(pAxis, ptAxis);
248+
addParticleHistos<7>(pAxis, ptAxis);
249+
addParticleHistos<8>(pAxis, ptAxis);
227250
}
228251

229-
template <uint8_t i, typename T>
230-
void fillParticleHistos(const T& t, const float nsigma)
252+
template <o2::track::PID::ID id, typename T>
253+
void fillParticleHistos(const T& t, const float& nsigma)
231254
{
232-
histos.fill(HIST(hnsigma[i]), t.p(), nsigma);
255+
if (applyRapidityCut) {
256+
const float y = TMath::ASinH(t.pt() / TMath::Sqrt(PID::getMass2(id) + t.pt() * t.pt()) * TMath::SinH(t.eta()));
257+
if (abs(y) > 0.5) {
258+
return;
259+
}
260+
}
261+
// Fill histograms
262+
histos.fill(HIST(hnsigma[id]), t.p(), nsigma);
263+
histos.fill(HIST(hnsigmapt[id]), t.pt(), nsigma);
264+
if (t.sign() > 0) {
265+
histos.fill(HIST(hnsigmapospt[id]), t.pt(), nsigma);
266+
} else {
267+
histos.fill(HIST(hnsigmanegpt[id]), t.pt(), nsigma);
268+
}
233269
}
234270

235-
void process(aod::Collision const& collision, soa::Join<aod::Tracks, aod::TracksExtra,
236-
aod::pidTPCEl, aod::pidTPCMu, aod::pidTPCPi,
237-
aod::pidTPCKa, aod::pidTPCPr, aod::pidTPCDe,
238-
aod::pidTPCTr, aod::pidTPCHe, aod::pidTPCAl,
239-
aod::TrackSelection> const& tracks)
271+
void process(soa::Join<aod::Collisions, aod::EvSels>::iterator const& collision,
272+
soa::Join<aod::Tracks, aod::TracksExtra,
273+
aod::pidTPCEl, aod::pidTPCMu, aod::pidTPCPi,
274+
aod::pidTPCKa, aod::pidTPCPr, aod::pidTPCDe,
275+
aod::pidTPCTr, aod::pidTPCHe, aod::pidTPCAl,
276+
aod::TrackSelection> const& tracks)
240277
{
278+
histos.fill(HIST("event/evsel"), 1);
279+
if (applyEvSel == 1) {
280+
if (!collision.sel7()) {
281+
return;
282+
}
283+
} else if (applyEvSel == 2) {
284+
if (!collision.sel8()) {
285+
return;
286+
}
287+
}
288+
histos.fill(HIST("event/evsel"), 2);
289+
290+
float ntracks = 0;
291+
for (auto t : tracks) {
292+
if (applyTrackCut && !t.isGlobalTrack()) {
293+
continue;
294+
}
295+
ntracks += 1;
296+
}
297+
// if (0 && ntracks < 1) {
298+
// return;
299+
// }
300+
histos.fill(HIST("event/evsel"), 3);
301+
if (abs(collision.posZ()) > 10.f) {
302+
return;
303+
}
304+
histos.fill(HIST("event/evsel"), 4);
241305
histos.fill(HIST("event/vertexz"), collision.posZ());
306+
histos.fill(HIST("event/multiplicity"), ntracks);
242307

243308
for (auto t : tracks) {
309+
if (applyTrackCut && !t.isGlobalTrack()) {
310+
continue;
311+
}
244312
// const float mom = t.p();
245313
const float mom = t.tpcInnerParam();
246314
histos.fill(HIST("event/tpcsignal"), mom, t.tpcSignal());
315+
histos.fill(HIST("event/signedtpcsignal"), mom * t.sign(), t.tpcSignal());
247316
//
248-
fillParticleHistos<0>(t, t.tpcNSigmaEl());
249-
fillParticleHistos<1>(t, t.tpcNSigmaMu());
250-
fillParticleHistos<2>(t, t.tpcNSigmaPi());
251-
fillParticleHistos<3>(t, t.tpcNSigmaKa());
252-
fillParticleHistos<4>(t, t.tpcNSigmaPr());
253-
fillParticleHistos<5>(t, t.tpcNSigmaDe());
254-
fillParticleHistos<6>(t, t.tpcNSigmaTr());
255-
fillParticleHistos<7>(t, t.tpcNSigmaHe());
256-
fillParticleHistos<8>(t, t.tpcNSigmaAl());
317+
fillParticleHistos<PID::Electron>(t, t.tpcNSigmaEl());
318+
fillParticleHistos<PID::Muon>(t, t.tpcNSigmaMu());
319+
fillParticleHistos<PID::Pion>(t, t.tpcNSigmaPi());
320+
fillParticleHistos<PID::Kaon>(t, t.tpcNSigmaKa());
321+
fillParticleHistos<PID::Proton>(t, t.tpcNSigmaPr());
322+
fillParticleHistos<PID::Deuteron>(t, t.tpcNSigmaDe());
323+
fillParticleHistos<PID::Triton>(t, t.tpcNSigmaTr());
324+
fillParticleHistos<PID::Helium3>(t, t.tpcNSigmaHe());
325+
fillParticleHistos<PID::Alpha>(t, t.tpcNSigmaAl());
257326
}
258327
}
259328
};

0 commit comments

Comments
 (0)