Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@ Unfolding/Unfolder
.DS_Store
stv_root_dict_rdict.pcm
*.o
*~
*.so
*.pcm
*.d
*.in
*ACLiC*
*~

python/env
python/*.pyc
python/__pycache__
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ LIB_DIR := lib
ROOT_DICTIONARY := $(LIB_DIR)/dictionaries.o
SHARED_LIB := $(LIB_DIR)/libXSecAnalyzer.$(SHARED_LIB_SUFFIX)

CXXFLAGS := $(shell root-config --cflags) -O3 -I$(INCLUDE_DIR)
#CXXFLAGS := $(shell root-config --cflags) -O3 -I$(INCLUDE_DIR) #normal mode
CXXFLAGS := $(shell root-config --cflags) -O0 -g -I$(INCLUDE_DIR) #debug mode
LDFLAGS := $(shell root-config --libs) -L$(LIB_DIR) -lXSecAnalyzer

# Source files to use when building the main shared library
Expand Down
25 changes: 25 additions & 0 deletions cafana/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.25)
project(cafana)

option(BUILD_DOC "Build documentation" ON)

# Check if Doxygen is installed.
#find_package(Doxygen PATHS ${DOXYGEN_PATH})
#if (DOXYGEN_FOUND)
# Set input and output files
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

# Request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)

# Add a custom target to run Doxygen
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
#else (DOXYGEN_FOUND)
# message("Doxygen need to be installed to generate the doxygen documentation")
#endif (DOXYGEN_FOUND)
27 changes: 27 additions & 0 deletions cafana/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## CAFAna

CAFAna is a framework for parsing the standard output of SBN CAF files. [sbnana](https://github.com/SBNSoftware/sbnana) is the main repository for the SBN software suite, which contains `cafe`.

## Setup
Setup `sbnana` to get access to `cafe` executable.
```bash
source /cvmfs/sbnd.opensciencegrid.org/products/sbnd/setup_sbnd.sh
ups list -aK+ sbnana #Use most recent version > 10_00_00
setup sbnana v10_00_00 -q e26:prof
```

## Usage
The macros should be setup to store the event classifications into `event_type` branch. `is_signal` identifies if the event is reconstructed as signal. These are both essential for `ProcessNTuples` to work.
```bash
cafe -bq <macro.C>
```

## Example

```bash
cafe -bq xsec_analyzer.C
```

## Output

The output is a ROOT file with the name `xsec_analyzer.root`. The file contains a tree with the name `xsec_analyzer`. This is used as input for `ProcessNTuples` to feed into downstream fitting tools.
199 changes: 199 additions & 0 deletions cafana/include/analysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/**
* @file analysis.h
* @brief Header file for the Analysis class, a class designed to streamline
* the running of multiple samples through CAFAna.
* @details The Analysis class operates under the principle that the full
* dataset in an analysis is comprised of multiple samples, each of which
* represents a different component of the signal or background. Under this
* paradigm, an analysis consists of running the same set of variables/cuts
* on each sample, and then combining the results at the end. The Analysis
* class is designed to facilitate this process by allowing the user to
* specify the variables and cuts to be applied to each sample, along with the
* full list of samples to be run. The class then handles the running of the
* samples and the storing of the results.
* @author mueller@fnal.gov
*/
#ifndef ANALYSIS_H
#define ANALYSIS_H
#include <vector>
#include <string>

#include "sbnana/CAFAna/Core/SpectrumLoader.h"
#include "sbnana/CAFAna/Core/Tree.h"
#include "sbnana/CAFAna/Core/Cut.h"
#include "sbnana/CAFAna/Core/Spectrum.h"

#include "TDirectory.h"
#include "TFile.h"

