Skip to content

Object Ranges

Just like there is an ObjectId corresponding to a single xAOD object, there is also an ObjectRange corresponding to an entire xAOD container. Just like for ObjectId it is specialized for the different containers, e.g. there is a MuonRange corresponding to the xAOD::MuonContainer.

In columnar mode an ObjectRange corresponds to an index range (plus a data pointer), essentially a begin-index end-index pair. Unlike xAOD mode an ObjectRange in columnar mode can correspond to multiple events. To match the behavior in xAOD mode the ranges in the ObjectRange can only correspond to whole events not subsets of events.

Object Column Accessors

There is the special ObjectColumn accessor that allows to get the ObjectRange for a given event:

MuonAccessor<ObjectColumn> muonsAcc {*this, "AnalysisMuons"};

This then can be used to access the muons for a given event:

EventId event = ...;
MuonRange muons = muonsAcc (event);
or for multiple events:
EventRange events = ...;
MuonRange muons = muonsAcc (events);

Beyond allowing access to the objects this also declares the name of the container in the input file. This may sound similar to data handles in Athena, but it is so far only used for columnar mode. To use it in xAOD mode (for AthenaMT) we'd need more configurability of the connected container, and handling of systematics.

Even if you don't access a given object type directly, e.g. you look up the linked track for a lepton, you should generally still declare an ObjectColumn accessor for every single container you use, just to connect it to the right container in the input file.

Optional ObjectRange

Currently there is no OptObjectRange, not because it would be difficult to implement, but because we haven't had a use for it.

View Containers

There is no direct view container support for ObjectRange. If you have an xAOD view container that will work with ObjectRange just fine, but you can't pass or create a view container in columnar mode. The reason is that they would need a different memory layout (it's not just an index range, but an index column), and while we could implement it we had no need for it so far (it also wouldn't be an ObjectRange but something separate).

In the CP Algorithms we used to use view containers extensively, but essentially got rid of them completely in favor of (pre)selection decorations. Since we can do the same in columnar mode, we generally assume that we will not need view containers, but expect tools to read a preselection flag from a column/decoration.

If you need a view container solely for internal use, you can put your ObjectId inside an std::vector and you should get roughly the behavior you are looking for. However, this doesn't allow passing the "view container" between tools, and should only be done when the functionality is needed.

Shallow Copies

There is generally no support for shallow copies. In xAOD mode shallow copies can still be passed in and run on, but we can't create them. For CP Tools that is generally fine, as shallow copies are usually done in the surrounding code, not the CP Tool itself.

In columnar mode shallow copies have to be done in a different fashion: Essentially what a shallow copy does is intercept the name-column lookup with some columns coming from the original objects and others from the copied object. However, in columnar mode the user passes in raw columns, and the name-column lookup has already happened. So if the user wants shallow copy functionality it has to happen in user code (or more realistically in their columnar framework), not in the columnar tool or columnar infrastructure.

Deep Copies

Deep copies are not supported at all. A deep copy involves creating a new object from scratch, including all the associated decorations/columns and then copying over the values for the selected objects. Technically it is tricky to create new objects from scratch, or columns that have a length not known prior to the call, so it's not supported. The copying is also at odds with how columnar code is meant to work.

Reverse Event Store Lookups

For xAOD containers you can generally ask what is the name of the container in the event store (if it has been registered in the event store). This is not supported for columnar code, as the columnar infrastructure doesn't model an event store and wraps raw columns instead.

If you need this in xAOD mode you can still do that using xAOD only code:

if constexpr (ColumnarModeDefault::isXAOD) { ... }
Just make sure that you have a reasonable behavior in columnar mode as well.