Skip to content

Commit

Permalink
Merge pull request cp3-llbb#61 from blinkseb/parser
Browse files Browse the repository at this point in the history
Get rid of TTreeFormula for parsing expression
  • Loading branch information
BrieucF committed Dec 18, 2015
2 parents 31b0956 + db3be26 commit 730d9e9
Show file tree
Hide file tree
Showing 5 changed files with 444 additions and 46 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ addons:
sources:
- ubuntu-toolchain-r-test
- kalakris-cmake
- boost-latest
packages:
- gcc-4.9
- g++-4.9
- git
- make
- cmake
- uuid-dev
- libboost-all-dev

install:
- wget http://sbrochet.web.cern.ch/sbrochet/public/ROOT-${ROOT_VERSION}_Python-2.7_Ubuntu-12.04_gcc4.9.tar.xz
Expand Down
16 changes: 13 additions & 3 deletions histFactory/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include(CMSSW)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++0x -g")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
Expand All @@ -28,16 +28,27 @@ if(IN_CMSSW)
execute_process(COMMAND scram tool tag python LIB OUTPUT_VARIABLE PYTHON_LIBRARY OUTPUT_STRIP_TRAILING_WHITESPACE)
set(PYTHON_LIBRARY "${PYTHON_LIBRARY_PATH}/lib${PYTHON_LIBRARY}.so")
execute_process(COMMAND scram tool tag python INCLUDE OUTPUT_VARIABLE PYTHON_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)

# Boost
execute_process(COMMAND scram tool tag boost BOOST_BASE OUTPUT_VARIABLE
BOOST_ROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
set(Boost_NO_SYSTEM_PATHS ON)
else()
execute_process(COMMAND python-config --prefix OUTPUT_VARIABLE
PYTHON_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
list(APPEND CMAKE_LIBRARY_PATH "${PYTHON_PREFIX}/lib")
list(APPEND CMAKE_INCLUDE_PATH "${PYTHON_PREFIX}/include")
endif()

set(Boost_NO_BOOST_CMAKE ON)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})

find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_PATH})

include_directories(src)

# Configure external

