Fork me on GitHub

Version 2 (modified by Christophe Delaere, 11 years ago) ( diff )

--

Delphes comes with all the ExRootAnalysis framework/facilities. It is powerful and very practical. Written in C++, it has all the nice (fast) and bad (heavy) aspects of that language. On the contrary, Python is an interpreted scripting language that allows for a fast development cycle. It is therefore (becoming) the preferred language for high-level applications.

  • Introspection makes the code easy to extend
  • Run-time type evaluation removes the need for templates

DelphesAnalysis is an analysis framework written in python where a clear separation is maintained between the standard code and what the user has to implement. This makes it easy to apprehend and generic, still retaining full flexibility and scalability. The framework is built out of:

  • AnalysisEvent class: interface to the ROOT tree + many more
  • Base ControlPlots class: interface to create plots
  • Base EventSelection class: interface to code cuts/categories

All that can be configured in a single configuration file.

The AnalysisEvent class

AnalysisEvent is an interface to the tree data. It provides new functionality w.r.t. the bare access:

  • A list of event products used in the analysis
    It allows to centralize the definition of the collections to use, and provides convenient aliases that you can use in your analysis to access the various objects/products.
  • A list of "producers" of analysis high-level quantities
    This is sometimes known as “Analysis on demand”. You don't have to explicitly call the analysis routines that were previously declared. Once registered, they are run when needed. Results are cached, so that the methods are called once per event. That functionality reduces a lot the number of import statements and contributes to the optimization of the analysis code.
  • A centralized weight infrastructure
    The user can define a set of weight classes where an event weight is computed based on event quantities. AnalysisEvent keeps track of every weight and caches the intermediate and final values. Beware that the caching mechanism for weights is based on the arguments passed to them... don't use object quantities that may change.
  • A volatile dictionary to cache temporarily reconstructed products
    Any high-level quantity can be “put in the event” and retrieved when needed. This means that if your analysis is split into modules, there is no need to pass many arguments to the various functions. Just pass the event instance and use the event to store what is needed.
hello = lambda: "world"

The BaseControlPlots class and its subclasses

That class allows to define/fill/save a set of histograms or ntuple variables, following the traditional scheme in such cases. Still, it makes use of a simplified and unified approach to minimize the amount of code needed while maintaining all the functionality of the ROOT back-end.

As a user, you must create a derived class where the following two methods are implemented:

beginJob(self)
That method is called before the event loop. You should declare the histograms, using self.add(/*TH1 arguments*/), and do any needed initialization.
process(self,event)
That method is called for each event. A proper implement should do the processing, taking all information from the input event. Remember to take benefit from the caching, producers, and other features of AnalysisEvent. The method must return a dictionary varName:value(s) that will be used internally by the framework to fill histograms or ntuple variables. It can be a list of values when more than one entry per event, but this is then only supported for histograms, not for ntuples (the corresponding ntuple branches will be empty).
hello = lambda: "world"

The BaseWeight class

That class has to be subclassed to compute event weights. The base class itself does nothing... it is mostly there as a documentation of what you have to implement in a subclass. Namely,

the constructor
A simple constructor should be implemented, with any needed parameters to initialize the calculation.
weight(self,event)
Method returning the weight value for the current event. The implementation should be based on the event content and on a set of options passed as argument. Beware that the caching mechanism for weights is based on the arguments passed to them... don't use quantities that may change during the event processing.
hello = lambda: "world"

The Event selection

The EventSelection module contains the set of functions needed to select and classify events. A proper implementation of the event selection will at least define the following:

categoryNames
an ordered list of the names of each category.
eventCategory(event)
a method that computes a tuple containing the data needed to sort events in the categories named above in its simplest form. It can be a tuple of bools, or may contain more detailed information but should always be kept simple to make the isInCategory method fast.
isInCategory(cat, categoryData)
that method returns a boolean to tell if the event is in the category cat, definition, from category data contained in categoryData.
hello = lambda: "world"

Steering code and Configuration file

The framework is contained in python/DelphesAnalsys. No file in that directory should ever be modified.

The main script is ControlPlots.

DumpEventInfo is another script that will output all the information available on a given event.

All that is configured through a simple configuration script.

Implementing an analysis

what should be touched to implement an example?

Examples

The release includes two examples.

  • Simple analysis.
    • simpleConfig.py
    • SimpleEventSelection.py
    • LeptonControlPlots.py
  • Basic ttbar analysis
    • topConfig.py
    • TtbarEventSelection.py
    • TopReconstruction.py
    • JetControlPlots.py
    • LeptonControlPlots.py
    • TopControlPlots.py

The following commands can be run from the Delphes ROOT directory:

# setup path
. ./DelphesEnv.sh
cd python
# run the analysis
DelphesAnalysis/ControlPlots.py -i ../files/ -o controlPlots_demo.root --all -c topConfig.py
# dump a list of events in category 5 (ttbar candidates)
export DelphesAnalysisCfg="topConfig.py"
python DelphesAnalysis/DumpEventList.py 5 ../delphes_output.root
# for each of them, print details
for i in `cat eventlist.txt| cut -d' ' -f 2`; { python DelphesAnalysis/DumpEventInfo.py $i ../delphes_output.root; }
Note: See TracWiki for help on using the wiki.