(Date of last update can be checked with git log -- README.md)
To be tested both as input and as output:
P) primitives: bool, int, double
A) c-arrays of primitives
| #include <vector> | |
| #include <functional> | |
| template<typename R, typename T> | |
| std::function<std::vector<R>(std::vector<T>&)> | |
| ApplyToVec(R(T::*m)()) { | |
| auto applyToEach = [m](std::vector<T> &v) { | |
| std::vector<R> r; | |
| r.reserve(v.size()); | |
| for (auto &e : v) { |
| #include <type_traits> // std::decay | |
| #include <utility> // std::forward, std::declval | |
| namespace Internal { | |
| template <typename F> | |
| class not_fn_t { | |
| typename std::decay<F>::type fFun; | |
| public: | |
| explicit not_fn_t(F &&f) : fFun(std::forward<F>(f)) {} |
| // TDataSource | |
| // | |
| // The problem it tries to solve: | |
| // - accessing specific columns of any tabular data-set through a uniform interface | |
| // - allow thread-safe parallel processing of the data (by slicing the data-set in nThreads pieces) | |
| // - offer the simplest interface possible, ideally iterator-based | |
| // 1. -- build the data source | |
| TDataSource s("file.root"); |
| #include <cstddef> // std::size_t | |
| #include <type_traits> // std::decay, std::is_same | |
| #include <vector> // need vector<bool> in is_container | |
| namespace meta { | |
| // lightweight storage for a collection of types | |
| // differently from std::tuple, no instantiation of objects of stored types is performed | |
| template <typename... Types> | |
| struct type_list { |
| /* | |
| Proof of concept of a TDataFrame with a lot less templates. | |
| Issues: | |
| - circular dependency nightmare in which all the different nodes have to know about each other and call methods on | |
| each other. Could be solved introducing a common parent class, but that would probably mean virtual dispatch? | |
| */ | |
| #include "TTreeReader.h" | |
| #include "TTreeReaderValue.h" |
Before delving in this utterly incomplete developers guide make sure you read the users guide here.
The important objects that are part of the TDataFrame framework are the following:
TDFActionHelpers.{hxx,cxx}) are those that actually execute the actions. There is about one helper per possible action. These are full-blown objects because in general they need to store state (e.g. current value of Max of a branch), they must be thread-aware (i.e. they store one partial result per thread/slot) and they must perform finalising operations when the event-loop is terminated (e.g. merge of the partial results).| #!/bin/bash | |
| # N.B. requires gawk, recode, templight++ and templigt-convert to be in PATH | |
| SRC="$1" | |
| if [[ -z "${SRC}" ]]; then | |
| exit 1 | |
| fi | |
| FNAME=${SRC%.C} | |
| FNAME=${FNAME%.cpp} |
| #include "TPool.h" | |
| #include "TH1F.h" | |
| #include "TRandom3.h" | |
| #include "TStopwatch.h" | |
| #include "TApplication.h" | |
| #include <iostream> | |
| #include <vector> | |
| TObject *FillHisto(unsigned long long nEvents) { | |
| TH1F *h = new TH1F("h","h",100,-3,3); |
| #ifndef _STREAMME_ | |
| #define _STREAMME_ | |
| struct StreamMe { | |
| explicit StreamMe(int _a) : a(_a) {}; | |
| StreamMe() : StreamMe(1) {}; | |
| int a; | |
| std::vector<int> b; | |
| }; |