Skip to content

Commit ec58799

Browse files
authored
[PWGUD,Tutorial] Add UD tutorial task for event selection with SGSelector (#13799)
1 parent 11f588a commit ec58799

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

Tutorials/PWGUD/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,9 @@ o2physics_add_dpl_workflow(udtutorial-07
5353
SOURCES UDTutorial_07.cxx
5454
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
5555
COMPONENT_NAME Analysis)
56+
57+
o2physics_add_dpl_workflow(udtutorial-08
58+
SOURCES UDTutorial_08.cxx
59+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::SGCutParHolder
60+
COMPONENT_NAME Analysis)
61+

Tutorials/PWGUD/UDTutorial_08.cxx

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+
// \brief UD tutorial demonstrating event selection using SGSelector. Processes raw AO2Ds. Dependency: o2-analysis-event-selection-service
13+
// \author Sigurd Nese
14+
// \since November 2025
15+
16+
#include "PWGUD/Core/SGSelector.h"
17+
18+
#include <Framework/AnalysisDataModel.h>
19+
#include <Framework/AnalysisTask.h>
20+
#include <Framework/runDataProcessing.h>
21+
22+
using namespace o2::framework;
23+
24+
// EvSels table contains connection between collision and BC
25+
using MyEvents = o2::soa::Join<o2::aod::Collisions, o2::aod::EvSels>;
26+
// BcSels table contains connection between BC and FIT info. Run3MatchedToBCSparse table contains index into ZDC table.
27+
using MyBCs = o2::soa::Join<o2::aod::BCs, o2::aod::BcSels, o2::aod::Run3MatchedToBCSparse>;
28+
29+
struct UDTutorial08 {
30+
31+
// Histogram setup
32+
OutputObj<TH1I> hSelectionResult{TH1I("hSelectionResult", "hSelectionResult", 5, -0.5, 4.5)};
33+
OutputObj<TH1I> hSelectionResultAfterCut{TH1I("hSelectionResultAfterCut", "hSelectionResultAfterCut", 5, -0.5, 4.5)};
34+
OutputObj<TH1F> hZNAEnergy{TH1F("hZNAEnergy", "hZNAEnergy", 200, 0, 20)};
35+
OutputObj<TH1F> hZNAEnergyAfterCut{TH1F("hZNAEnergyAfterCut", "hZNAEnergyAfterCut", 200, 0, 20)};
36+
OutputObj<TH1F> hZNCEnergy{TH1F("hZNCEnergy", "hZNCEnergy", 200, 0, 20)};
37+
OutputObj<TH1F> hZNCEnergyAfterCut{TH1F("hZNCEnergyAfterCut", "hZNCEnergyAfterCut", 200, 0, 20)};
38+
// Create instance of the selector class which runs the gap selection algorithm
39+
SGSelector sgSelector;
40+
// Create instance of cut holder class to contain the user defined cuts
41+
SGCutParHolder sgCuts = SGCutParHolder();
42+
43+
void init(o2::framework::InitContext&)
44+
{
45+
// Configure the gap selection criteria. Rest of the values are kept default
46+
sgCuts.SetNDtcoll(1); // Time range to consider, in units of collision time resolution
47+
sgCuts.SetMinNBCs(2); // Minimum number of BCs to check
48+
sgCuts.SetNTracks(2, 100); // Reject collisions with < 2 tracks and > 100 tracks
49+
sgCuts.SetMaxFITtime(34); // Reject collisions with FIT time > 34 ns in a compatible BC
50+
sgCuts.SetFITAmpLimits({-1, // Don't use the FV0A for selection
51+
150, // Require FT0A amplitude to be below 150 in all compatible BCs to classify as gap
52+
50, // Require FT0C amplitude to be below 50 in all compatible BCs to classify as gap
53+
-1, // Don't use the FDDA for selection
54+
-1}); // Don't use the FDDC for selection
55+
}
56+
57+
void process(MyEvents::iterator const& collision, // Process collision by collision
58+
MyBCs const& bcs, // We will check a range of bunch crossings
59+
o2::aod::FT0s const&, // Must subscribe to the FIT tables for the SGSelector to access them
60+
o2::aod::FDDs const&,
61+
o2::aod::FV0As const&,
62+
o2::aod::Zdcs const&) // Want to plot ZDC energies, so we need to subscribe to the ZDC table
63+
{
64+
// Find the bunch crossing assigned to this collision
65+
auto bc = collision.foundBC_as<MyBCs>();
66+
// Find the range of bunch crossings compatible with this collision
67+
auto bcRange = udhelpers::compatibleBCs(collision, sgCuts.NDtcoll(), bcs, sgCuts.minNBCs());
68+
// Determine whether this event is single gap (A or C), double gap, or no gap
69+
auto selectorResult = sgSelector.IsSelected(sgCuts, collision, bcRange, bc);
70+
auto newbc = *(selectorResult.bc);
71+
72+
// --- Process the event here: Apply cuts, save to derived tables, fill histograms... ---
73+
74+
// Plot the outcome of the gap selection algorithm
75+
hSelectionResult->Fill(selectorResult.value);
76+
// Plot ZDC energies
77+
if (newbc.has_zdc()) {
78+
auto zdc = newbc.zdc();
79+
hZNAEnergy->Fill(zdc.energyCommonZNA());
80+
hZNCEnergy->Fill(zdc.energyCommonZNC());
81+
} else {
82+
hZNAEnergy->Fill(-999);
83+
hZNCEnergy->Fill(-999);
84+
}
85+
86+
// Apply a selection -- as an example, keep only events classified as single gap on C side
87+
if (selectorResult.value != o2::aod::sgselector::SingleGapC) {
88+
return;
89+
}
90+
hSelectionResultAfterCut->Fill(selectorResult.value);
91+
if (newbc.has_zdc()) {
92+
auto zdc = newbc.zdc();
93+
hZNAEnergyAfterCut->Fill(zdc.energyCommonZNA());
94+
hZNCEnergyAfterCut->Fill(zdc.energyCommonZNC());
95+
} else {
96+
hZNAEnergyAfterCut->Fill(-999);
97+
hZNCEnergyAfterCut->Fill(-999);
98+
}
99+
}
100+
};
101+
102+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
103+
{
104+
return WorkflowSpec{
105+
adaptAnalysisTask<UDTutorial08>(cfgc, TaskName{"udtutorial08"})};
106+
}

0 commit comments

Comments
 (0)