Skip to content

Plotting with Merlin

Daniel Savoiu edited this page Aug 19, 2017 · 1 revision

Merlin is a subpackage of Excalibur and contains the necessary functionality for creating plots from the output n-Tuples. It is an extension of HarryPlotter, which is a subpackage of Artus.

Please also have a look at the HarryPlotter documentation.

Structure

Merlin derives most classes from HarryPlotter in order to implement Z+Jet-specific stuff.

See:

Please also have a look at the HarryPlotter documentation.

Basic plotting

First of all, make sure you source the initialization script:

source scripts/ini_excalibur.sh

If you're using Merlin outside a SCRAM environment, you need to execute the shell function standalone_merlin. This only needs to be done once per working area. After that, you need to re-source the initialization file:

source scripts/ini_excalibur.sh
standalone_merlin
source scripts/ini_excalibur.sh

Type merlin.py --help to get a list of the plotting options.

Plot configs can be stored as JSON or Python files. Type merlin.py --list-functions to get a list of the available python plot configs.

TODO: check whether the following sections are up to date

Note: everything below this line may be outdated


InputRootZJet

merlin has the additional --zjetfolder, --algorithms and --corrections arguments. From these arguments, the folder name is constructed, according to the ZJet folder naming convention "ZJetFolder_AlgorithmCorrection".

'ZJetFolder' corresponds to different levels of event selection:

  • 'finalcuts' is the default, all cuts for Z+Jet calibration studies are applied
  • 'noetacuts' like finalcuts, but without the cut on the leading jet eta
  • 'noalphacuts' like finalcuts, but without the cut on alpha (= Jet2pT/ZpT)
  • 'noalphanoetacutscuts' like finalcuts, but without cuts on alpha or leading jet eta
  • 'zcuts' only cuts on Z boson and muons, no cuts on jets. Used for checking e.g. Z mass peak
  • 'nocuts' no cuts (only the basic event selection like json or hlt filter which is applied for all pipelines.)

By default, MC histograms (from Artus root files) are scaled to the given luminosity (--lumi) if at least one Data file is used for plotting.

The quantities.py file in Plotting/python/utiliy contains a dictionary for quantity aliases. E.g., type 'ptbalance' and this will be replaced with 'jet2pt/zpt'.

The binnings.py file in Plotting/python/utiliy contains a dictionary for special binnings for ZpT, jet eta, Npv. If you use e.g. --x-bins zpt (or dictionary key), the binning is replaced with the values from this dictionary.

When plotting from a TTree/TNtuple, the 'weight' entry is automatically used as weight. Disable this with --no-weight.

PlotMplZJet

The --cutlabel argument places a label with the used cuts (Z pT, abs(jet1eta), alpha) on the plot. The plot axes can be automatically labelled via the entries of the LabelsDict in Plotting/python/utility/labelsZJet.py (simple strings like 'zpt' are replaced with nicer Latex labels).

The --layout option implements special Matplotlib style settings. See Plotting/python/utility/matplotlib_rc.py for the list of style options. Use e.g. --layout poster to increase the font size for better plot readability in posters.

Python plot configs

  • Python functions allow to construct loops of plots, but cannot be saved or read as easily as json files. Execution of these functions with --python, a list of the available functions can be displayed with --list-functions. The docstring of the functions should contain a description.
  • Plotting/plot-configs/configs/ contains some python plotting scripts

New Python plot config style

There is a new python plot config style which allows to create new configs based on existing ones and override properties in the plot dictionary.

Example:

from Excalibur.Plotting.utility.toolsZJet import PlottingJob

def existing_config(args):
    plots = []
    for x_value in ['zpt', 'npv']:
        d = {
            'x_expression': x_value,
            'y_expression': 'jet1pt/matchedgenjet1pt',
            'y_lims': [0.8, 1.2],
            'tree_draw_options': 'prof'
        }
        plots.append(d)
    return [PlottingJob(plots=plots, args=args)]

def new_config(args):
    plotting_jobs = []

    existing_jobs = existing_config(args)
    for plot in existing_jobs[0].plots:
        plot['y_lims'] = [0.9, 1.4]
    plotting_jobs += existing_jobs

    return plotting_jobs

There's no need to call harryinterface.harry_interface because it is automatically called if a list with PlottingJob is returned by the config function.