Creating and Filling Histograms

Last update: 11 Mar 2024 [History] [Edit]

In a typical analysis workflow, you will want to process the information in an xAOD and write outputs to histograms or a TTree (known as an ntuple) for further analysis processing. In this section, you will be shown how to create and fill histograms using this framework. You will be shown how to make an ntuple in a later section.

There are several ways to manage histograms, but here we will show a way that allows you to manage histograms in the same way whether you are running your algorithm in EventLoop or Athena. Using a histogram is typically a two-step process, first you book the histogram indicating the name, binning, etc. then you fill the histogram. As an example let’s use the eventNumber that we’ve already printed out. Later in the tutorial, you will be asked to produce histograms for objects such as electrons and muons.

First, add the following include to MyxAODAnalysis.h:

#include <TH1.h>

tip Ordinarily, it would be better to put this in MyxAODAnalysis.cxx, but we will need it in the header file later, so we may as well put it there now.

Booking should happen in the initialize() function of your algorithm. Though in exceptional cases you may want to delay this to the processing of the first event. (In case the creation of the histogram depends on what sort of sample you are processing.) Either way you call:

  // Book run number histogram
  ANA_CHECK (book (TH1F ("runNumber", "runNumber", 10, 284495, 284505)));

  // Book event number histogram
  ANA_CHECK (book (TH1F ("eventNumber", "eventNumber", 100, 394.445e6, 394.455e6)));

tip Note that the binning defined here is very specific to the input file. This is meant to simply be an example of how to book and fill histograms. In an analysis scenario, you likely wouldn’t be filling eventNumber or runNumber histograms and therefore wouldn’t need to fine tune the binning like this.

Whenever possible, you should put this in initialize() because it is called before processing any events and makes sure that the histogram gets created even if we don’t process any events.

Now, you need to access the run number and event number from eventInfo. You already did this when you printed the values to the screen, but now let’s store them as local variables before filling the histograms. First, define two private variables in MyxAODAnalysis.h:

  // Event identifier variables
  unsigned int m_runNumber = 0; //< Run number
  unsigned long long m_eventNumber = 0; //< Event number

Then set the variables in MyxAODAnalysis.cxx in the execute() function:

  // Access run number and event number and store as local variables
  m_runNumber = eventInfo->runNumber ();
  m_eventNumber = eventInfo->eventNumber ();

Finally, inside execute() let’s fill the histograms with the eventNumber information we’ve already retrieved:

  // Fill run number and event number histograms
  hist ("runNumber")->Fill (m_runNumber);
  hist ("eventNumber")->Fill (m_eventNumber);

That is it on the c++ side. Now let’s compile your code.

Running and locating output histograms

To now successfully run your updated code, you need to do slightly different things depending on whether you are using EventLoop or Athena. In the following we describe these differences.

Outputs in EventLoop

EventLoop creates a file automatically for your output histograms, you don’t need to modify your job submission script at all to run your histogram writing algorithm.

Once your job is finished you can find the histogram(s) inside the unique directory you created at job submission (submitDir). There is a different file for each sample you submitted (hist-label.root), so in our case we have only one submitDir/hist-dataset. Please note that the second part of the histogram file name will correspond directly to the name of the sample in SampleHandler, while the first part (hist-) is set by EventLoop and cannot be changed.

tip Note that there is another output file in the hist directory called hist/dataset.root. This is not the file that contains your output histograms.

Outputs in Athena

The formalism is exactly the same as for trees. You need to tell the THistSvc service which file to write for the ANALYSIS stream. You can just add the following to your jobOptions to do this (see main Athena tutorial for more info):

jps.AthenaCommonFlags.HistOutputs = ["ANALYSIS:MyxAODAnalysis.outputs.root"]
svcMgr.THistSvc.MaxFileSize=-1 #speeds up jobs that output lots of histograms

tip Just as for trees, you can assign a different stream name to your algorithm, and create the output file with a different stream name. Allowing you to create multiple files from multiple algorithms.

Check, commit and push your changes

Check both histograms to make sure they were created and filled correctly.

If you are happy that the histograms are being filled properly, commit and push your changes.