Skip to content

Commit 38f9bb1

Browse files
committed
[PWGJE,EMCAL-670] Add BC selection to EMCal QA task
- Add Core/utilsBcSelEMC.h where EMCEventSelection struct is defined with configurables to select BCs based on different selection bits. - Add EMCEventSelection to emcEventSelectionQA.cxx
1 parent fcef305 commit 38f9bb1

File tree

2 files changed

+266
-0
lines changed

2 files changed

+266
-0
lines changed

PWGJE/Core/utilsBcSelEMC.h

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
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 utilsBcSelEMC.h
13+
/// \brief BC selection utilities for EMCal QA
14+
/// \author Marvin Hemmer <marvin.hemmer@cern.ch>, Goethe-University
15+
16+
#ifndef PWGJE_CORE_UTILSBCSELEMC_H_
17+
#define PWGJE_CORE_UTILSBCSELEMC_H_
18+
19+
#include <memory> // std::shared_ptr
20+
#include <string> // std::string
21+
22+
#include "Framework/Configurable.h"
23+
#include "Framework/HistogramRegistry.h"
24+
#include "Framework/HistogramSpec.h"
25+
#include "Framework/OutputObjHeader.h"
26+
27+
#include "Common/CCDB/EventSelectionParams.h"
28+
29+
namespace o2::emc_evsel
30+
{
31+
// event rejection types
32+
enum EventRejection {
33+
None = 0,
34+
Trigger,
35+
TvxTrigger,
36+
TimeFrameBorderCut,
37+
ItsRofBorderCut,
38+
IsGoodZvtxFT0vsPV,
39+
NoSameBunchPileup,
40+
NoCollInTimeRangeNarrow,
41+
NoCollInTimeRangeStandard,
42+
NoCollInRofStandard,
43+
NEventRejection
44+
};
45+
46+
o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""};
47+
48+
/// \brief Function to put labels on monitoring histogram
49+
/// \param hRejection monitoring histogram
50+
template <typename Histo>
51+
void setEventRejectionLabels(Histo& hRejection)
52+
{
53+
// Puts labels on the bc monitoring histogram.
54+
hRejection->GetXaxis()->SetBinLabel(EventRejection::None + 1, "All");
55+
hRejection->GetXaxis()->SetBinLabel(EventRejection::Trigger + 1, "Trigger");
56+
hRejection->GetXaxis()->SetBinLabel(EventRejection::TvxTrigger + 1, "TVX Trigger");
57+
hRejection->GetXaxis()->SetBinLabel(EventRejection::TimeFrameBorderCut + 1, "TF border");
58+
hRejection->GetXaxis()->SetBinLabel(EventRejection::ItsRofBorderCut + 1, "ITS ROF border");
59+
hRejection->GetXaxis()->SetBinLabel(EventRejection::IsGoodZvtxFT0vsPV + 1, "PV #it{z} consistency FT0 timing");
60+
hRejection->GetXaxis()->SetBinLabel(EventRejection::NoSameBunchPileup + 1, "No same-bunch pile-up"); // POTENTIALLY BAD FOR BEAUTY ANALYSES
61+
hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInTimeRangeNarrow + 1, "No coll timerange narrow");
62+
hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInTimeRangeStandard + 1, "No coll timerange strict");
63+
hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInRofStandard + 1, "No coll in ROF std");
64+
}
65+
66+
struct EMCEventSelection : o2::framework::ConfigurableGroup {
67+
std::string prefix = "emcBcSel"; // JSON group name
68+
// event selection parameters (in chronological order of application)
69+
o2::framework::Configurable<bool> useSel8Trigger{"useSel8Trigger", true, "Apply the sel8 event selection"};
70+
o2::framework::Configurable<int> triggerClass{"triggerClass", -1, "Trigger class different from sel8 (e.g. kINT7 for Run2) used only if useSel8Trigger is false"};
71+
o2::framework::Configurable<bool> useTvxTrigger{"useTvxTrigger", true, "Apply TVX trigger sel"};
72+
o2::framework::Configurable<bool> useTimeFrameBorderCut{"useTimeFrameBorderCut", true, "Apply TF border cut"};
73+
o2::framework::Configurable<bool> useItsRofBorderCut{"useItsRofBorderCut", true, "Apply ITS ROF border cut"};
74+
o2::framework::Configurable<bool> useIsGoodZvtxFT0vsPV{"useIsGoodZvtxFT0vsPV", false, "Check consistency between PVz from central barrel with that from FT0 timing"};
75+
o2::framework::Configurable<bool> useNoSameBunchPileup{"useNoSameBunchPileup", false, "Exclude collisions in bunches with more than 1 reco. PV"}; // POTENTIALLY BAD FOR BEAUTY ANALYSES
76+
o2::framework::Configurable<bool> useNoCollInTimeRangeNarrow{"useNoCollInTimeRangeNarrow", false, "Reject collisions in time range narrow"};
77+
o2::framework::Configurable<bool> useNoCollInTimeRangeStandard{"useNoCollInTimeRangeStandard", false, "Reject collisions in time range strict"};
78+
o2::framework::Configurable<bool> useNoCollInRofStandard{"useNoCollInRofStandard", false, "Reject collisions in ROF standard"};
79+
o2::framework::Configurable<std::string> softwareTrigger{"softwareTrigger", "", "Label of software trigger. Multiple triggers can be selected dividing them by a comma. Set None if you want bcs that are not selected by any trigger"};
80+
81+
// histogram names
82+
static constexpr char NameHistBCs[] = "hBCs";
83+
84+
std::shared_ptr<TH1> hBCs;
85+
86+
int currentRun{-1};
87+
88+
/// \brief Adds bc monitoring histograms in the histogram registry.
89+
/// \param registry reference to the histogram registry
90+
void addHistograms(o2::framework::HistogramRegistry& registry)
91+
{
92+
hBCs = registry.add<TH1>(NameHistBCs, "EMC event counter;;# of accepted collisions", {o2::framework::HistType::kTH1D, {axisEvents}});
93+
setEventRejectionLabels(hBCs);
94+
}
95+
96+
/// \brief Applies event selection.
97+
/// \tparam useEvSel use information from the EvSel table
98+
/// \param bc bc to test against the selection criteria
99+
/// \return bitmask with the event selection criteria not satisfied by the bc
100+
template <bool useEvSel, typename Bc>
101+
uint16_t getEMCCollisionRejectionMask(const Bc& bc)
102+
{
103+
uint16_t rejectionMask{0}; // 16 bits, in case new ev. selections will be added
104+
105+
if constexpr (useEvSel) {
106+
/// trigger condition
107+
bool sel8 = bc.selection_bit(o2::aod::evsel::kIsBBT0A) && bc.selection_bit(o2::aod::evsel::kIsBBT0C);
108+
if ((useSel8Trigger && sel8) || (!useSel8Trigger && triggerClass > -1 && !bc.alias_bit(triggerClass))) {
109+
SETBIT(rejectionMask, EventRejection::Trigger);
110+
}
111+
/// TVX trigger selection
112+
if (useTvxTrigger && !bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) {
113+
SETBIT(rejectionMask, EventRejection::TvxTrigger);
114+
}
115+
/// time frame border cut
116+
if (useTimeFrameBorderCut && !bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
117+
SETBIT(rejectionMask, EventRejection::TimeFrameBorderCut);
118+
}
119+
/// ITS rof border cut
120+
if (useItsRofBorderCut && !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
121+
SETBIT(rejectionMask, EventRejection::ItsRofBorderCut);
122+
}
123+
/// PVz consistency tracking - FT0 timing
124+
if (useIsGoodZvtxFT0vsPV && !bc.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) {
125+
SETBIT(rejectionMask, EventRejection::IsGoodZvtxFT0vsPV);
126+
}
127+
/// remove collisions in bunches with more than 1 reco bc
128+
/// POTENTIALLY BAD FOR BEAUTY ANALYSES
129+
if (useNoSameBunchPileup && !bc.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) {
130+
SETBIT(rejectionMask, EventRejection::NoSameBunchPileup);
131+
}
132+
/// No collisions in time range narrow
133+
if (useNoCollInTimeRangeNarrow && !bc.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) {
134+
SETBIT(rejectionMask, EventRejection::NoCollInTimeRangeNarrow);
135+
}
136+
/// No collisions in time range strict
137+
if (useNoCollInTimeRangeStandard && !bc.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) {
138+
SETBIT(rejectionMask, EventRejection::NoCollInTimeRangeStandard);
139+
}
140+
/// No collisions in ROF standard
141+
if (useNoCollInRofStandard && !bc.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) {
142+
SETBIT(rejectionMask, EventRejection::NoCollInRofStandard);
143+
}
144+
}
145+
return rejectionMask;
146+
}
147+
148+
/// \brief Fills histograms for monitoring event selections satisfied by the bc.
149+
/// \param bc analysed bc
150+
/// \param rejectionMask bitmask storing the info about which ev. selections are not satisfied by the bc
151+
template <typename Bc>
152+
void fillHistograms(Bc const& bc, const uint16_t rejectionMask)
153+
{
154+
hBCs->Fill(EventRejection::None);
155+
for (std::size_t reason = 1; reason < EventRejection::NEventRejection; reason++) {
156+
if (TESTBIT(rejectionMask, reason)) {
157+
return;
158+
}
159+
hBCs->Fill(reason);
160+
}
161+
}
162+
};
163+
164+
struct EMCEventSelectionMc {
165+
// event selection parameters (in chronological order of application)
166+
bool useSel8Trigger{false}; // Apply the Sel8 selection
167+
bool useTvxTrigger{false}; // Apply the TVX trigger
168+
bool useTimeFrameBorderCut{true}; // Apply TF border cut
169+
bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut
170+
171+
// histogram names
172+
static constexpr char NameHistNSplitVertices[] = "hNSplitVertices";
173+
std::shared_ptr<TH1> hNSplitVertices;
174+
static constexpr char NameHistParticles[] = "hParticles";
175+
std::shared_ptr<TH1> hParticles;
176+
177+
/// \brief Adds bc monitoring histograms in the histogram registry.
178+
/// \param registry reference to the histogram registry
179+
void addHistograms(o2::framework::HistogramRegistry& registry)
180+
{
181+
hNSplitVertices = registry.add<TH1>(NameHistNSplitVertices, "EMC split vertices counter;;# of reconstructed collisions per mc bc", {o2::framework::HistType::kTH1D, {{4, 1., 5.}}});
182+
hParticles = registry.add<TH1>(NameHistParticles, "EMC particle counter;;# of accepted particles", {o2::framework::HistType::kTH1D, {axisEvents}});
183+
// Puts labels on the bc monitoring histogram.
184+
setEventRejectionLabels(hParticles);
185+
}
186+
187+
void configureFromDevice(const o2::framework::DeviceSpec& device)
188+
{
189+
for (const auto& option : device.options) {
190+
if (option.name.compare("emcEvSel.useSel8Trigger") == 0) {
191+
useSel8Trigger = option.defaultValue.get<bool>();
192+
} else if (option.name.compare("emcEvSel.useTvxTrigger") == 0) {
193+
useTvxTrigger = option.defaultValue.get<bool>();
194+
} else if (option.name.compare("emcEvSel.useTimeFrameBorderCut") == 0) {
195+
useTimeFrameBorderCut = option.defaultValue.get<bool>();
196+
} else if (option.name.compare("emcEvSel.useItsRofBorderCut") == 0) {
197+
useItsRofBorderCut = option.defaultValue.get<bool>();
198+
}
199+
}
200+
}
201+
202+
/// \brief Function to apply event selections to generated MC collisions
203+
/// \param mcCollision MC bc to test against the selection criteria
204+
/// \param collSlice collection of reconstructed collisions
205+
/// \return a bitmask with the event selections not satisfied by the analysed bc
206+
template <typename TBc, typename CCs, typename TMcColl>
207+
uint16_t getEMCMcCollisionRejectionMask(TMcColl const& mcCollision, CCs const& collSlice)
208+
{
209+
uint16_t rejectionMask{0};
210+
float zPv = mcCollision.posZ();
211+
auto bc = mcCollision.template bc_as<TBc>();
212+
213+
/// Sel8 trigger selection
214+
if (useSel8Trigger && (!bc.selection_bit(o2::aod::evsel::kIsTriggerTVX) || !bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) || !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))) {
215+
SETBIT(rejectionMask, EventRejection::Trigger);
216+
}
217+
/// TVX trigger selection
218+
if (useTvxTrigger && !bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) {
219+
SETBIT(rejectionMask, EventRejection::TvxTrigger);
220+
}
221+
/// time frame border cut
222+
if (useTimeFrameBorderCut && !bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
223+
SETBIT(rejectionMask, EventRejection::TimeFrameBorderCut);
224+
}
225+
/// ITS RO frame border cut
226+
if (useItsRofBorderCut && !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
227+
SETBIT(rejectionMask, EventRejection::ItsRofBorderCut);
228+
}
229+
return rejectionMask;
230+
}
231+
232+
/// \brief Fills histogram for monitoring event selections satisfied by the bc.
233+
/// \param bc analysed bc
234+
/// \param rejectionMask bitmask storing the info about which ev. selections are not satisfied by the bc
235+
template <typename Bc>
236+
void fillHistograms(Bc const& mcCollision, const uint16_t rejectionMask, int nSplitColl = 0)
237+
{
238+
hParticles->Fill(EventRejection::None);
239+
240+
for (std::size_t reason = 1; reason < EventRejection::NEventRejection; reason++) {
241+
if (TESTBIT(rejectionMask, reason)) {
242+
return;
243+
}
244+
hParticles->Fill(reason);
245+
}
246+
}
247+
};
248+
} // namespace o2::emc_evsel
249+
250+
#endif // PWGJE_CORE_UTILSBCSELEMC_H_

