ATLAS Offline Software
Loading...
Searching...
No Matches
VariantExampleTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7//
8// includes
9//
10
12
13//
14// method implementations
15//
16
17namespace columnar
18{
19 VariantExampleTool ::
20 VariantExampleTool (const std::string& name)
21 : AsgTool (name)
22 {}
23
24
25
26 StatusCode VariantExampleTool ::
27 initialize ()
28 {
29 // give the base class a chance to initialize the column accessor
30 // backends
31 ANA_CHECK (initializeColumns());
32 return StatusCode::SUCCESS;
33 }
34
35
36
37 void VariantExampleTool ::
38 callSingleEvent (ElectronRange electrons, MuonRange muons) const
39 {
40 // First copy all the wanted particles into a vector of variant
41 // objects. These then no longer care whether they are electrons or
42 // muons, they can be either. Effectively these acts like a "view"
43 // container, i.e. each entry still refers to the original container
44 // and there isn't a new aux/column store for the data being
45 // accessed.
46 //
47 // If you use variant object ids, there is a fair chance you are
48 // using this kind of pattern, as there aren't a lot of ways to get
49 // "variant" objects.
50 //
51 // Please note that in columnar mode it would be more efficient to
52 // embed this whole function inside `callEvents` and simply reset
53 // the vector at the start of each event. For a simple tool like
54 // this that saves about 33% of total execution time, but for
55 // purposes of demonstration and testing the current setup is
56 // simpler.
57 std::vector<ObjectId<MyVariantDef>> variantParticles;
58 variantParticles.reserve (electrons.size() + muons.size());
59 for (auto electron : electrons)
60 variantParticles.push_back(electron);
61 for (auto muon : muons)
62 variantParticles.push_back(muon);
63
64 for (auto& variantParticle : variantParticles)
65 {
66 // It is possible to check whether a given column is available,
67 // just as for regular column accessors. For variant objects that
68 // happens on a per-object basis, as some columns may not be
69 // defined for all objects. This is more to illustrate that it can
70 // be done, but will never trigger. Also, we didn't mark the
71 // column as optional, which means that at least in columnar mode the
72 // column is guaranteed to be there.
73 if (!ptAcc.isAvailable(variantParticle))
74 {
75 ANA_MSG_WARNING ("pt is not available for " << variantParticle);
76 throw std::runtime_error("pt is not available");
77 }
78 }
79
80 // sort the combined electron-muon vector by PT.
81 std::sort (variantParticles.begin(), variantParticles.end(),
82 [&](const auto& a, const auto& b) {
83 return ptAcc(a) > ptAcc(b);
84 });
85
86 // attach the PT rank decoration to each variant particle
87 for (std::size_t rank = 0; rank < variantParticles.size(); ++rank)
88 {
89 ptRankDec(variantParticles[rank]) = rank;
90 }
91
92 // sort the combined electron-muon vector by |eta|.
93 std::sort (variantParticles.begin(), variantParticles.end(),
94 [&](const auto& a, const auto& b) {
95 return std::abs (etaAcc(a)) < std::abs (etaAcc(b));
96 });
97
98 // attach the eta rank decoration to each variant particle
99 for (std::size_t rank = 0; rank < variantParticles.size(); ++rank)
100 {
101 // an example of how to convert to a specific container and do
102 // something just for that container. in this case we are just
103 // applying the same decoration under a different name, but it is
104 // hopefully clear how that could be utilized otherwise.
105 if (auto castObject = variantParticles[rank].tryGetVariant<ContainerId::electron>())
106 etaRankSpecialDec(*castObject) = rank;
107 }
108 }
109
110
111
112 void VariantExampleTool ::
113 callEvents (EventContextRange events) const
114 {
115 std::vector<ObjectId<MyVariantDef>> variantParticles;
116
117 // loop over all events and particles. note that this is
118 // deliberately looping by value, as the ID classes are very small
119 // and can be copied cheaply. this could have also been written as
120 // a single loop over all particles in the event range, but I chose
121 // to split it up into two loops as most tools will need to do some
122 // per-event things, e.g. retrieve `EventInfo`.
123 for (columnar::EventContextId event : events)
124 {
125 // variantParticles.clear();
126 // auto electrons = electronsHandle(event);
127 // auto muons = muonsHandle(event);
128 // for (auto electron : electrons)
129 // variantParticles.push_back(electron);
130 // for (auto muon : muons)
131 // variantParticles.push_back(muon);
132 // std::sort (variantParticles.begin(), variantParticles.end(),
133 // [&](const auto& a, const auto& b) {
134 // return ptAcc(a) > ptAcc(b);
135 // });
136 // for (std::size_t rank = 0; rank < variantParticles.size(); ++rank)
137 // {
138 // ptRankDec(variantParticles[rank]) = rank;
139
140 // // an example of how to convert to a specific
141 // if (auto castObject = variantParticles[rank].tryGetVariant<ContainerId::electron>())
142 // ptRankSpecialDec(*castObject) = rank;
143 // }
145 }
146 }
147}
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
static Double_t a
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
ColumnDecorator< MyVariantDef, std::uint16_t > ptRankDec
the pt-rank decorator for the variant container
ElectronAccessor< ObjectColumn > electronsHandle
the object accessor for the underlying containers
MuonAccessor< ObjectColumn > muonsHandle
ColumnDecorator< ContainerId::electron, std::uint16_t > etaRankSpecialDec
a eta-rank decorator just for electrons
void callSingleEvent(ElectronRange electrons, MuonRange muons) const
ColumnAccessor< MyVariantDef, float > ptAcc
the pt and eta accessors for the variant container
ObjectRange< ContainerId::eventContext > EventContextRange
ObjectId< ContainerId::eventContext > EventContextId
ObjectRange< ContainerId::muon > MuonRange
Definition MuonDef.h:24
ObjectRange< ContainerId::electron > ElectronRange
Definition EgammaDef.h:37
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.