Skip to content

Commit b9c3aea

Browse files
authored
Add files via upload
1 parent 99853ea commit b9c3aea

1 file changed

Lines changed: 185 additions & 0 deletions

File tree

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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 bcOccupancyQa.cxx
13+
/// \brief QA of the occupancy wrt bunch crossings: aod::BcOccsAll (all BCs of the TFs), produced by the event selection service
14+
///
15+
/// \author Igor Altsybeev <Igor.Altsybeev@cern.ch>
16+
17+
#include "Common/DataModel/EventSelection.h"
18+
19+
#include <Framework/AnalysisDataModel.h>
20+
#include <Framework/AnalysisTask.h>
21+
#include <Framework/Configurable.h>
22+
#include <Framework/HistogramRegistry.h>
23+
#include <Framework/HistogramSpec.h>
24+
#include <Framework/InitContext.h>
25+
#include <Framework/Logger.h>
26+
#include <Framework/OutputObjHeader.h>
27+
#include <Framework/runDataProcessing.h>
28+
29+
#include <TH1.h>
30+
#include <TH2.h>
31+
32+
#include <array>
33+
#include <cstdint>
34+
35+
using namespace o2;
36+
using namespace o2::framework;
37+
38+
struct BcOccupancyQaTask {
39+
Configurable<int> nBinsOccupancyByTracks{"nBinsOccupancyByTracks", 500, "number of bins for the occupancy by ITS tracks"};
40+
Configurable<float> maxOccupancyByTracks{"maxOccupancyByTracks", 25000., "upper edge of the axis for the occupancy by ITS tracks"};
41+
Configurable<int> nBinsOccupancyByFT0C{"nBinsOccupancyByFT0C", 500, "number of bins for the occupancy by FT0C amplitudes"};
42+
Configurable<float> maxOccupancyByFT0C{"maxOccupancyByFT0C", 250000., "upper edge of the axis for the occupancy by FT0C amplitudes"};
43+
Configurable<int> nBinsBcInTF{"nBinsBcInTF", 1188, "number of bins for the BC position in the TF"};
44+
Configurable<int> nOrbitsPerTF{"nOrbitsPerTF", 32, "number of orbits per TF, for the histograms vs BC position in the TF (128 in 2022)"};
45+
46+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
47+
48+
static constexpr int NFlags = 6;
49+
static constexpr std::array<int, NFlags> FlagBits = {aod::bcocc::kNoCollInTimeRangeNarrow, aod::bcocc::kNoCollInTimeRangeStrict, aod::bcocc::kNoCollInTimeRangeStandard,
50+
aod::bcocc::kNoCollInRofStrict, aod::bcocc::kNoCollInRofStandard, aod::bcocc::kNoHighMultCollInPrevRof};
51+
static constexpr std::array<const char*, NFlags> FlagNames = {"NoCollInTimeRangeNarrow", "NoCollInTimeRangeStrict", "NoCollInTimeRangeStandard",
52+
"NoCollInRofStrict", "NoCollInRofStandard", "NoHighMultCollInPrevRof"};
53+
static constexpr int NBCsPerOrbit = 3564;
54+
int64_t nBCsPerTF = 0;
55+
56+
void init(InitContext&)
57+
{
58+
nBCsPerTF = static_cast<int64_t>(nOrbitsPerTF.value) * NBCsPerOrbit;
59+
const AxisSpec axisOccupancyByTracks{nBinsOccupancyByTracks.value, 0., maxOccupancyByTracks.value, "occupancy by ITS tracks"};
60+
const AxisSpec axisOccupancyByFT0C{nBinsOccupancyByFT0C.value, 0., maxOccupancyByFT0C.value, "occupancy by FT0C amplitudes"};
61+
const AxisSpec axisMedianTime{280, -40., 100., "median time of the occupancy (#mus)"};
62+
const AxisSpec axisNumCollsInBC{11, -0.5, 10.5, "number of collisions found in the BC"};
63+
const AxisSpec axisBcInTF{nBinsBcInTF.value, 0., static_cast<double>(nBCsPerTF), "BC in TF"};
64+
const AxisSpec axisBcInOrbit{NBCsPerOrbit, -0.5, NBCsPerOrbit - 0.5, "BC in orbit"};
65+
const AxisSpec axisFlags{NFlags + 1, -0.5, NFlags + 0.5, ""};
66+
const AxisSpec axisBcCounter{3, -0.5, 2.5, ""};
67+
const AxisSpec axisIndexCheck{6, -0.5, 5.5, ""};
68+
69+
// all BCs
70+
histos.add("hBcCounter", "number of BCs", kTH1D, {axisBcCounter});
71+
histos.add("hNumCollsInBC", "all BCs", kTH1D, {axisNumCollsInBC});
72+
histos.add("hBcInTF", "all BCs", kTH1D, {axisBcInTF});
73+
// BCs with calculated occupancy
74+
histos.add("hBcInTFOccupancyDefined", "BCs with calculated occupancy", kTH1D, {axisBcInTF});
75+
histos.add("hOccupancyByTracks", "BCs with calculated occupancy", kTH1D, {axisOccupancyByTracks});
76+
histos.add("hOccupancyByFT0C", "BCs with calculated occupancy", kTH1D, {axisOccupancyByFT0C});
77+
histos.add("hOccupancyByTracksVsFT0C", "BCs with calculated occupancy", kTH2D, {axisOccupancyByFT0C, axisOccupancyByTracks});
78+
histos.add("hMedianTime", "BCs with calculated occupancy", kTH1D, {axisMedianTime});
79+
histos.add("pOccupancyByTracksVsBcInTF", "BCs with calculated occupancy;BC in TF;mean occupancy by ITS tracks", kTProfile, {axisBcInTF});
80+
histos.add("pOccupancyByTracksVsBcInOrbit", "BCs with calculated occupancy;BC in orbit;mean occupancy by ITS tracks", kTProfile, {axisBcInOrbit});
81+
// occupancy flags: first bin - all BCs with calculated occupancy, then the BCs with a given flag set
82+
histos.add("hOccupancyFlags", "BCs with calculated occupancy", kTH1D, {axisFlags});
83+
histos.add("hOccupancyFlagsVsOccupancyByTracks", "BCs with calculated occupancy", kTH2D, {axisFlags, axisOccupancyByTracks});
84+
// cross-check of the lookup by global BC (aod::bcocc::BcOccAllIndex)
85+
histos.add("hBcIndexCheck", "lookup in BcOccsAll by global BC", kTH1D, {axisIndexCheck});
86+
87+
auto hBcCounter = histos.get<TH1>(HIST("hBcCounter"));
88+
hBcCounter->GetXaxis()->SetBinLabel(1, "all");
89+
hBcCounter->GetXaxis()->SetBinLabel(2, "occupancy calculated");
90+
hBcCounter->GetXaxis()->SetBinLabel(3, "occupancy not available");
91+
auto hFlags = histos.get<TH1>(HIST("hOccupancyFlags"));
92+
auto hFlagsVsOcc = histos.get<TH2>(HIST("hOccupancyFlagsVsOccupancyByTracks"));
93+
hFlags->GetXaxis()->SetBinLabel(1, "all");
94+
hFlagsVsOcc->GetXaxis()->SetBinLabel(1, "all");
95+
for (int i = 0; i < NFlags; i++) {
96+
hFlags->GetXaxis()->SetBinLabel(i + 2, FlagNames[i]);
97+
hFlagsVsOcc->GetXaxis()->SetBinLabel(i + 2, FlagNames[i]);
98+
}
99+
auto hBcIndexCheck = histos.get<TH1>(HIST("hBcIndexCheck"));
100+
hBcIndexCheck->GetXaxis()->SetBinLabel(1, "BcOccsAll rows");
101+
hBcIndexCheck->GetXaxis()->SetBinLabel(2, "row found by its global BC");
102+
hBcIndexCheck->GetXaxis()->SetBinLabel(3, "BCs in aod::BCs");
103+
hBcIndexCheck->GetXaxis()->SetBinLabel(4, "BC found in BcOccsAll");
104+
hBcIndexCheck->GetXaxis()->SetBinLabel(5, "BC found, same global BC");
105+
hBcIndexCheck->GetXaxis()->SetBinLabel(6, "BC not found");
106+
}
107+
108+
void process(aod::BcOccsAll const& bcOccs, aod::BCs const& bcs)
109+
{
110+
// cross-check of the lookup by global BC: every BC of the BC table should be found, with the same global BC
111+
// (not found: BCs before the start of run, or no BcOccsAll entries for this DF)
112+
aod::bcocc::BcOccAllIndex bcOccAllIndexed(bcOccs);
113+
for (const auto& bc : bcs) {
114+
histos.fill(HIST("hBcIndexCheck"), 2);
115+
if (!bcOccAllIndexed.contains(bc.globalBC())) {
116+
histos.fill(HIST("hBcIndexCheck"), 5);
117+
continue;
118+
}
119+
histos.fill(HIST("hBcIndexCheck"), 3);
120+
if (bcOccAllIndexed[bc.globalBC()].globalBC() == bc.globalBC()) {
121+
histos.fill(HIST("hBcIndexCheck"), 4);
122+
}
123+
}
124+
125+
if (bcOccs.size() == 0) {
126+
return;
127+
}
128+
// BC position in the TF: the table contains complete TFs and TF starts differ by multiples of nBCsPerTF,
129+
// so bcInTF = (globalBC - globalBC of the first row) % nBCsPerTF; check that nOrbitsPerTF is consistent with the table
130+
const uint64_t firstGlobalBC = bcOccs.iteratorAt(0).globalBC();
131+
const uint64_t lastGlobalBC = bcOccs.iteratorAt(bcOccs.size() - 1).globalBC();
132+
const bool isBcInTFValid = (static_cast<int64_t>(bcOccs.size()) % nBCsPerTF == 0) && (static_cast<int64_t>((lastGlobalBC - firstGlobalBC) % nBCsPerTF) == nBCsPerTF - 1);
133+
if (!isBcInTFValid) {
134+
LOGP(warning, "BC occupancy QA: table size {} is not consistent with {} orbits per TF, no histograms vs BC in TF for this DF", bcOccs.size(), nOrbitsPerTF.value);
135+
}
136+
137+
for (const auto& bcOcc : bcOccs) {
138+
const uint64_t globalBC = bcOcc.globalBC();
139+
const int bcInTF = isBcInTFValid ? static_cast<int>((globalBC - firstGlobalBC) % nBCsPerTF) : -1;
140+
const int bcInOrbit = static_cast<int>(globalBC % NBCsPerOrbit);
141+
histos.fill(HIST("hBcCounter"), 0);
142+
histos.fill(HIST("hNumCollsInBC"), bcOcc.numCollsInBC());
143+
histos.fill(HIST("hBcIndexCheck"), 0);
144+
if (bcOccAllIndexed.contains(globalBC) && bcOccAllIndexed[globalBC].globalBC() == globalBC) { // global BCs are unique: same row
145+
histos.fill(HIST("hBcIndexCheck"), 1);
146+
}
147+
if (isBcInTFValid) {
148+
histos.fill(HIST("hBcInTF"), bcInTF);
149+
}
150+
151+
// occupancy is not available (BC is close to TF borders, or not selected for the calculation)
152+
const int occByTracks = bcOcc.trackOccupancyInTimeRange();
153+
const float occByFT0C = bcOcc.ft0cOccupancyInTimeRange();
154+
if (occByTracks < 0 || occByFT0C < 0) {
155+
histos.fill(HIST("hBcCounter"), 2);
156+
continue;
157+
}
158+
histos.fill(HIST("hBcCounter"), 1);
159+
histos.fill(HIST("hOccupancyByTracks"), occByTracks);
160+
histos.fill(HIST("hOccupancyByFT0C"), occByFT0C);
161+
histos.fill(HIST("hOccupancyByTracksVsFT0C"), occByFT0C, occByTracks);
162+
histos.fill(HIST("hMedianTime"), bcOcc.occupancyMedianTime());
163+
histos.fill(HIST("pOccupancyByTracksVsBcInOrbit"), bcInOrbit, occByTracks);
164+
if (isBcInTFValid) {
165+
histos.fill(HIST("hBcInTFOccupancyDefined"), bcInTF);
166+
histos.fill(HIST("pOccupancyByTracksVsBcInTF"), bcInTF, occByTracks);
167+
}
168+
169+
histos.fill(HIST("hOccupancyFlags"), 0);
170+
histos.fill(HIST("hOccupancyFlagsVsOccupancyByTracks"), 0, occByTracks);
171+
for (int i = 0; i < NFlags; i++) {
172+
if (bcOcc.occupancyFlags_bit(FlagBits[i])) {
173+
histos.fill(HIST("hOccupancyFlags"), i + 1);
174+
histos.fill(HIST("hOccupancyFlagsVsOccupancyByTracks"), i + 1, occByTracks);
175+
}
176+
}
177+
}
178+
}
179+
};
180+
181+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
182+
{
183+
return WorkflowSpec{
184+
adaptAnalysisTask<BcOccupancyQaTask>(cfgc)};
185+
}

0 commit comments

Comments
 (0)