PWGJE/Tasks/emcEventSelectionQA.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,20 @@
2222
#include "Framework/HistogramRegistry.h"
2323

2424
#include "Common/DataModel/EventSelection.h"
25+
#include "PWGJE/Core/utilsBcSelEMC.h"
2526

2627
using namespace o2;
2728
using namespace o2::framework;
2829
using namespace o2::framework::expressions;
30+
using namespace o2::emc_evsel;
2931

3032
using BCEvSels = o2::soa::Join<o2::aod::BCs, o2::aod::BcSels>;
3133
using CollEventSels = o2::soa::Join<o2::aod::Collisions, o2::aod::EvSels>;
3234
using FilteredCells = o2::soa::Filtered<aod::Calos>;
3335

3436
struct EmcEventSelectionQA {
37+
38+
EMCEventSelection emcEvSel; // event selection and monitoring
3539
o2::framework::HistogramRegistry mHistManager{"EMCALEventSelectionQAHistograms"};
3640

3741
// Require EMCAL cells (CALO type 1)
@@ -96,6 +100,8 @@ struct EmcEventSelectionQA {
96100
initCollisionHistogram(mHistManager.get<TH1>(HIST("hCollisionMatchingDJ1")).get());
97101
initCollisionHistogram(mHistManager.get<TH1>(HIST("hCollisionMatchingEJ2")).get());
98102
initCollisionHistogram(mHistManager.get<TH1>(HIST("hCollisionMatchingDJ2")).get());
103+
104+
emcEvSel.addHistograms(mHistManager); // collision monitoring
99105
}
100106

101107
PresliceUnsorted<CollEventSels> perFoundBC = aod::evsel::foundBCId;
@@ -120,6 +126,11 @@ struct EmcEventSelectionQA {
120126
bool isEMCALreadout = false;
121127
auto bcID = bc.globalBC() % 3564;
122128

129+
// get bitmask with bc selection info
130+
const auto rejectionMask = emcEvSel.getEMCCollisionRejectionMask<true, BCEvSels::iterator>(bc);
131+
// monitor the satisfied event selections
132+
emcEvSel.fillHistograms(bc, rejectionMask);
133+
123134
if (bc.runNumber() > mRun3MinNumber) {
124135
// in case of run3 not all BCs contain EMCAL data, require trigger selection also for min. bias
125136
// in addition select also L0/L1 triggers as triggers with EMCAL in reaodut
@@ -134,6 +145,11 @@ struct EmcEventSelectionQA {
134145
}
135146
}
136147

148+
if (rejectionMask != 0) {
149+
// at least one event selection not satisfied --> reject the candidate
150+
continue;
151+
}
152+
137153
// Monitoring BCs with EMCAL trigger / readout / FIT trigger
138154
if (isEMCALreadout) {
139155
mHistManager.fill(HIST("hBCEmcalReadout"), bcID);

0 commit comments

Comments
 (0)