SBNAnalysis - PetrilloAtWork/sbncode GitHub Wiki

h1. SBNAnalysis

This package provides a lightweight event analysis and fitting framework for measurements within the the Short-Baseline Neutrino program at Fermilab.

It is built on "gallery":http://art.fnal.gov/gallery/, a library designed for reading "art":http://art.fnal.gov ROOT files.

Analysis code is stored in subdirectories of @ana@, with one directory per analysis. Common core code for event I/O is in @core@, and shared utilities in @util@.

h2. Processors

The fundamental piece of analysis code is a @Processor@, which operates on gallery events and writes an output tree. A processor can add additional branches to the tree, or save any other desired objects to the output file. Configuration parameters may be passed to a processor using a JSON file.

One runs a processor by calling a framework-wide binary, like this:

sbn -m MyAnalysis_MySelection -c CONFIG.json INPUT1.root INPUT2.root

Multiple processors can be run at the same time, and configurations are optional. For example:

sbn -m PROC1 -c CONFIG1 -m PROC2 -m PROC3 -c CONFIG3 INPUT.root

Note that the order matters: the configuration applies to the processor it follows.

h2. Documentation

The code is fully documented with Doxygen. To build it, run

doxygen doc/Doxyfile

The output HTML documentation is placed in @doc/html/index.html@.

Note to developers: All code in @sbnanalysis@ should be completely documented with Doxygen-compatible comments. Please build the documentation before committing to check for anything missing.

h2. Building

The build process is managed by "CMake":https://cmake.org. A number of dependencies are required to read art ROOT files, which are most easily configured using "ups":https://cdcvs.fnal.gov/redmine/projects/ups/wiki.

A shell script which installs sbncode (and sbnanalysis) in a new mrb working area is provided in @env@.

To set things up manually, start by configuring an environment for reading SBND or MicroBooNE files on a host with CVMFS access:

source /cvmfs/sbnd.opensciencegrid.org/products/sbnd/setup_sbnd.sh
source /cvmfs/uboone.opensciencegrid.org/products/setup_uboone.sh
source /cvmfs/icarus.opensciencegrid.org/products/icarus/setup_icarus.sh

Then setup your favorite, non-conflicting, <sbnd/icarus/uboone>code releases. Then set up the appropriate versions of gallery, cmake, and jsoncpp, e.g.:

setup gallery v1_06_04 -q e14:prof:nu
setup cmake v3_9_0
setup jsoncpp v1_7_7a -q e14:prof

Note: In the future an @sbncode@ UPS product will automatically set up the dependencies to read files for any SBN experiment.

To build the software:

mkdir build && cd build  # A directory for build products
cmake ..  # Configure the build system
make install  # Build
source bin/setup_sbnanalysis.sh  # Set up environment

Note that the setup script @setup_sbnanalysis.sh@ is created during the build and contains absolute paths to the installation location.

The @cmake@ command accepts many useful options. For example:

  • -DCMAKE_INSTALL_PREFIX=/some/path: Install the software at /some/path. The default is to install inside the build directory.
  • -DCMAKE_BUILD_TYPE=Debug: Build with debugging flags enabled (i.e. -g)

In addition, it is possible to configure @cmake@ to compile one of your processors into a standalone executable which can be easy to run on, e.g., the grid. To do this, run

cmake -DSBNANA_COMPILED_PROCESSOR=YOUR_PROCESSOR_NAME

Then, every time you build the software, your processor will get built as a standalone executable. To unset building a standalone executable, run

cmake -USBNANA_COMPILED_PROCESSOR

Final binaries are placed in the @bin@ directory and libraries in @lib@.

h2. Tutorial

A primary goal of this package is to centralize development of event selection code and fitting frameworks, and establish a standard analysis tree format that is compatible with all fitters. As such, the fundamental object in @sbnanalysis@ is an event processor class which writes a standard ROOT tree, plus additional user-specified data.

h3. A Selection Analysis

Analysis code is stored in subdirectories of @ana@, one per analysis. These directories contain any utility code and algorithms, and a selection class which is a subclass of @core::SelectionBase@. Note that all code should should be defined inside a namespace @ana::NameOfAnalysis@.

