11#ifndef ROOT_RDF_TINTERFACE_UTILS
12#define ROOT_RDF_TINTERFACE_UTILS
39#include <unordered_map>
52template<
typename T,
typename V>
76 std::unique_ptr<RDFInternal::RActionBase> actionPtr);
85class RIgnoreErrorLevelRAII {
90 RIgnoreErrorLevelRAII(
int errorIgnoreLevel) {
gErrorIgnoreLevel = errorIgnoreLevel; }
115template <typename T, bool ISV6HISTO = std::is_base_of<TH1, T>::value>
118 static bool HasAxisLimits(
T &
h)
120 auto xaxis =
h.GetXaxis();
121 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
126struct HistoUtils<
T, false> {
127 static void SetCanExtendAllAxes(
T &) {}
128 static bool HasAxisLimits(
T &) {
return true; }
132template <
typename... BranchTypes,
typename ActionTag,
typename ActionResultType,
typename PrevNodeType>
133std::unique_ptr<RActionBase>
134BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &
h,
const unsigned int nSlots,
137 using Helper_t = FillParHelper<ActionResultType>;
138 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
139 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), std::move(customColumns));
143template <
typename... BranchTypes,
typename PrevNodeType>
144std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1D> &
h,
145 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
148 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*
h);
151 using Helper_t = FillParHelper<::TH1D>;
152 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
153 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), std::move(customColumns));
155 using Helper_t = FillHelper;
156 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
157 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), std::move(customColumns));
161template <
typename... BranchTypes,
typename PrevNodeType>
162std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<TGraph> &
g,
163 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
166 using Helper_t = FillTGraphHelper;
167 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
168 return std::make_unique<Action_t>(Helper_t(
g, nSlots), bl, std::move(prevNode), std::move(customColumns));
172template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
173std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &minV,
174 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
177 using Helper_t = MinHelper<ActionResultType>;
178 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
179 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), std::move(customColumns));
183template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
184std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &maxV,
185 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
188 using Helper_t = MaxHelper<ActionResultType>;
189 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
190 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), std::move(customColumns));
194template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
195std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &sumV,
196 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
199 using Helper_t = SumHelper<ActionResultType>;
200 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
201 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), std::move(customColumns));
205template <
typename BranchType,
typename PrevNodeType>
206std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
207 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
210 using Helper_t = MeanHelper;
211 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
212 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), std::move(customColumns));
216template <
typename BranchType,
typename PrevNodeType>
217std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &stdDeviationV,
218 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
221 using Helper_t = StdDevHelper;
222 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
223 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, std::move(customColumns));
227template <
typename... BranchTypes,
typename PrevNodeType>
228std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<RDisplay> &
d,
229 const unsigned int, std::shared_ptr<PrevNodeType> prevNode,
232 using Helper_t = DisplayHelper<PrevNodeType>;
233 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
234 return std::make_unique<Action_t>(Helper_t(
d, prevNode), bl, prevNode, std::move(customColumns));
239template <
typename Filter>
242 using FilterRet_t =
typename RDF::CallableTraits<Filter>::ret_type;
243 static_assert(std::is_convertible<FilterRet_t, bool>::value,
244 "filter expression returns a type that is not convertible to bool");
248 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &dataSourceColumns);
252void BookFilterJit(
const std::shared_ptr<RJittedFilter> &jittedFilter, std::shared_ptr<RNodeBase> *prevNodeOnHeap,
254 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &branches,
259 const ColumnNames_t &branches,
260 std::shared_ptr<RNodeBase> *prevNodeOnHeap);
262std::string
JitBuildAction(
const ColumnNames_t &bl, std::shared_ptr<RDFDetail::RNodeBase> *prevNode,
263 const std::type_info &art,
const std::type_info &at,
void *rOnHeap,
TTree *
tree,
265 RDataSource *ds, std::weak_ptr<RJittedAction> *jittedActionOnHeap);
274std::weak_ptr<T> *MakeWeakOnHeap(
const std::shared_ptr<T> &shPtr)
276 return new std::weak_ptr<T>(shPtr);
281std::shared_ptr<T> *MakeSharedOnHeap(
const std::shared_ptr<T> &shPtr)
283 return new std::shared_ptr<T>(shPtr);
290std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr);
293 const ColumnNames_t &validCustomColumns,
RDataSource *ds);
295std::vector<std::string>
GetValidatedArgTypes(
const ColumnNames_t &colNames,
const RBookedCustomColumns &customColumns,
299std::vector<bool>
FindUndefinedDSColumns(
const ColumnNames_t &requestedCols,
const ColumnNames_t &definedDSCols);
301using ROOT::Detail::RDF::ColumnNames_t;
307 auto getValue = [readers](
unsigned int slot) {
return *readers[slot]; };
310 auto newCol = std::make_shared<NewCol_t>(
name, ds.
GetTypeName(
name), std::move(getValue), ColumnNames_t{}, nSlots,
312 currentCols.AddName(
name);
313 currentCols.AddColumn(newCol,
name);
318template <
typename... ColumnTypes, std::size_t...
S>
325 if (std::none_of(mustBeDefined.begin(), mustBeDefined.end(), [](
bool b) { return b; })) {
329 auto newColumns(currentCols);
332 int expander[] = {(mustBeDefined[
S] ? AddDSColumnsHelper<ColumnTypes>(requiredCols[
S], newColumns, ds, nSlots)
343template <
typename F,
typename PrevNode>
345 std::weak_ptr<RJittedFilter> *wkJittedFilter, std::shared_ptr<PrevNode> *prevNodeOnHeap,
348 if (wkJittedFilter->expired()) {
351 delete wkJittedFilter;
354 delete customColumns;
355 delete prevNodeOnHeap;
359 const auto jittedFilter = wkJittedFilter->lock();
364 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
365 constexpr auto nColumns = ColTypes_t::list_size;
366 RDFInternal::CheckFilter(
f);
368 auto &lm = *jittedFilter->GetLoopManagerUnchecked();
369 auto ds = lm.GetDataSource();
371 auto newColumns = ds ? RDFInternal::AddDSColumns(cols, *customColumns, *ds, lm.GetNSlots(),
372 std::make_index_sequence<nColumns>(), ColTypes_t())
377 delete customColumns;
379 jittedFilter->SetFilter(std::make_unique<F_t>(std::forward<F>(
f), cols, *prevNodeOnHeap, newColumns,
name));
380 delete prevNodeOnHeap;
381 delete wkJittedFilter;
386 std::weak_ptr<RJittedCustomColumn> *wkJittedCustomCol,
389 if (wkJittedCustomCol->expired()) {
392 delete wkJittedCustomCol;
395 delete customColumns;
396 delete prevNodeOnHeap;
400 auto jittedCustomCol = wkJittedCustomCol->lock();
404 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
405 constexpr auto nColumns = ColTypes_t::list_size;
408 auto newColumns = ds ? RDFInternal::AddDSColumns(cols, *customColumns, *ds, lm->
GetNSlots(),
409 std::make_index_sequence<nColumns>(), ColTypes_t())
414 delete customColumns;
417 delete prevNodeOnHeap;
421 const auto dummyType =
"jittedCol_t";
423 jittedCustomCol->SetCustomColumn(std::unique_ptr<RCustomColumnBase>(
424 new NewCol_t(
name, dummyType, std::forward<F>(
f), cols, lm->
GetNSlots(), newColumns)));
426 delete wkJittedCustomCol;
430template <
typename ActionTag,
typename... BranchTypes,
typename PrevNodeType,
typename ActionResultType>
431void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap,
const ColumnNames_t &bl,
const unsigned int nSlots,
432 std::weak_ptr<ActionResultType> *wkROnHeap, std::weak_ptr<RJittedAction> *wkJittedActionOnHeap,
435 if (wkROnHeap->expired()) {
437 delete wkJittedActionOnHeap;
440 delete customColumns;
441 delete prevNodeOnHeap;
445 const auto rOnHeap = wkROnHeap->lock();
446 auto jittedActionOnHeap = wkJittedActionOnHeap->lock();
449 auto &prevNodePtr = *prevNodeOnHeap;
450 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
451 using ColTypes_t =
TypeList<BranchTypes...>;
452 constexpr auto nColumns = ColTypes_t::list_size;
453 auto ds = loopManager.GetDataSource();
454 auto newColumns = ds ? RDFInternal::AddDSColumns(bl, *customColumns, *ds, loopManager.GetNSlots(),
455 std::make_index_sequence<nColumns>(), ColTypes_t())
458 auto actionPtr = BuildAction<BranchTypes...>(bl, std::move(rOnHeap), nSlots, std::move(prevNodePtr), ActionTag{},
459 std::move(newColumns));
460 jittedActionOnHeap->SetAction(std::move(actionPtr));
464 delete customColumns;
467 delete prevNodeOnHeap;
468 delete wkJittedActionOnHeap;
472template <typename T, bool Container = RDFInternal::IsDataContainer<T>::value && !std::is_same<T, std::string>::value>
473struct TMinReturnType {
478struct TMinReturnType<RInferredType, false> {
483struct TMinReturnType<
T, true> {
484 using type = TTraits::TakeFirstParameter_t<T>;
488template <
typename R,
typename F,
typename... Args>
491 return [
f](
unsigned int, Args...
a) ->
R {
return f(
a...); };
494template <
typename BranchType,
typename... Rest>
496 static constexpr bool value = TNeedJitting<Rest...>::value;
499template <
typename... Rest>
500struct TNeedJitting<RInferredType, Rest...> {
501 static constexpr bool value =
true;
505struct TNeedJitting<
T> {
506 static constexpr bool value =
false;
510struct TNeedJitting<RInferredType> {
511 static constexpr bool value =
true;
519 typename mergeArgsNoDecay_t =
typename CallableTraits<Merge>::arg_types_nodecay,
520 typename mergeArgs_t =
typename CallableTraits<Merge>::arg_types,
521 typename mergeRet_t =
typename CallableTraits<Merge>::ret_type>
524 constexpr bool isAggregatorOk =
525 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
526 static_assert(isAggregatorOk,
"aggregator function must have signature `U(U,T)` or `void(U&,T)`");
527 constexpr bool isMergeOk =
528 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
529 (std::is_same<
TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
530 std::is_same<void, mergeRet_t>::value);
531 static_assert(isMergeOk,
"merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
536template <
typename R,
typename T>
537void CheckAggregate(
T)
539 static_assert(
sizeof(
T) == 0,
"aggregator function must take exactly two arguments");
547const ColumnNames_t
SelectColumns(
unsigned int nArgs,
const ColumnNames_t &bl,
const ColumnNames_t &defBl);
550ColumnNames_t
FindUnknownColumns(
const ColumnNames_t &requiredCols,
const ColumnNames_t &datasetColumns,
551 const ColumnNames_t &definedCols,
const ColumnNames_t &dataSourceColumns);
556std::vector<std::string>
GetFilterNames(
const std::shared_ptr<RLoopManager> &loopManager);
559template <
typename NodeType>
560std::vector<std::string>
GetFilterNames(
const std::shared_ptr<NodeType> &node)
562 std::vector<std::string> filterNames;
563 node->AddFilterName(filterNames);
572using IsTrueForAllImpl_t =
typename std::is_same<TBoolPack<bs...,
true>, TBoolPack<
true, bs...>>;
574template <
bool... Conditions>
576 static constexpr bool value = IsTrueForAllImpl_t<Conditions...>::value;
583struct IsList_t : std::false_type {};
586struct IsList_t<std::list<T>> : std::true_type {};
589struct IsDeque_t : std::false_type {};
592struct IsDeque_t<std::deque<T>> : std::true_type {};
606using MaxReturnType_t = MinReturnType_t<T>;
609using SumReturnType_t = MinReturnType_t<T>;
#define R(a, b, c, d, e, f, g, h, i)
R__EXTERN Int_t gErrorIgnoreLevel
typedef void((*Func_t)())
The head node of a RDF computation graph.
RDataSource * GetDataSource() const
unsigned int GetNSlots() const
Encapsulates the columns defined by the user.
ColumnNames_t GetNames() const
Returns the list of the names of the defined columns.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
virtual std::string GetTypeName(std::string_view) const =0
Type of a column as a string, e.g.
std::vector< T ** > GetColumnReaders(std::string_view columnName)
Called at most once per column by RDF.
The public interface to the RDataFrame federation of classes.
Smart pointer for the return type of actions.
A TTree represents a columnar dataset.
basic_string_view< char > string_view
const ColumnNames_t SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
Choose between local column names or default column names, throw in case of errors.
void BookFilterJit(const std::shared_ptr< RJittedFilter > &jittedFilter, std::shared_ptr< RDFDetail::RNodeBase > *prevNodeOnHeap, std::string_view name, std::string_view expression, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &branches, const RDFInternal::RBookedCustomColumns &customCols, TTree *tree, RDataSource *ds)
std::vector< std::string > GetValidatedArgTypes(const ColumnNames_t &colNames, const RBookedCustomColumns &customColumns, TTree *tree, RDataSource *ds, const std::string &context, bool vector2rvec)
std::shared_ptr< RNodeBase > UpcastNode(std::shared_ptr< RNodeBase > ptr)
std::vector< std::string > GetFilterNames(const std::shared_ptr< RLoopManager > &loopManager)
ColumnNames_t ConvertRegexToColumns(const RDFInternal::RBookedCustomColumns &customColumns, TTree *tree, ROOT::RDF::RDataSource *dataSource, std::string_view columnNameRegexp, std::string_view callerName)
std::string PrettyPrintAddr(const void *const addr)
std::shared_ptr< RJittedCustomColumn > BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds, const RDFInternal::RBookedCustomColumns &customCols, const ColumnNames_t &branches, std::shared_ptr< RNodeBase > *upcastNodeOnHeap)
void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames)
std::string DemangleTypeIdName(const std::type_info &typeInfo)
bool AtLeastOneEmptyString(const std::vector< std::string_view > strings)
ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns, const ColumnNames_t &definedCols, const ColumnNames_t &dataSourceColumns)
HeadNode_t CreateSnapshotRDF(const ColumnNames_t &validCols, std::string_view treeName, std::string_view fileName, bool isLazy, RLoopManager &loopManager, std::unique_ptr< RDFInternal::RActionBase > actionPtr)
std::string JitBuildAction(const ColumnNames_t &bl, std::shared_ptr< RDFDetail::RNodeBase > *prevNode, const std::type_info &art, const std::type_info &at, void *rOnHeap, TTree *tree, const unsigned int nSlots, const RDFInternal::RBookedCustomColumns &customCols, RDataSource *ds, std::weak_ptr< RJittedAction > *jittedActionOnHeap)
bool IsInternalColumn(std::string_view colName)
ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const ColumnNames_t &validCustomColumns, RDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
std::vector< bool > FindUndefinedDSColumns(const ColumnNames_t &requestedCols, const ColumnNames_t &definedCols)
Return a bitset each element of which indicates whether the corresponding element in selectedColumns ...
void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &dataSourceColumns)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
ROOT type_traits extensions.
T Sum(const RVec< T > &v)
Sum elements of an RVec.
RVec< T > Filter(const RVec< T > &v, F &&f)
Create a new collection with the elements passing the filter expressed by the predicate.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
RooArgSet S(const RooAbsArg &v1)
Short_t Max(Short_t a, Short_t b)
Double_t Mean(Long64_t n, const T *a, const Double_t *w=0)
Return the weighted mean of an array a with length n.
Short_t Min(Short_t a, Short_t b)
Double_t StdDev(Long64_t n, const T *a, const Double_t *w=0)
Lightweight storage for a collection of types.