Variant Link and Object Access¶
The general assumption in the columnar infrastructure is that when you
have an object you know exactly which container it belongs to. And for
the most part that works very well and is sufficient. However, sometimes
that simply doesn't work, you may have a link that can point to objects
in multiple containers, or may need to have uniform handling of objects
from multiple containers. In analogy to std::variant we use the name
variant for this access.
While this is by now pretty well supported and it is what you may be used to from the xAOD world (where that is integrated into all EDM objects), please only use it where actually necessary, e.g. for variant links that already exist in PHYSLITE or if otherwise you'd need to implement variant-like behavior yourself. In particular you don't need this if the same tool may be run on different containers in the same job. Each instance of the tool (or even each call to the tool) can operate on a different container without using variant code.
To use variants in your code, you first need to define a variant container, which could look like:
using MyTrackDef = VariantContainerId<ContainerId::track0,ContainerId::track0,ContainerId::track1>;
ContainerId::track0 is listed here twice,
with the first instance being used solely to determine the type the
variant should have in xAOD mode, i.e. it must correspond to an xAOD
type that is base to all other types. So if you used a variant over
muons and electrons, you could put ContainerId::particle there (for
xAOD::IParticle), even if you don't use a particle container.
You can then use that like a regular container as a template argument
for many of the columnar infrastructure template classes, e.g.
ObjectId, OptObjectId, ColumnAccessor. One notable exception for
that is the momentum accessor which currently doesn't support them, but
could have support added in the future.
Variant Links¶
For variant links we will typically use an ObjectLink not an
OptObjectId column. The ObjectLink is a bit more raw (think
ElementLink vs xAOD::IParticle*), and has some options for
inspection and converting to OptObjectId and ObjectId either for the
variant or individual containers.
Note that the ObjectLink was where the original variant support
started, essentially as a way to read the object links for
METAssociation in the columnar METMaker. As we seem to be adding
more and more complete support for variants we may take another look at
the ObjectLink and potentially phase it out, either completely or
relegate it to special cases in which it is actually beneficial.
Variant Accessors¶
You can also declare a column accessor for a variant:
ColumnAccessor<MyTrackDef,float> phiAcc {*this, "phi"};
ObjectId<MyTrackDef> but also
other compatible object ids.
However, please keep in mind that it is very easy to overdeclare the numberĀ of input columns you request. Instead of just declaring a single input column, it requires to declare one column per container in the variant. Sometimes that is exactly what you want, but other times you may just need or want it for one of them.