Logo ROOT  
Reference Guide
RDFHelpers.hxx
Go to the documentation of this file.
1 // Author: Enrico Guiraud, Danilo Piparo CERN 02/2018
2 
3 /*************************************************************************
4  * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 // This header contains helper free functions that slim down RDataFrame's programming model
12 
13 #ifndef ROOT_RDF_HELPERS
14 #define ROOT_RDF_HELPERS
15 
16 #include <ROOT/RDataFrame.hxx>
17 #include <ROOT/RResultHandle.hxx>
18 #include <ROOT/RDF/GraphUtils.hxx>
20 #include <ROOT/TypeTraits.hxx>
21 
22 #include <algorithm> // std::transform
23 #include <functional>
24 #include <type_traits>
25 #include <vector>
26 #include <memory>
27 #include <fstream>
28 #include <iostream>
29 
30 namespace ROOT {
31 namespace Internal {
32 namespace RDF {
33 template <typename... ArgTypes, typename F>
35 {
36  return std::function<bool(ArgTypes...)>([=](ArgTypes... args) mutable { return !f(args...); });
37 }
38 
39 template <typename... ArgTypes, typename Ret, typename... Args>
41 {
42  return std::function<bool(ArgTypes...)>([=](ArgTypes... args) mutable { return !f(args...); });
43 }
44 
45 template <typename I, typename T, typename F>
47 
48 template <std::size_t... N, typename T, typename F>
49 class PassAsVecHelper<std::index_sequence<N...>, T, F> {
50  template <std::size_t Idx>
51  using AlwaysT = T;
52  F fFunc;
53 
54 public:
55  PassAsVecHelper(F &&f) : fFunc(std::forward<F>(f)) {}
56  auto operator()(AlwaysT<N>... args) -> decltype(fFunc({args...})) { return fFunc({args...}); }
57 };
58 
59 template <std::size_t N, typename T, typename F>
61 {
62  return PassAsVecHelper<std::make_index_sequence<N>, T, F>(std::forward<F>(f));
63 }
64 
65 } // namespace RDF
66 } // namespace Internal
67 
68 namespace RDF {
70 
71 
72 // clag-format off
73 /// Given a callable with signature bool(T1, T2, ...) return a callable with same signature that returns the negated result
74 ///
75 /// The callable must have one single non-template definition of operator(). This is a limitation with respect to
76 /// std::not_fn, required for interoperability with RDataFrame.
77 // clang-format on
78 template <typename F,
79  typename Args = typename ROOT::TypeTraits::CallableTraits<typename std::decay<F>::type>::arg_types_nodecay,
80  typename Ret = typename ROOT::TypeTraits::CallableTraits<typename std::decay<F>::type>::ret_type>
81 auto Not(F &&f) -> decltype(RDFInternal::NotHelper(Args(), std::forward<F>(f)))
82 {
83  static_assert(std::is_same<Ret, bool>::value, "RDF::Not requires a callable that returns a bool.");
84  return RDFInternal::NotHelper(Args(), std::forward<F>(f));
85 }
86 
87 // clang-format off
88 /// PassAsVec is a callable generator that allows passing N variables of type T to a function as a single collection.
89 ///
90 /// PassAsVec<N, T>(func) returns a callable that takes N arguments of type T, passes them down to function `func` as
91 /// an initializer list `{t1, t2, t3,..., tN}` and returns whatever f({t1, t2, t3, ..., tN}) returns.
92 ///
93 /// Note that for this to work with RDataFrame the type of all columns that the callable is applied to must be exactly T.
94 /// Example usage together with RDataFrame ("varX" columns must all be `float` variables):
95 /// \code
96 /// bool myVecFunc(std::vector<float> args);
97 /// df.Filter(PassAsVec<3, float>(myVecFunc), {"var1", "var2", "var3"});
98 /// \endcode
99 // clang-format on
100 template <std::size_t N, typename T, typename F>
102 {
104 }
105 
106 // clang-format off
107 /// Create a graphviz representation of the dataframe computation graph, return it as a string.
108 /// \param[in] node any node of the graph. Called on the head (first) node, it prints the entire graph. Otherwise, only the branch the node belongs to.
109 ///
110 /// Note that SaveGraph is not thread-safe and must not be called concurrently from different threads.
111 // clang-format on
112 template <typename NodeType>
113 std::string SaveGraph(NodeType node)
114 {
116  return helper(node);
117 }
118 
119 // clang-format off
120 /// Create a graphviz representation of the dataframe computation graph, write it to the specified file.
121 /// \param[in] node any node of the graph. Called on the head (first) node, it prints the entire graph. Otherwise, only the branch the node belongs to.
122 /// \param[in] outputFile file where to save the representation.
123 ///
124 /// Note that SaveGraph is not thread-safe and must not be called concurrently from different threads.
125 // clang-format on
126 template <typename NodeType>
127 void SaveGraph(NodeType node, const std::string &outputFile)
128 {
130  std::string dotGraph = helper(node);
131 
132  std::ofstream out(outputFile);
133  if (!out.is_open()) {
134  throw std::runtime_error("Could not open output file \"" + outputFile + "\"for reading");
135  }
136 
137  out << dotGraph;
138  out.close();
139 }
140 
141 // clang-format off
142 /// Cast a RDataFrame node to the common type ROOT::RDF::RNode
143 /// \param[in] node Any node of a RDataFrame graph
144 // clang-format on
145 template <typename NodeType>
146 RNode AsRNode(NodeType node)
147 {
148  return node;
149 }
150 
151 // clang-format off
152 /// Trigger the event loop of multiple RDataFrames concurrently
153 /// \param[in] handles A vector of RResultHandles
154 ///
155 /// This function triggers the event loop of all computation graphs which relate to the
156 /// given RResultHandles. The advantage compared to running the event loop implicitly by accessing the
157 /// RResultPtr is that the event loops will run concurrently. Therefore, the overall
158 /// computation of all results is generally more efficient.
159 /// It should be noted that user-defined operations (e.g., Filters and Defines) of the different RDataFrame graphs are assumed to be safe to call concurrently.
160 ///
161 /// ~~~{.cpp}
162 /// ROOT::RDataFrame df1("tree1", "file1.root");
163 /// auto r1 = df1.Histo1D("var1");
164 ///
165 /// ROOT::RDataFrame df2("tree2", "file2.root");
166 /// auto r2 = df2.Sum("var2");
167 ///
168 /// // RResultPtr -> RResultHandle conversion is automatic
169 /// ROOT::RDF::RunGraphs({r1, r2});
170 /// ~~~
171 // clang-format on
172 void RunGraphs(std::vector<RResultHandle> handles);
173 
174 } // namespace RDF
175 } // namespace ROOT
176 #endif
f
#define f(i)
Definition: RSha256.hxx:104
F
#define F(x, y, z)
ROOT::Internal::RDF::PassAsVecHelper
Definition: RDFHelpers.hxx:46
ROOT::Internal::RDF::NotHelper
std::function< bool(ArgTypes...)> NotHelper(ROOT::TypeTraits::TypeList< ArgTypes... >, F &&f)
Definition: RDFHelpers.hxx:34
ROOT::TypeTraits::TypeList
Lightweight storage for a collection of types.
Definition: TypeTraits.hxx:25
ROOT::RDF::PassAsVec
auto PassAsVec(F &&f) -> RDFInternal::PassAsVecHelper< std::make_index_sequence< N >, T, F >
PassAsVec is a callable generator that allows passing N variables of type T to a function as a single...
Definition: RDFHelpers.hxx:101
N
#define N
ROOT::RDF::Not
auto Not(F &&f) -> decltype(RDFInternal::NotHelper(Args(), std::forward< F >(f)))
Given a callable with signature bool(T1, T2, ...) return a callable with same signature that returns ...
Definition: RDFHelpers.hxx:81
operator()
TRObject operator()(const T1 &t1) const
Definition: TRFunctionImport__oprtr.h:14
ROOT::RDF::RunGraphs
void RunGraphs(std::vector< RResultHandle > handles)
Trigger the event loop of multiple RDataFrames concurrently.
Definition: RDFHelpers.cxx:23
ROOT::Internal::RDF::PassAsVec
auto PassAsVec(F &&f) -> PassAsVecHelper< std::make_index_sequence< N >, T, F >
Definition: RDFHelpers.hxx:60
bool
RDataFrame.hxx
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper
Definition: GraphUtils.hxx:56
RIntegerSequence.hxx
ROOT::RDF::SaveGraph
std::string SaveGraph(NodeType node)
Create a graphviz representation of the dataframe computation graph, return it as a string.
Definition: RDFHelpers.hxx:113
ROOT::Internal::RDF::NotHelper
std::function< bool(ArgTypes...)> NotHelper(ROOT::TypeTraits::TypeList< ArgTypes... >, Ret(*f)(Args...))
Definition: RDFHelpers.hxx:40
RResultHandle.hxx
ROOT::R::function
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:151
TypeTraits.hxx
GraphUtils.hxx
ROOT::RDF::RInterface
The public interface to the RDataFrame federation of classes.
Definition: RInterface.hxx:90
TMVA::DNN::forward
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
ROOT::RDF::AsRNode
RNode AsRNode(NodeType node)
Cast a RDataFrame node to the common type ROOT::RDF::RNode.
Definition: RDFHelpers.hxx:146
ROOT::Internal::RDF
Definition: RArrowDS.hxx:15
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
type
int type
Definition: TGX11.cxx:121
ROOT
VSD Structures.
Definition: StringConv.hxx:21