ATLAS Offline Software
Public Types | Static Public Member Functions | Static Public Attributes | List of all members
columnar::VariantContainerId< CIBase, CIList > Struct Template Reference

a "variant" ContainerId More...

#include <VariantDef.h>

Collaboration diagram for columnar::VariantContainerId< CIBase, CIList >:

Public Types

using xAODObjectIdType = typename CIBase::xAODObjectIdType
 the xAOD type to use with ObjectId More...
 
using xAODObjectRangeType = typename CIBase::xAODObjectRangeType
 the xAOD type to use with ObjectRange More...
 
using xAODElementLinkType = typename CIBase::xAODElementLinkType
 the xAOD type to use with ElementLink More...
 
using baseId = CIBase
 
using mpCIList = boost::mp11::mp_list< CIList... >
 

Static Public Member Functions

template<ContainerIdConcept CI>
static constexpr bool isValidContainer ()
 
template<ContainerIdConcept CI>
static constexpr unsigned getVariantIndex ()
 get the index of the given container in the list More...
 

Static Public Attributes

static constexpr bool isContainerId = true
 identify this as a container id definition More...
 
static constexpr bool isMutable = CIBase::isMutable
 whether this is a non-const container More...
 
static constexpr bool perEventRange = false
 whether this can be retrieved as a range per event More...
 
static constexpr bool perEventId = false
 whether this can be retrieved as a single object per event More...
 
static constexpr std::size_t numVariants = sizeof...(CIList)
 
static constexpr std::array< std::string_view, numVariantsidNameArray = {CIList::idName...}
 

Detailed Description

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
struct columnar::VariantContainerId< CIBase, CIList >

a "variant" ContainerId

A "variant" ContainerId (CI) in this context means that an object id or link can refer to an object in one of several containers. This is contrasted with regular object ids or links, which are only ever associated with a single container. If you are wondering about the name, I named it after std::variant, as it seems like a similar concept.

While it may seem very convenient to be able to refer to more than a single container, it is actually a non-trivial thing to achieve in columnar mode, and should only be used when that capability is needed and can't be reasonably avoided. In practice that means use it when otherwise you would have to implement similar functionality in your own code.

This also only works with a fixed list of containers, not an open-ended list. As such you have to pass in a CIList... of container ids you intend to use with it. Further you need to pass a CIBase that isn't a possible variant container, but is used to define a common base class in xAOD mode. If you also want to use it as a possible "variant" container id, you need to list it twice.

Note that it is generally possible for variant links to refer to containers not in the list, but variant (non-optional) object ids are guaranteed to refer to a valid object in one of the containers.

It is possible to go from a variant id/link to a regular id, but due to the way it is implemented there are slight differences between modes: In xAOD mode it is based on dynamic_cast of underlying objects, whereas in columnar mode it is based on unique ids for each container. In practice that means that if you have e.g. multiple track containers in your variant you can (and have to) distinguish them in columnar mode, whereas in xAOD mode they will show up as belonging to each of the containers.

Note that in columnar mode if you are only interested in a single variant for a variant link, it is probably more efficient to query the link directly for the specific variant (as opposed to converting it to a variant object id first). However, the impact of this hasn't been benchmarked, so it is unclear whether it provides a significant performance benefit.

Implementation Details

In xAOD mode the object ids are represented as pointers to the base class (as identified via CIBase), and links are represented by a pointer to the proper ElementLink. Implementation-wise this is mostly pass through in xAOD mode, with no overhead compared to "regular" containers.

In columnar mode the object ids are represented as a pair of integers (and a data pointer), as opposed to the single integer for the regular columnar object ids. That second integer identifies the container the object belongs to, and is essentially just the index in the variant list.

Object links in columnar mode are a bit more complex, but at the heart they are still a pair of integers. However, in the persistent format the integer identifying the container can not be expected to correspond to the index in the variant list. Instead it is assumed to be a key that is unique for each container, and then there is another data-vector that holds the unique key for each "variant" container in order.

