Skip to content

Commit e1be4af

Browse files
authored
DPL Analysis: First workflow for event mixing (#3450)
1 parent 63c5c67 commit e1be4af

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

Analysis/Tutorials/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,8 @@ o2_add_executable(tracks-combinations
8686
SOURCES src/tracksCombinations.cxx
8787
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel
8888
COMPONENT_NAME AnalysisTutorial)
89+
90+
o2_add_executable(event-mixing
91+
SOURCES src/eventMixing.cxx
92+
PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel
93+
COMPONENT_NAME AnalysisTutorial)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
#include "Framework/runDataProcessing.h"
11+
#include "Framework/AnalysisTask.h"
12+
#include "Framework/ASoAHelpers.h"
13+
14+
namespace o2::aod
15+
{
16+
namespace hash
17+
{
18+
DECLARE_SOA_COLUMN(Bin, bin, int);
19+
} // namespace hash
20+
DECLARE_SOA_TABLE(Hashes, "AOD", "HASH", hash::Bin);
21+
22+
using Hash = Hashes::iterator;
23+
} // namespace o2::aod
24+
25+
using namespace o2;
26+
using namespace o2::framework;
27+
using namespace o2::soa;
28+
29+
// This is a tentative workflow to get mixed-event tracks
30+
// FIXME: this should really inherit from AnalysisTask but
31+
// we need GCC 7.4+ for that
32+
33+
struct HashTask {
34+
std::vector<float> xBins{-1.5f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 1.5f};
35+
std::vector<float> yBins{-1.5f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 1.5f};
36+
Produces<aod::Hashes> hashes;
37+
38+
// Calculate hash for an element based on 2 properties and their bins.
39+
int getHash(std::vector<float> const& xBins, std::vector<float> const& yBins, float colX, float colY)
40+
{
41+
for (int i = 0; i < xBins.size(); i++) {
42+
if (colX < xBins[i]) {
43+
for (int j = 0; j < yBins.size(); j++) {
44+
if (colY < yBins[j]) {
45+
return i + j * (xBins.size() + 1);
46+
}
47+
}
48+
// overflow for yBins only
49+
return i + yBins.size() * (xBins.size() + 1);
50+
}
51+
}
52+
53+
// overflow for xBins only
54+
for (int j = 0; j < yBins.size(); j++) {
55+
if (colY < yBins[j]) {
56+
return xBins.size() + j * (xBins.size() + 1);
57+
}
58+
}
59+
60+
// overflow for both bins
61+
return (yBins.size() + 1) * (xBins.size() + 1) - 1;
62+
}
63+
64+
void process(aod::Collisions const& collisions)
65+
{
66+
for (auto& collision : collisions) {
67+
int hash = getHash(xBins, yBins, collision.posX(), collision.posY());
68+
LOGF(info, "Collision: %d (%f, %f, %f) hash: %d", collision.index(), collision.posX(), collision.posY(), collision.posZ(), hash);
69+
hashes(hash);
70+
}
71+
}
72+
};
73+
74+
// Version 1: Using categorised combinations
75+
struct CollisionsCombinationsTask {
76+
void process(aod::Hashes const& hashes, aod::Collisions& collisions, aod::Tracks& tracks)
77+
{
78+
collisions.bindExternalIndices(&tracks);
79+
auto tracksTuple = std::make_tuple(tracks);
80+
AnalysisDataProcessorBuilder::GroupSlicer slicer(collisions, tracksTuple);
81+
82+
// Strictly upper categorised collisions
83+
for (auto& [c1, c2] : selfCombinations("fBin", join(hashes, collisions), join(hashes, collisions))) {
84+
LOGF(info, "Collisions bin: %d pair: %d (%f, %f, %f), %d (%f, %f, %f)", c1.bin(), c1.index(), c1.posX(), c1.posY(), c1.posZ(), c2.index(), c2.posX(), c2.posY(), c2.posZ());
85+
86+
auto it1 = slicer.begin();
87+
auto it2 = slicer.begin();
88+
for (auto& slice : slicer) {
89+
if (slice.groupingElement().index() == c1.index()) {
90+
it1 = slice;
91+
break;
92+
}
93+
}
94+
for (auto& slice : slicer) {
95+
if (slice.groupingElement().index() == c2.index()) {
96+
it2 = slice;
97+
break;
98+
}
99+
}
100+
auto tracks1 = std::get<aod::Tracks>(it1.associatedTables());
101+
tracks1.bindExternalIndices(&collisions);
102+
auto tracks2 = std::get<aod::Tracks>(it2.associatedTables());
103+
tracks2.bindExternalIndices(&collisions);
104+
105+
for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) {
106+
LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index());
107+
}
108+
}
109+
}
110+
};
111+
112+
// Version 2: Filtering instead of combinations
113+
// Possible only after filters & grouping upgrades
114+
// struct CollisionsFilteringTask {
115+
// Alternatively: filter/partition directly on collisions
116+
// expressions::Filter aod::hash::bin{0} == aod::hash::bin{1};
117+
118+
// Currently multiple grouping and grouping by Joins is not possible
119+
// void process(soa::Filtered<soa::Join<aod::Hashes, aod::Collisions>>::iterator const& hashedCol1, aod::Tracks const& tracks1,
120+
// soa::Filtered<soa::Join<aod::Hashes, aod::Collisions>>::iterator const& hashedCol2, aod::Tracks const& tracks2)
121+
//{
122+
// for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) {
123+
// LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), hashedCol1.index(), hashedCol2.index());
124+
// }
125+
//}
126+
// };
127+
128+
// What we would like to have
129+
struct MixedEventsTask {
130+
void process(aod::Collision const& col1, aod::Tracks const& tracks1, aod::Collision const& col2, aod::Tracks const& tracks2)
131+
{
132+
for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) {
133+
LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), col1.index(), col2.index());
134+
}
135+
}
136+
};
137+
138+
WorkflowSpec defineDataProcessing(ConfigContext const&)
139+
{
140+
return WorkflowSpec{
141+
adaptAnalysisTask<HashTask>("collisions-hashed"),
142+
adaptAnalysisTask<CollisionsCombinationsTask>("mixed-event-tracks")};
143+
}

0 commit comments

Comments
 (0)