Skip to content

Tutorial III: Reading ROOT Input

Thomas Mueller edited this page Aug 22, 2019 · 10 revisions

This tutorial is based on the ROOT files generated in the first step.

Reading from ROOT trees or ntuples

Histograms

Simple examples and parameter expansions

  • Different files

     harry.py -i gaussians.root gaussians1000.root -f gaussians -x var0

    plots/histograms_2files.png

  • Different trees

     harry.py -i gaussians3.root -f gaussians1 gaussians2 -x var0

    plots/histograms_2trees.png

  • Different expressions

     harry.py -i gaussians3.root -f gaussians1 -x var0 var1

    plots/histograms_2expressions.png

Binning options

Profiling options

Proxy options

The ROOT function TTree::Draw offers a possibility to execute C++ macros when processing trees. These macros need to be created by the function TTree::MakeProxy. HarryPlotter supports this mechanism and takes care of creating and compiling this code. Users can use this mode with the setting --tree-draw-options proxy and provide code at -x (not -y/-z) and -w to provide for the extraction of float values to be plotted and float values for weights and cuts. Note, that the original ROOT functions only support bool cuts, but HarryPlotter modifies this to support also float weight. HarryPlotter creates files called proxy_* in the current directory, which can only be deleted after the last plot in a given HarryPlotter (multiplot) run is finished. This is currently not so easy to implement and therefore files have to be deleted manually afterwards (rm proxy_*). Reading from ROOT trees with proxies always requires an existing histogram to fill. This is why HarryPlotter always requires --x-bins to be specified together with --tree-draw-options proxy.

There are two important use cases for this option:

  1. Calculations with high-level objects:

    A frequent use case is a calculation based on LorentzVector (LV) objects. As an example, at tree containing two LV-type objects is considered here:

    harry.py -i <file.root> -f <path/to/tree> -q | grep -e lep.LV

    outputs

    lep1LV (ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >)
    lep2LV (ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >)
    

    Then the mass of the system of the two LV's can be plotted with

    harry.py -i <file.root> -f <path/to/tree> --tree-draw-options proxy --x-bins <binning> \
    	-x "((*lep1LV.obj.GetPtr())+(*lep2LV.obj.GetPtr())).M()"

    The expression *lep1LV.obj.GetPtr() is needed in order to access the ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> > type object, which is wrapped like this by the TTree::MakeProxy function. This is equivalent to filling LV vector objects on-the-fly:

    harry.py -i <file.root> -f <path/to/tree> --tree-draw-options proxy --x-bins <binning> \
    	-x "(ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float>>(lep1LV->Pt(),lep1LV->Eta(),lep1LV->Phi(),lep1LV->M())+ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float>>(lep2LV->Pt(),lep2LV->Eta(),lep2LV->Phi(),lep2LV->M())).M()" \
    	--proxy-prefixes "#include <Math/LorentzVector.h>\n#include <Math/PtEtaPhiM4D.h>"

    In this example is is necessary to tell HarryPlotter to import two header files in the proxy code.

  2. Running more complicated C++ code when iterating over trees:

Graphs

Loading histograms, graphs, functions from ROOT files

Binning options

Clone this wiki locally