Knowing what information is in the xAOD

Last update: 26 Oct 2023 [History] [Edit]

One question everyone will have is: how do I know what physics object information/variables are actually stored in my xAOD for each type? You an be sure for “particles” (inheriting from IParticle) you will have things like pT, η, and φ. But what other variables are associated to the different object types? We’ll try to answer that question…

Containers and key names

In order to “retrieve” the information stored in the xAOD containers we need to know the container type and the container key name. We will use a handy script called checkxAOD.py. If you have an xAOD file called xAOD.pool.root and want to know the containers and associated key names, do the following:

checkxAOD.py xAOD.pool.root

Note: You need to replace the fake xAOD.pool.root with the full path to an xAOD sample, for example:

checkxAOD.py $ALRB_TutorialData/mc16_13TeV.312276.aMcAtNloPy8EG_A14N30NLO_LQd_mu_ld_0p3_beta_0p5_2ndG_M1000.deriv.DAOD_PHYS.e7587_a875_r10201_p5001/DAOD_PHYS.30350968._000001.pool.root.1

Alternatively you can make a symbolic link using:

ln -s $ALRB_TutorialData/mc16_13TeV.312276.aMcAtNloPy8EG_A14N30NLO_LQd_mu_ld_0p3_beta_0p5_2ndG_M1000.deriv.DAOD_PHYS.e7587_a875_r10201_p5001/DAOD_PHYS.30350968._000001.pool.root.1 xAOD.pool.root

tip If you have not set ALRB_TutorialData in your current shell nor set it in your .bashrc file, you will need to set it before using it. For more details, see xAOD Samples.

The last column will show you the xAOD container names and types. When you are retrieving information you usually need to know the container type (for example xAOD::ElectronContainer) and the key name for the particular instance of that container you are interested in (for example "Electrons"). In your analysis you can ignore the Aux containers (for Auxiliary store), these hold some behind-the-scenes magic. You can also “mostly” ignore the versions like _v1. Most information in the xAOD is stored and retrieved via the Auxiliary store. The user doesn’t need to worry about this Auxiliary store, and only retrieves the interface from the event store (e.g. TEvent for ROOT standalone analysis). So now you should know the container type and key name. If you use the wrong key name the code will compile, but it will fail at run-time.

tip If you run the checkxAOD.py script on the file above (and generally in any file) you will see that the type printed for the "Electrons" container is actually DataVector<xAOD::Electron_v1>. The xAOD::ElectronContainer name is an alias we use for the DataVector<xAOD::Electron_v1> name in the file. Those aliases are centrally defined and one should always use the alias.
If you struggle with the translation, here is the rough guidance: In the file every object has a version suffix (_v1) that we don’t use and that should be ignored and is not part of the alias. In the file the Container objects are stored as DataVector<...>, but for the alias we replace the DataVector part with simply adding Container to the object name.

Variables inside the containers

The xAOD containers store xAOD objects. Each xAOD object has a set of associated variables that are part of their class definition. You can find documentation of all xAOD classes here.

In addition to the class variables, additional variables can be added as decorations to object containers (and can be accessed from individual objects). These variables can be seen directly using ROOT. To do this, make sure you have an analysis release set up and do:

root -l xAOD.pool.root
root [1] CollectionTree->Print("Electrons*")

You will get a printout of all variables you can access from that container (aka collection). Note that the variable name you will use in your code is the one that comes after the “.”, so for example you might see:

ElectronsAuxDyn.charge : vector<float>

So in your analysis code (after setting up the interface magic that will be discussed shortly), you can access this variable from the xAOD::Electron object by calling charge().