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/RDF/GraphUtils.hxx>
19 #include <ROOT/TypeTraits.hxx>
20 
21 #include <algorithm> // std::transform
22 #include <functional>
23 #include <type_traits>
24 #include <vector>
25 #include <memory>
26 #include <fstream>
27 #include <iostream>
28 
29 namespace ROOT {
30 namespace Internal {
31 namespace RDF {
32 template <typename... ArgTypes, typename F>
34 {
35  return std::function<bool(ArgTypes...)>([=](ArgTypes... args) mutable { return !f(args...); });
36 }
37 
38 template <typename... ArgTypes, typename Ret, typename... Args>
40 {
41  return std::function<bool(ArgTypes...)>([=](ArgTypes... args) mutable { return !f(args...); });
42 }
43 
44 template <typename I, typename T, typename F>
46 
47 template <std::size_t... N, typename T, typename F>
48 class PassAsVecHelper<std::index_sequence<N...>, T, F> {
49  template <std::size_t Idx>
50  using AlwaysT = T;
51  F fFunc;
52 
53 public:
54  PassAsVecHelper(F &&f) : fFunc(std::forward<F>(f)) {}
55  auto operator()(AlwaysT<N>... args) -> decltype(fFunc({args...})) { return fFunc({args...}); }
56 };
57 
58 template <std::size_t N, typename T, typename F>
60 {
61  return PassAsVecHelper<std::make_index_sequence<N>, T, F>(std::forward<F>(f));
62 }
63 
64 } // namespace RDF
65 } // namespace Internal
66 
67 namespace RDF {
69 
70 
71 // clag-format off
72 /// Given a callable with signature bool(T1, T2, ...) return a callable with same signature that returns the negated result
73 ///
74 /// The callable must have one single non-template definition of operator(). This is a limitation with respect to
75 /// std::not_fn, required for interoperability with RDataFrame.
76 // clang-format on
77 template <typename F,
78  typename Args = typename ROOT::TypeTraits::CallableTraits<typename std::decay<F>::type>::arg_types_nodecay,
79  typename Ret = typename ROOT::TypeTraits::CallableTraits<typename std::decay<F>::type>::ret_type>
80 auto Not(F &&f) -> decltype(RDFInternal::NotHelper(Args(), std::forward<F>(f)))
81 {
82  static_assert(std::is_same<Ret, bool>::value, "RDF::Not requires a callable that returns a bool.");
83  return RDFInternal::NotHelper(Args(), std::forward<F>(f));
84 }
85 
86 // clang-format off
87 /// PassAsVec is a callable generator that allows passing N variables of type T to a function as a single collection.
88 ///
89 /// PassAsVec<N, T>(func) returns a callable that takes N arguments of type T, passes them down to function `func` as
90 /// an initializer list `{t1, t2, t3,..., tN}` and returns whatever f({t1, t2, t3, ..., tN}) returns.
91 ///
92 /// Note that for this to work with RDataFrame the type of all columns that the callable is applied to must be exactly T.
93 /// Example usage together with RDataFrame ("varX" columns must all be `float` variables):
94 /// \code
95 /// bool myVecFunc(std::vector<float> args);
96 /// df.Filter(PassAsVec<3, float>(myVecFunc), {"var1", "var2", "var3"});
97 /// \endcode
98 // clang-format on
99 template <std::size_t N, typename T, typename F>
101 {
103 }
104 
105 // clang-format off
106 /// Create a graphviz representation of the dataframe computation graph, return it as a string.
107 /// \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.
108 ///
109 /// Note that SaveGraph is not thread-safe and must not be called concurrently from different threads.
110 // clang-format on
111 template <typename NodeType>
112 std::string SaveGraph(NodeType node)
113 {
115  return helper(node);
116 }
117 
118 // clang-format off
119 /// Create a graphviz representation of the dataframe computation graph, write it to the specified file.
120 /// \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.
121 /// \param[in] outputFile file where to save the representation.
122 ///
123 /// Note that SaveGraph is not thread-safe and must not be called concurrently from different threads.
124 // clang-format on
125 template <typename NodeType>
126 void SaveGraph(NodeType node, const std::string &outputFile)
127 {
129  std::string dotGraph = helper(node);
130 
131  std::ofstream out(outputFile);
132  if (!out.is_open()) {
133  throw std::runtime_error("Could not open output file \"" + outputFile + "\"for reading");
134  }
135 
136  out << dotGraph;
137  out.close();
138 }
139 
140 // clang-format off
141 /// Cast a RDataFrame node to the common type ROOT::RDF::RNode
142 /// \param[in] node Any node of a RDataFrame graph
143 // clang-format on
144 template <typename NodeType>
145 RNode AsRNode(NodeType node)
146 {
147  return node;
148 }
149 
150 } // namespace RDF
151 } // namespace ROOT
152 #endif
f
#define f(i)
Definition: RSha256.hxx:104
F
#define F(x, y, z)
ROOT::Internal::RDF::PassAsVecHelper
Definition: RDFHelpers.hxx:45
ROOT::Internal::RDF::NotHelper
std::function< bool(ArgTypes...)> NotHelper(ROOT::TypeTraits::TypeList< ArgTypes... >, F &&f)
Definition: RDFHelpers.hxx:33
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:100
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:80
operator()
TRObject operator()(const T1 &t1) const
Definition: TRFunctionImport__oprtr.h:14
ROOT::Internal::RDF::PassAsVec
auto PassAsVec(F &&f) -> PassAsVecHelper< std::make_index_sequence< N >, T, F >
Definition: RDFHelpers.hxx:59
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:112
ROOT::Internal::RDF::NotHelper
std::function< bool(ArgTypes...)> NotHelper(ROOT::TypeTraits::TypeList< ArgTypes... >, Ret(*f)(Args...))
Definition: RDFHelpers.hxx:39
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:89
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:145
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