ATLAS Offline Software
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 
17 namespace columnar
18 {
20  VariantExampleTool (const std::string& name)
21  : AsgTool (name)
22  {}
23 
24 
25 
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 
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 
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`.
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 }
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:196
columnar::VariantExampleTool::ptAcc
ColumnAccessor< MyVariantDef, float > ptAcc
the pt and eta accessors for the variant container
Definition: VariantExampleTool.h:94
columnar::VariantExampleTool::VariantExampleTool
VariantExampleTool(const std::string &name)
Definition: VariantExampleTool.cxx:20
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
columnar::ObjectRange
a class representing a continuous sequence of objects (a.k.a. a container)
Definition: ContainerId.h:177
python.DataFormatRates.events
events
Definition: DataFormatRates.py:105
columnar::VariantExampleTool::callEvents
virtual void callEvents(EventContextRange events) const override
Definition: VariantExampleTool.cxx:113
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
columnar::VariantExampleTool::ptRankDec
ColumnDecorator< MyVariantDef, std::uint16_t > ptRankDec
the pt-rank decorator for the variant container
Definition: VariantExampleTool.h:102
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ANA_MSG_WARNING
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:292
columnar::ObjectId
a class representing a single object (electron, muons, etc.)
Definition: ContainerId.h:178
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
columnar::VariantExampleTool::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: VariantExampleTool.cxx:27
columnar::VariantExampleTool::muonsHandle
MuonAccessor< ObjectColumn > muonsHandle
Definition: VariantExampleTool.h:67
columnar::VariantExampleTool::electronsHandle
ElectronAccessor< ObjectColumn > electronsHandle
the object accessor for the underlying containers
Definition: VariantExampleTool.h:66
a
TList * a
Definition: liststreamerinfos.cxx:10
VariantExampleTool.h
columnar::VariantExampleTool::etaRankSpecialDec
ColumnDecorator< ContainerId::electron, std::uint16_t > etaRankSpecialDec
a eta-rank decorator just for electrons
Definition: VariantExampleTool.h:108
columnar
Definition: ClusterDef.h:16
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
columnar::VariantExampleTool::callSingleEvent
void callSingleEvent(ElectronRange electrons, MuonRange muons) const
Definition: VariantExampleTool.cxx:38