Variant accessors in columnar mode essentially just create N accessors internally, one for each variant container. This is necessary because the accessors are linked to the specific container they operate on. However that also means that the number of accessors can quickly balloon if a variant container has a large number of variants and accessors.

Definition at line 97 of file VariantDef.h.

Member Typedef Documentation

◆ baseId

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
using columnar::VariantContainerId< CIBase, CIList >::baseId = CIBase

Variant Specific Definitions

Definition at line 126 of file VariantDef.h.

◆ mpCIList

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
using columnar::VariantContainerId< CIBase, CIList >::mpCIList = boost::mp11::mp_list<CIList...>

Definition at line 146 of file VariantDef.h.

◆ xAODElementLinkType

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
using columnar::VariantContainerId< CIBase, CIList >::xAODElementLinkType = typename CIBase::xAODElementLinkType

the xAOD type to use with ElementLink

Definition at line 120 of file VariantDef.h.

◆ xAODObjectIdType

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
using columnar::VariantContainerId< CIBase, CIList >::xAODObjectIdType = typename CIBase::xAODObjectIdType

the xAOD type to use with ObjectId

Definition at line 114 of file VariantDef.h.

◆ xAODObjectRangeType

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
using columnar::VariantContainerId< CIBase, CIList >::xAODObjectRangeType = typename CIBase::xAODObjectRangeType

the xAOD type to use with ObjectRange

Definition at line 117 of file VariantDef.h.

Member Function Documentation

◆ getVariantIndex()

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
template<ContainerIdConcept CI>
static constexpr unsigned columnar::VariantContainerId< CIBase, CIList >::getVariantIndex ( )
inlinestaticconstexpr

get the index of the given container in the list

Definition at line 140 of file VariantDef.h.

141  {
142  constexpr unsigned index = boost::mp11::mp_find<std::tuple<CIList...>,CI>::value;
143  return index;
144  }

◆ isValidContainer()

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
template<ContainerIdConcept CI>
static constexpr bool columnar::VariantContainerId< CIBase, CIList >::isValidContainer ( )
inlinestaticconstexpr

Definition at line 133 of file VariantDef.h.

134  {
135  return (... || std::is_same_v<CI,CIList>);
136  }

Member Data Documentation

◆ idNameArray

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr std::array<std::string_view,numVariants> columnar::VariantContainerId< CIBase, CIList >::idNameArray = {CIList::idName...}
staticconstexpr

Definition at line 130 of file VariantDef.h.

◆ isContainerId

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr bool columnar::VariantContainerId< CIBase, CIList >::isContainerId = true
staticconstexpr

identify this as a container id definition

Definition at line 102 of file VariantDef.h.

◆ isMutable

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr bool columnar::VariantContainerId< CIBase, CIList >::isMutable = CIBase::isMutable
staticconstexpr

whether this is a non-const container

Definition at line 105 of file VariantDef.h.

◆ numVariants

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr std::size_t columnar::VariantContainerId< CIBase, CIList >::numVariants = sizeof...(CIList)
staticconstexpr

Definition at line 128 of file VariantDef.h.

◆ perEventId

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr bool columnar::VariantContainerId< CIBase, CIList >::perEventId = false
staticconstexpr

whether this can be retrieved as a single object per event

Definition at line 111 of file VariantDef.h.

◆ perEventRange

template<ContainerIdConcept CIBase, ContainerIdConcept... CIList>
constexpr bool columnar::VariantContainerId< CIBase, CIList >::perEventRange = false
staticconstexpr

whether this can be retrieved as a range per event

Definition at line 108 of file VariantDef.h.


The documentation for this struct was generated from the following file:
index
Definition: index.py:1
athena.value
value
Definition: athena.py:124
CI
std::map< std::string, HypoJetVector >::const_iterator CI
Definition: xAODJetCollector.h:18
DeMoScan.index
string index
Definition: DeMoScan.py:362