Using MET in Analysis

Last update: 14 Nov 2022 [History] [Edit]

Missing Transverse Energy needs to be calculated separately for each analysis because it is determined by the exact object definitions used. To do this, we first need to schedule the sequences for the objects we have not touched yet (photons and tau leptons). Then we define a new type of container that allows the MET tools to use only the objects we want and finally the MET sequence is scheduled.

At a minimum, the MET tools require a user-defined jet collection for calculation. Additionally, users can define other object collections to be used in MET calculation, but this is not required. Any energy in the detector that is not associated with user-defined object collections is independently incorporated into the MET calculation.

Create preselection decorations

In order to calculate MET, we need to make sure that only objects we care about are used. Each of the object analysis sequences creates a container and also decorates the objects with information indicating whether they pass the baseline quality and kinematic selection criteria. To simplify the MET configurations, we will combine the baseline and kinematic selection results to add a summary decoration called preselection.

To create the summary decorations, add the following code to makeSequence() in MyAnalysisAlgorithms.py where the jet summary preselection is applied:

    preselAlgEl = createAlgorithm( 'CP::AsgSelectionAlg','ElectronPreelectionAlg' )
    preselAlgEl.preselection = 'selectPtEta,as_char&&baselineSelection_loose,as_char'
    preselAlgEl.particles = 'AnaElectrons_%SYS%'
    preselAlgEl.selectionDecoration = 'preselection,as_char'
    algSeq += preselAlgEl

    preselAlgMu = createAlgorithm( 'CP::AsgSelectionAlg','MuonPreelectionAlg' )
    preselAlgMu.preselection = 'selectPtEta,as_char&&baselineSelection_medium,as_char'
    preselAlgMu.particles = 'AnaMuons_%SYS%'
    preselAlgMu.selectionDecoration = 'preselection,as_char'
    algSeq += preselAlgMu

Rerun to make sure the changes are implemented correctly.

Schedule MET calculation sequence

Now that we have our selected object containers, it is time to schedule the MET calculation. Add the following lines

    # Include and set up the MET analysis sequence:
    from MetAnalysisAlgorithms.MetAnalysisSequence import makeMetAnalysisSequence
    metSequence = makeMetAnalysisSequence( dataType, metSuffix = 'AntiKt4EMPFlow',
                                           electronsSelection = 'preselection,as_char',
                                           muonsSelection = 'preselection,as_char' )
    metSequence.configure( inputName = { 'jets'      : 'AnaJets_%SYS%',
                                         'muons'     : 'AnaMuons_%SYS%',
                                         'electrons' : 'AnaElectrons_%SYS%' },
                           outputName = 'AnaMET_%SYS%' )

    # Add the MET analysis sequence to the job:
    algSeq += metSequence

Rerun to make sure the changes are implemented correctly.

Retrieve MET container

As the MET is calculated, several intermediate values are found and stored, resulting in a MET container in the event, similar to the containers of other analysis objects. The MET container differs from the other containers in the fact that it has the same number of elements for each event. For our analysis, we only care about the Final MET in the container, which can be accessed directly using the name.

Begin by adding xAODMissingET to CMakeLists.txt where the other object libraries are linked. Then add the following include statement to MyxAODAnalysis.cxx:

#include <xAODMissingET/MissingETContainer.h>

Now, you can retrieve the MET using the following lines:

  // Retrieve MET container from the event store
  const xAOD::MissingETContainer* allMET = 0;
  ANA_CHECK (evtStore()->retrieve(allMET, "AnaMET_NOSYS"));

Write MET information to the ntuple

We need to get the correct instance of MET and then write the total MET (a scalar quantity) and the azimuthal angle of the MET to the ntuple.

First, declare the following private class members in your header file:

  float m_met;
  float m_met_phi;

Next, create branches using the following lines in initialize():

  mytree->Branch ("met", &m_met);
  mytree->Branch ("met_phi", &m_met_phi);

Finally, in execute() after you’ve retrieved the MET (but before you fill the TTree), set the class members to the MET and φ values:

  // Get the final MET and store the scalar and phi direction
  const xAOD::MissingET* met = (*allMET)["Final"];
  m_met = met->met();
  m_met_phi = met->phi();

tip Since the met member variables are float and not vectors, it is not necessary to clear them or delete them.