include(BuildExternals)
Expand All @@ -52,7 +63,7 @@ configure_file(scripts/createPlotter.sh.in createPlotter.sh @ONLY NEWLINE_STYLE
# plotter sources
set(PLOTTER_SOURCES
src/createPlotter.cpp
${EXTERNAL_SRC_DIR}/jsoncpp.cpp
src/formula_parser.cpp
)

# Multidraw sources
Expand Down Expand Up @@ -103,7 +114,6 @@ set_target_properties(count PROPERTIES OUTPUT_NAME "createProcessedEvents.exe")

# Link libraries
target_link_libraries(plotter ${ROOT_LIBRARIES})
target_link_libraries(plotter ${ROOT_TREEPLAYER_LIBRARY})
target_link_libraries(plotter ${PYTHON_LIBRARY})

target_link_libraries(plotter "uuid")
Expand Down
88 changes: 45 additions & 43 deletions histFactory/src/createPlotter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
#include <iostream>
#include <fstream>
#include <memory>
#include <cstdio>
#include <regex>
#include <unordered_map>

#include <TChain.h>
#include <TBranch.h>
#include <TLeaf.h>
#include <TApplication.h>

// Ugly hack to access list of leaves in the formula
#define protected public
#include <TTreeFormula.h>
#undef protected
#include <formula_parser.h>

#include <uuid/uuid.h>

Expand Down Expand Up @@ -278,56 +277,54 @@ bool execute(const std::string& skeleton, const std::string& config_file, std::s
plot.name = uuid;
}

parser::parser parser;

std::unique_ptr<TChain> t(new TChain("t"));
t->Add(skeleton.c_str());

std::vector<Branch> branches;
std::function<void(TTreeFormula*)> getBranches = [&branches, &getBranches](TTreeFormula* f) {
if (!f)
return;

for (size_t i = 0; i < f->GetNcodes(); i++) {
TLeaf* leaf = f->GetLeaf(i);
if (! leaf)
continue;

TBranch* p_branch = getTopBranch(leaf->GetBranch());
// Get list of all branches
std::unordered_map<std::string, Branch> tree_branches;
TObjArray* root_tree_branches = t->GetListOfBranches();
for (size_t i = 0; i < static_cast<size_t>(root_tree_branches->GetEntries()); i++) {
TBranch* b = static_cast<TBranch*>(root_tree_branches->UncheckedAt(i));

Branch branch;
branch.name = p_branch->GetName();
if (std::find_if(branches.begin(), branches.end(), [&branch](const Branch& b) { return b.name == branch.name; }) == branches.end()) {
branch.type = p_branch->GetClassName();
if (branch.type.empty())
branch.type = leaf->GetTypeName();
Branch branch;
branch.name = b->GetName();
branch.type = b->GetClassName();

branches.push_back(branch);
}

for (size_t j = 0; j < f->fNdimensions[i]; j++) {
if (f->fVarIndexes[i][j])
getBranches(f->fVarIndexes[i][j]);
if (branch.type.empty()) {
TLeaf* leaf = b->GetLeaf(branch.name.c_str());
if (! leaf) {
std::cerr << "Error: can't deduce type for branch '" << branch.name << "'" << std::endl;
continue;
}
branch.type = leaf->GetTypeName();
}

for (size_t i = 0; i < f->fAliases.GetEntriesFast(); i++) {
getBranches((TTreeFormula*) f->fAliases.UncheckedAt(i));
}
};
tree_branches.emplace(branch.name, branch);
}

std::string hists_declaration;
std::string text_plots;
std::set<std::string> identifiers;
size_t index = 0;
for (auto& p: plots) {
// Create formulas
std::shared_ptr<TTreeFormula> selector(new TTreeFormula("selector", p.cut.c_str(), t.get()));
std::shared_ptr<TTreeFormula> weight(new TTreeFormula("weight", p.weight.c_str(), t.get()));

getBranches(selector.get());
getBranches(weight.get());
if ((index % 200) == 0)
std::cout << "Parsing plot #" << index << " / " << plots.size() << std::endl;

index++;

// Create formulas
if (! parser.parse(p.cut, identifiers))
std::cerr << "Warning: " << p.cut << " failed to parse." << std::endl;
if (! parser.parse(p.weight, identifiers))
std::cerr << "Warning: " << p.weight << " failed to parse." << std::endl;

std::vector<std::string> splitted_variables = split(p.variable, ":::");
for (const std::string& variable: splitted_variables) {
std::shared_ptr<TTreeFormula> var(new TTreeFormula("var", variable.c_str(), t.get()));
getBranches(var.get());
if (!parser.parse(variable, identifiers))
std::cerr << "Warning: " << variable << " failed to parse." << std::endl;
}

std::string binning = p.binning;
Expand Down Expand Up @@ -360,10 +357,15 @@ bool execute(const std::string& skeleton, const std::string& config_file, std::s
ctemplate::ExpandTemplate(getTemplate("Plot"), ctemplate::DO_NOT_STRIP, &plot, &text_plots);
}

// Sort alphabetically
std::sort(branches.begin(), branches.end(), [](const Branch& a, const Branch& b) {
return a.name < b.name;
});
// Everything is parsed. Collect the list of branches used by the formula
std::vector<Branch> branches;
for (const auto& id: identifiers) {
auto branch = tree_branches.find(id);
if (branch == tree_branches.end())
continue;

branches.push_back(branch->second);
}

std::string text_branches;
for (const auto& branch: branches) {
Expand Down
16 changes: 16 additions & 0 deletions histFactory/src/formula_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <formula_parser.h>

namespace parser
{
bool parser::parse(const std::string& line, std::set<std::string>& identifiers) {
m_grammar.set_identifiers(identifiers);

bool result = qi::phrase_parse(
line.begin(),
line.end(),
m_grammar,
ascii::space);

return result;
}
}
Loading

0 comments on commit 730d9e9

Please sign in to comment.