11#ifndef ROOT_RDF_TINTERFACE_UTILS
12#define ROOT_RDF_TINTERFACE_UTILS
40#include <unordered_map>
53template<
typename T,
typename V>
79class RIgnoreErrorLevelRAII {
84 RIgnoreErrorLevelRAII(
int errorIgnoreLevel) {
gErrorIgnoreLevel = errorIgnoreLevel; }
110template <typename T, bool ISV6HISTO = std::is_base_of<TH1, T>::value>
113 static bool HasAxisLimits(T &
h)
115 auto xaxis =
h.GetXaxis();
116 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
121struct HistoUtils<
T, false> {
122 static void SetCanExtendAllAxes(T &) {}
123 static bool HasAxisLimits(T &) {
return true; }
127template <
typename... ColTypes,
typename ActionTag,
typename ActionResultType,
typename PrevNodeType>
128std::unique_ptr<RActionBase>
129BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &
h,
const unsigned int nSlots,
132 using Helper_t = FillParHelper<ActionResultType>;
133 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
134 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
138template <
typename... ColTypes,
typename PrevNodeType>
139std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1D> &
h,
140 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
143 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*
h);
146 using Helper_t = FillParHelper<::TH1D>;
147 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
148 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
150 using Helper_t = FillHelper;
151 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
152 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
156template <
typename... ColTypes,
typename PrevNodeType>
157std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<TGraph> &
g,
158 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
161 using Helper_t = FillTGraphHelper;
162 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
163 return std::make_unique<Action_t>(Helper_t(
g, nSlots), bl, std::move(prevNode), defines);
167template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
168std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &minV,
169 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
172 using Helper_t = MinHelper<ActionResultType>;
173 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
174 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), defines);
178template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
179std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &maxV,
180 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
183 using Helper_t = MaxHelper<ActionResultType>;
184 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
185 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), defines);
189template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
190std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &sumV,
191 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
194 using Helper_t = SumHelper<ActionResultType>;
195 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
196 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), defines);
200template <
typename ColType,
typename PrevNodeType>
201std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
202 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
205 using Helper_t = MeanHelper;
206 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
207 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), defines);
211template <
typename ColType,
typename PrevNodeType>
212std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &stdDeviationV,
213 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
216 using Helper_t = StdDevHelper;
217 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
218 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, defines);
222template <
typename... ColTypes,
typename PrevNodeType>
223std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<RDisplay> &
d,
224 const unsigned int, std::shared_ptr<PrevNodeType> prevNode,
227 using Helper_t = DisplayHelper<PrevNodeType>;
228 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
229 return std::make_unique<Action_t>(Helper_t(
d, prevNode), bl, prevNode, defines);
232struct SnapshotHelperArgs {
233 std::string fFileName;
234 std::string fDirName;
235 std::string fTreeName;
236 std::vector<std::string> fOutputColNames;
241template <
typename... ColTypes,
typename PrevNodeType>
242std::unique_ptr<RActionBase>
243BuildAction(
const ColumnNames_t &colNames,
const std::shared_ptr<SnapshotHelperArgs> &snapHelperArgs,
244 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode, ActionTags::Snapshot,
247 const auto &filename = snapHelperArgs->fFileName;
248 const auto &dirname = snapHelperArgs->fDirName;
249 const auto &treename = snapHelperArgs->fTreeName;
250 const auto &outputColNames = snapHelperArgs->fOutputColNames;
251 const auto &options = snapHelperArgs->fOptions;
253 std::unique_ptr<RActionBase> actionPtr;
256 using Helper_t = SnapshotHelper<ColTypes...>;
257 using Action_t = RAction<Helper_t, PrevNodeType>;
258 actionPtr.reset(
new Action_t(Helper_t(filename, dirname, treename, colNames, outputColNames, options), colNames,
262 using Helper_t = SnapshotHelperMT<ColTypes...>;
263 using Action_t = RAction<Helper_t, PrevNodeType>;
264 actionPtr.reset(
new Action_t(Helper_t(nSlots, filename, dirname, treename, colNames, outputColNames, options),
265 colNames, prevNode, defines));
272template <
typename Filter>
273void CheckFilter(Filter &)
275 using FilterRet_t =
typename RDF::CallableTraits<Filter>::ret_type;
276 static_assert(std::is_convertible<FilterRet_t, bool>::value,
277 "filter expression returns a type that is not convertible to bool");
281 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &dataSourceColumns);
285void BookFilterJit(
const std::shared_ptr<RJittedFilter> &jittedFilter, std::shared_ptr<RNodeBase> *prevNodeOnHeap,
286 std::string_view
name, std::string_view expression,
287 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &branches,
293 std::shared_ptr<RNodeBase> *prevNodeOnHeap);
296 const std::type_info &art,
const std::type_info &at,
void *rOnHeap,
TTree *
tree,
298 RDataSource *ds, std::weak_ptr<RJittedAction> *jittedActionOnHeap);
307std::weak_ptr<T> *MakeWeakOnHeap(
const std::shared_ptr<T> &shPtr)
309 return new std::weak_ptr<T>(shPtr);
314std::shared_ptr<T> *MakeSharedOnHeap(
const std::shared_ptr<T> &shPtr)
316 return new std::shared_ptr<T>(shPtr);
323std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr);
342 const auto valuePtrs =
ds.GetColumnReaders<
T>(colName);
343 if (!valuePtrs.empty()) {
345 std::vector<void*> typeErasedValuePtrs(valuePtrs.begin(), valuePtrs.end());
352template <
typename... ColumnTypes>
357 using expander =
int[];
359 (
void)expander{(AddDSColumnsHelper<ColumnTypes>(requiredCols[i], lm, ds), ++i)..., 0};
363template <
typename F,
typename PrevNode>
364void JitFilterHelper(
F &&
f,
const char **colsPtr, std::size_t colsSize, std::string_view
name,
365 std::weak_ptr<RJittedFilter> *wkJittedFilter, std::shared_ptr<PrevNode> *prevNodeOnHeap,
368 if (wkJittedFilter->expired()) {
371 delete wkJittedFilter;
375 delete prevNodeOnHeap;
382 const auto jittedFilter = wkJittedFilter->lock();
385 using Callable_t =
typename std::decay<F>::type;
387 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
388 constexpr auto nColumns = ColTypes_t::list_size;
389 RDFInternal::CheckFilter(
f);
395 RDFInternal::AddDSColumns(cols, lm, *ds, ColTypes_t());
397 jittedFilter->SetFilter(
398 std::unique_ptr<RFilterBase>(
new F_t(std::forward<F>(
f), cols, *prevNodeOnHeap, *defines,
name)));
402 delete prevNodeOnHeap;
403 delete wkJittedFilter;
407void JitDefineHelper(
F &&
f,
const char **colsPtr, std::size_t colsSize, std::string_view
name,
RLoopManager *lm,
408 std::weak_ptr<RJittedDefine> *wkJittedDefine,
411 if (wkJittedDefine->expired()) {
414 delete wkJittedDefine;
418 delete prevNodeOnHeap;
425 auto jittedDefine = wkJittedDefine->lock();
427 using Callable_t =
typename std::decay<F>::type;
429 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
430 constexpr auto nColumns = ColTypes_t::list_size;
434 RDFInternal::AddDSColumns(cols, *lm, *ds, ColTypes_t());
438 const auto dummyType =
"jittedCol_t";
440 jittedDefine->SetDefine(std::unique_ptr<RDefineBase>(
448 delete prevNodeOnHeap;
449 delete wkJittedDefine;
453template <
typename ActionTag,
typename... ColTypes,
typename PrevNodeType,
typename HelperArgType>
454void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap,
const char **colsPtr, std::size_t colsSize,
455 const unsigned int nSlots, std::shared_ptr<HelperArgType> *helperArgOnHeap,
458 if (wkJittedActionOnHeap->expired()) {
459 delete helperArgOnHeap;
460 delete wkJittedActionOnHeap;
464 delete prevNodeOnHeap;
471 auto jittedActionOnHeap = wkJittedActionOnHeap->lock();
474 auto &prevNodePtr = *prevNodeOnHeap;
475 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
476 using ColTypes_t =
TypeList<ColTypes...>;
477 constexpr auto nColumns = ColTypes_t::list_size;
478 auto ds = loopManager.GetDataSource();
480 RDFInternal::AddDSColumns(cols, loopManager, *ds, ColTypes_t());
483 BuildAction<ColTypes...>(cols, std::move(*helperArgOnHeap), nSlots, std::move(prevNodePtr), ActionTag{}, *defines);
484 loopManager.AddDataBlockCallback(actionPtr->GetDataBlockCallback());
485 jittedActionOnHeap->SetAction(std::move(actionPtr));
491 delete helperArgOnHeap;
492 delete prevNodeOnHeap;
493 delete wkJittedActionOnHeap;
497template <typename T, bool Container = RDFInternal::IsDataContainer<T>::value && !std::is_same<T, std::string>::value>
498struct RMinReturnType {
503struct RMinReturnType<RInferredType, false> {
508struct RMinReturnType<
T, true> {
509 using type = TTraits::TakeFirstParameter_t<T>;
513template <
typename R,
typename F,
typename... Args>
516 return [
f](
unsigned int, Args...
a)
mutable ->
R {
return f(
a...); };
519template <
typename ColType,
typename... Rest>
520struct RNeedJittingHelper {
521 static constexpr bool value = RNeedJittingHelper<Rest...>::value;
524template <
typename... Rest>
525struct RNeedJittingHelper<RInferredType, Rest...> {
526 static constexpr bool value =
true;
530struct RNeedJittingHelper<
T> {
531 static constexpr bool value =
false;
535struct RNeedJittingHelper<RInferredType> {
536 static constexpr bool value =
true;
539template <
typename ...ColTypes>
541 static constexpr bool value = RNeedJittingHelper<ColTypes...>::value;
545struct RNeedJitting<> {
546 static constexpr bool value =
false;
553template <typename R, typename Merge, typename U, typename T, typename decayedU = typename std::decay<U>::type,
554 typename mergeArgsNoDecay_t =
typename CallableTraits<Merge>::arg_types_nodecay,
555 typename mergeArgs_t =
typename CallableTraits<Merge>::arg_types,
556 typename mergeRet_t =
typename CallableTraits<Merge>::ret_type>
559 constexpr bool isAggregatorOk =
560 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
561 static_assert(isAggregatorOk,
"aggregator function must have signature `U(U,T)` or `void(U&,T)`");
562 constexpr bool isMergeOk =
563 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
564 (std::is_same<
TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
565 std::is_same<void, mergeRet_t>::value);
566 static_assert(isMergeOk,
"merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
571template <
typename R,
typename T>
572void CheckAggregate(T)
574 static_assert(
sizeof(
T) == 0,
"aggregator function must take exactly two arguments");
589std::vector<std::string>
GetFilterNames(
const std::shared_ptr<RLoopManager> &loopManager);
592template <
typename NodeType>
593std::vector<std::string>
GetFilterNames(
const std::shared_ptr<NodeType> &node)
595 std::vector<std::string> filterNames;
596 node->AddFilterName(filterNames);
600struct ParsedTreePath {
601 std::string fTreeName;
602 std::string fDirName;
612using IsTrueForAllImpl_t =
typename std::is_same<TBoolPack<bs...,
true>, TBoolPack<
true, bs...>>;
614template <
bool... Conditions>
616 static constexpr bool value = IsTrueForAllImpl_t<Conditions...>::value;
623struct IsList_t : std::false_type {};
626struct IsList_t<std::list<T>> : std::true_type {};
629struct IsDeque_t : std::false_type {};
632struct IsDeque_t<std::deque<T>> : std::true_type {};
643using MinReturnType_t =
typename RDFInternal::RMinReturnType<T>::type;
646using MaxReturnType_t = MinReturnType_t<T>;
649using SumReturnType_t = MinReturnType_t<T>;
R__EXTERN Int_t gErrorIgnoreLevel
typedef void((*Func_t)())
The head node of a RDF computation graph.
void AddDSValuePtrs(const std::string &col, const std::vector< void * > ptrs)
const std::map< std::string, std::vector< void * > > & GetDSValuePtrs() const
RDataSource * GetDataSource() const
unsigned int GetNSlots() const
bool HasDSValuePtrs(const std::string &col) const
RLoopManager * GetLoopManagerUnchecked() final
Encapsulates the columns defined by the user.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
The public interface to the RDataFrame federation of classes.
A TTree represents a columnar dataset.
std::vector< std::string > ColumnNames_t
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.
ParsedTreePath ParseTreePath(std::string_view fullTreeName)
std::shared_ptr< RNodeBase > UpcastNode(std::shared_ptr< RNodeBase > ptr)
std::vector< std::string > GetFilterNames(const std::shared_ptr< RLoopManager > &loopManager)
std::string PrettyPrintAddr(const void *const addr)
ColumnNames_t GetTopLevelBranchNames(TTree &t)
Get all the top-level branches names, including the ones of the friend trees.
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)
std::string JitBuildAction(const ColumnNames_t &cols, std::shared_ptr< RDFDetail::RNodeBase > *prevNode, const std::type_info &helperArgType, const std::type_info &at, void *helperArgOnHeap, TTree *tree, const unsigned int nSlots, const RDFInternal::RBookedDefines &customCols, RDataSource *ds, std::weak_ptr< RJittedAction > *jittedActionOnHeap)
ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns, const ColumnNames_t &validDefines, RDataSource *ds)
Given the desired number of columns and the user-provided list of columns:
ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns, const ColumnNames_t &definedCols, const ColumnNames_t &dataSourceColumns)
void CheckDefine(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &dataSourceColumns)
ColumnNames_t ConvertRegexToColumns(const ColumnNames_t &colNames, std::string_view columnNameRegexp, std::string_view callerName)
std::vector< std::string > GetValidatedArgTypes(const ColumnNames_t &colNames, const RBookedDefines &defines, TTree *tree, RDataSource *ds, const std::string &context, bool vector2rvec)
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 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::RBookedDefines &customCols, TTree *tree, RDataSource *ds)
std::shared_ptr< RJittedDefine > BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds, const RDFInternal::RBookedDefines &customCols, const ColumnNames_t &branches, std::shared_ptr< RNodeBase > *upcastNodeOnHeap)
ROOT type_traits extensions.
T Sum(const RVec< T > &v)
Sum elements of an RVec.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
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)
A collection of options to steer the creation of the dataset on file.
Lightweight storage for a collection of types.