The selection code must define the following methods:

  • @void Initialize(Json::Value* config)@: Load configuration parameters and perform analysis-specific setup, such as defining histograms, and adding custom branches to the output tree.

  • @void Finalize()@: Perform analysis-specific tear-down, such as computing statistics and writing histograms to the output file.

  • @bool ProcessEvent(gallery::Event& ev)@: Perform the event-level analysis, such as filling histograms and setting the variables corresponding to the custom branches (they will filled -- written to the tree -- automatically). The return value is used for event filtering: if ProcessEvent returns false, the event is not written to the output tree.

The user is free to add arbitrary branches to the default output ROOT tree, using the method @void AddBranch(std::string name, T* object)@ where the first argument is the branch name and the second is a reference to the object, which should be a member variable of the user's selection class.

Note that @Initialize@ (@Finalize@) is called after the after (before) the base selection class setup and teardown, so you have access to the ROOT output file and the output tree in these methods.

As an example, a selection subclass might look like this:

namespace ana {
  namespace ExampleAnalysis {

class ExampleSelection : public core::SelectionBase {
public:
  ExampleSelection();
  void Initialize();
  void Finalize();
  bool ProcessEvent(const gallery::Event& ev,
                    const std::vector &truth,
                    std::vector& reco);

protected:
  int fMyVar;  // For a custom branch
};

with an implementation like:

#include 
#include "gallery/ValidHandle.h"
#include "ExampleSelection.h"

namespace ana {
  namespace ExampleAnalysis {
    // Constructor
    ExampleSelection::ExampleSelection() : SelectionBase() {}

    // Setup
    void ExampleSelection::Initialize() {
      AddBranch("myvar", &fMyVar);  // Define a custom branch
    }

    // Teardown
    void ExampleSelection::Finalize() {}

    // Event processing
    bool ExampleSelection::ProcessEvent(
        const gallery::Event& ev,
        const std::vector& truth,
        std::vector& reco) {
      // ... Process the gallery::Event ...
      fMyVar = 42;  // Fill in the custom branch
      return true;
    }
  }  // namespace ExampleAnalysis
}  // namespace ana

// Important!: Declare the selection to sbnanalysis.
DECLARE_SBN_PROCESSOR(ana::ExampleAnalysis::ExampleSelection)

Note that the final @DECLARE_SBN_PROCESSOR@ line is required to run the code within the sbnanalysis framework.

Finally, new source code must be added to the library definitions in the @CMakeLists.txt@ file within the analysis subdirectory. See the provided @ExampleAnalysis@ for an example.

h3. Running the Analysis

The analysis code is run over a set of files using a framework-level executable:

sbn -m PROCESSOR [-c CONFIG] [-m PROCESSOR [-c CONFIG] ...] INPUT

PROCESSOR - Name of processor, typically AnalysisName_SelectionName
CONFIG - JSON configuration file
INPUT - Input files (see note)

The configuration file contains settings which are passed to the selection processor's @Initialize@ function.

The input files can be defined as one or more ROOT files (ending in @.root@). Support is planned for file lists and SAM dataset definitions in future versions.

To run the above example (after building):

sbn -m ExampleAnalysis_ExampleSelection -c ExampleConfig.json input.root

Or, if you have configured cmake to build ExampleAnalysis_ExampleSelection as a standalone executable:

SBNProcessor_ExampleAnalysis_ExampleSelection \
    -c config1.json -c config2.json input.root

h3. Analyzing the Output

The output file is a ROOT file with a tree named @sbnana@ plus any additional objects written by the selection code. The @sbnana@ tree contains a branch called @events@; this is the standard event-level information written out by all processors, stored in an @Event@ object. See @core/Event.hh@ for the complete definition.

To read the output files in ROOT, one must load the event dictionary, which is stored in @libsbnanalysis_Processor.so@. Compiled code should link to this library, and on the ROOT command line one can run:

.L lib/libsbnanalysis_Event.so

Now, we can open the file in a @TBrowser@ and browse around.

One can make plots interactively, or analyze this tree with a ROOT macro or script. For example, in the ROOT console:

root [0] .L lib/libsbnanalysis_Event.so
root [1] TFile f("output.root")
root [2] sbnana->Draw("interactions.lepton.energy")

This will produce a plot of the primary lepton energies for all neutrino interactions.

h2. Examples

A complete example analysis package is provided in @ana/ExampleAnalysis@.

⚠️ **GitHub.com Fallback** ⚠️