/**
* @namespace ana
* @brief Namespace for the Analysis class and related functions.
* @details The ana namespace contains the Analysis class, which is designed
* to streamline the running of multiple samples through CAFAna. The namespace
* is also used to organize analysis-related functions and variables within
* CAFAna.
*/
namespace ana
{
/**
* @struct Sample
* @brief Struct to store information about a sample in the analysis.
* @details This struct is used to store information about a sample in the
* analysis, including the name of the sample, the SpectrumLoader object
* representing the sample, and a boolean indicating whether the sample is
* a simulation sample. The simulation flag is used to determine if truth
* information is available for the sample.
*/
struct Sample
{
std::string name;
ana::SpectrumLoader * loader;
bool is_sim;
};

/**
* @struct TreeSet
* @brief Struct to store information about a set of variables that comprise
* a Tree in the analysis.
* @details This struct is used to store information about a set of variables
* that comprise a Tree in the analysis. The Tree is used to store the results
* of the analysis in a TTree in the output ROOT file. The struct contains the
* name of the Tree, the names of the variables, the SpillMultiVars that
* implement the variables, and a boolean indicating whether the Tree
* represents a simulation sample. The simulation flag is used to determine
* if truth information is present in the Tree.
*/
struct TreeSet
{
std::string name;
std::vector<std::string> names;
std::vector<ana::SpillMultiVar> vars;
bool is_sim;
};

/**
* @class Analysis
* @brief Class designed to streamline the running of multiple samples
* through CAFAna.
* @details The Analysis class operates under the principle that the full
* dataset in an analysis is comprised of multiple samples, each of which
* represents a different component of the signal or background. Under this
* paradigm, an analysis consists of running the same set of variables/cuts
* on each sample, and then combining the results at the end. The Analysis
* class is designed to facilitate this process by allowing the user to
* specify the variables and cuts to be applied to each sample, along with
* the full list of samples to be run. The class then handles the running of
* the samples and the storing of the results.
*/
class Analysis
{
public:
Analysis(std::string name);
void AddLoader(std::string name, ana::SpectrumLoader * loader, bool is_sim);
void AddTree(std::string name, std::map<std::string, ana::SpillMultiVar> & vars, bool is_sim);
void Go();
private:
std::string name;
std::vector<Sample> samples;
std::vector<TreeSet> trees;
};

/**
* @brief Default constructor for the Analysis class.
* @details This constructor initializes an instance of the Analysis class
* with a default name.
* @param name The name of the Analysis class. This name is used in the
* creation of the output ROOT file.
* @return A new instance of the Analysis class.
*/
Analysis::Analysis(std::string name)
{
this->name = name;
}

/**
* @brief Add a SpectrumLoader to the Analysis class.
* @details This function allows the user to add a SpectrumLoader to the
* Analysis class. The SpectrumLoader represents a sample in the analysis,
* and is used to load the data from the ROOT file and apply the cuts and
* variables to the data.
* @param name The name of the SpectrumLoader to be added to the Analysis
* class.
* @param loader The SpectrumLoader to be added to the Analysis class.
* @param is_sim A boolean indicating whether the SpectrumLoader represents
* a simulation sample, which is principally used to determine if truth
* information is available.
* @return void
*/
void Analysis::AddLoader(std::string name, ana::SpectrumLoader * loader, bool is_sim)
{
samples.push_back({name, loader, is_sim});
}

/**
* @brief Add a Tree to the Analysis class (set of variables and names).
* @details This function allows the user to add a new Tree to the Analysis
* class. A Tree is a set of variables with associated names that are
* applied to the data in the SpectrumLoader. The Tree is used to store the
* results of the analysis in a TTree in the output ROOT file.
* @param names A vector of strings containing the names of the variables
* to use in the Tree.
* @param vars A vector of SpillMultiVar objects implementing the variables
* to use in the Tree.
* @param is_sim A boolean indicating whether the Tree represents a
* simulation sample, which is principally used to determine if truth
* information is available.
* @return void
*/
void Analysis::AddTree(std::string name, std::map<std::string, ana::SpillMultiVar> & vars, bool is_sim)
{
std::vector<std::string> n;
std::vector<ana::SpillMultiVar> v;
for(const auto & [name, var] : vars)
{
n.push_back(name);
v.push_back(var);
}
trees.push_back({name, n, v, is_sim});
}

/**
* @brief Run the analysis on the specified samples.
* @details This function runs the analysis on the configured samples by
* looping over each sample, creating the Trees for each sample, then
* running the analysis on the sample to populate the Trees with the
* results of the analysis. The results are stored in a TFile in the output
* ROOT file in a parent directory named "events" and a subdirectory for
* each sample.
* @return void
*/
void Analysis::Go()
{
TFile * f = new TFile(std::string(name + ".root").c_str(), "RECREATE");
TDirectory * dir = f->mkdir("events");
dir->cd();

for(const Sample & s : samples)
{
TDirectory * subdir = dir->mkdir(s.name.c_str());
subdir->cd();
std::vector<ana::Tree*> sbruce_trees;
for(const TreeSet & t : trees)
{
if(t.is_sim && !s.is_sim)
continue;
sbruce_trees.push_back(new ana::Tree(t.name, t.names, *s.loader, t.vars, ana::kNoSpillCut, true));
}
s.loader->Go();
for(const ana::Tree * t : sbruce_trees)
{
t->SaveTo(subdir);
delete t;
}
dir->cd();
}
f->Close();
}
}
#endif // ANALYSIS_H
33 changes: 33 additions & 0 deletions cafana/include/pandora/definitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @file xsec_analyzer/pandora/definitions.h
* @brief Definitions of analysis variables.
* @details This file contains definitions of analysis variables which can be
* used to extract information from slices. Each variable is implemented
* as a function which takes a slice object as an argument and returns a
* double. These variables are intended to define slice definitions.
* @author brindenc@fnal.gov
*/

#ifndef DEFINITIONS_H
#define DEFINITIONS_H

#include "sbnanaobj/StandardRecord/Proxy/SRProxy.h"
#include "sbnana/SBNAna/Cuts/TruthCuts.h"

#include "slice_cuts.h"

using namespace ana;

namespace defs
{
int kEventType(const caf::SRSliceProxy & slc)
{
if (kTrueActiveVolumeND(&slc) && kIsNumu(&slc) && kIsCC(&slc)) return 0; //numucc
else if (kTrueActiveVolumeND(&slc) & kIsNC(&slc)) return 1; //NC
else if (kTrueActiveVolumeND(&slc) & kIsNue(&slc) & kIsCC(&slc)) return 2; //nuecc
else if (!kIsNu(&slc)) return 3; //Cosmic
else if (!kTrueActiveVolumeND(&slc) & kIsNu(&slc)) return 4; //Out of volume
else return -1; //Other
}
}
#endif // DEFINITIONS_H
Loading