11#ifndef ROOT_RDF_TINTERFACE_UTILS
12#define ROOT_RDF_TINTERFACE_UTILS
51template<
typename T,
typename V>
71 const std::string &fullTreeName,
72 const std::string &fileName,
75 std::unique_ptr<RDFInternal::RActionBase> actionPtr);
84class RIgnoreErrorLevelRAII {
89 RIgnoreErrorLevelRAII(
int errorIgnoreLevel) {
gErrorIgnoreLevel = errorIgnoreLevel; }
114template <
int D,
typename P,
template <
int,
typename,
template <
typename>
class>
class...
S>
119struct IsV7Hist :
public std::false_type {
120 static_assert(std::is_base_of<TH1, T>::value,
"not implemented for this type");
123template <
int D,
typename P,
template <
int,
typename,
template <
typename>
class>
class...
S>
124struct IsV7Hist<THist<D,
P,
S...>> :
public std::true_type {
127template <typename T, bool ISV7HISTO = IsV7Hist<T>::value>
130 static bool HasAxisLimits(
T &
h)
132 auto xaxis =
h.GetXaxis();
133 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
138struct HistoUtils<
T, true> {
139 static void SetCanExtendAllAxes(
T &) {}
140 static bool HasAxisLimits(
T &) {
return true; }
144template <
typename... BranchTypes,
typename ActionTag,
typename ActionResultType,
typename PrevNodeType>
145std::unique_ptr<RActionBase>
146BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &
h,
const unsigned int nSlots,
149 using Helper_t = FillParHelper<ActionResultType>;
150 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
151 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), customColumns);
155template <
typename... BranchTypes,
typename PrevNodeType>
156std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1D> &
h,
157 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
160 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*
h);
163 using Helper_t = FillParHelper<::TH1D>;
164 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
165 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), customColumns);
167 using Helper_t = FillHelper;
168 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
169 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), customColumns);
173template <
typename... BranchTypes,
typename PrevNodeType>
174std::unique_ptr<RActionBase>
175BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<TGraph> &
g,
const unsigned int nSlots,
178 using Helper_t = FillTGraphHelper;
179 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
180 return std::make_unique<Action_t>(Helper_t(
g, nSlots), bl, std::move(prevNode), customColumns);
184template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
185std::unique_ptr<RActionBase>
186BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &minV,
const unsigned int nSlots,
189 using Helper_t = MinHelper<ActionResultType>;
190 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
191 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), customColumns);
195template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
196std::unique_ptr<RActionBase>
197BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &maxV,
const unsigned int nSlots,
200 using Helper_t = MaxHelper<ActionResultType>;
201 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
202 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), customColumns);
206template <
typename BranchType,
typename PrevNodeType,
typename ActionResultType>
207std::unique_ptr<RActionBase>
208BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &sumV,
const unsigned int nSlots,
211 using Helper_t = SumHelper<ActionResultType>;
212 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
213 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), customColumns);
217template <
typename BranchType,
typename PrevNodeType>
218std::unique_ptr<RActionBase>
219BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
const unsigned int nSlots,
222 using Helper_t = MeanHelper;
223 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
224 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), customColumns);
228template <
typename BranchType,
typename PrevNodeType>
229std::unique_ptr<RActionBase>
230BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &stdDeviationV,
const unsigned int nSlots,
233 using Helper_t = StdDevHelper;
234 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<BranchType>>;
235 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, customColumns);
239template <
typename... BranchTypes,
typename PrevNodeType>
240std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<RDisplay> &
d,
241 const unsigned int, std::shared_ptr<PrevNodeType> prevNode,
244 using Helper_t = DisplayHelper<PrevNodeType>;
245 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<BranchTypes...>>;
246 return std::make_unique<Action_t>(Helper_t(
d, prevNode), bl, prevNode, customColumns);
251template <
typename Filter>
254 using FilterRet_t =
typename RDF::CallableTraits<Filter>::ret_type;
255 static_assert(std::is_same<FilterRet_t, bool>::value,
"filter functions must return a bool");
259 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &dataSourceColumns);
264 std::string_view expression,
const std::map<std::string, std::string> &aliasMap,
269 const std::shared_ptr<RJittedCustomColumn> &jittedCustomColumn,
273 void *
r, TTree *
tree,
const unsigned int nSlots,
275 std::shared_ptr<RJittedAction> *jittedActionOnHeap,
unsigned int namespaceID);
284std::shared_ptr<T> *MakeSharedOnHeap(
const std::shared_ptr<T> &shPtr)
286 return new std::shared_ptr<T>(shPtr);
293std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr);
307 auto getValue = [readers](
unsigned int slot) {
return *readers[slot]; };
310 auto newCol = std::make_shared<NewCol_t>(&lm,
name, std::move(getValue),
ColumnNames_t{}, nSlots, currentCols,
314 currentCols.AddName(
name);
315 currentCols.AddColumn(newCol,
name);
320template <
typename... ColumnTypes, std::size_t...
S>
322AddDSColumns(
RLoopManager &lm,
const std::vector<std::string> &requiredCols,
328 if (std::none_of(mustBeDefined.begin(), mustBeDefined.end(), [](
bool b) { return b; })) {
332 auto newColumns(currentCols);
335 int expander[] = {(mustBeDefined[
S] ? AddDSColumnsHelper<ColumnTypes>(lm, requiredCols[
S], newColumns, ds, nSlots)
346template <
typename F,
typename PrevNode>
352 using ColTypes_t =
typename TTraits::CallableTraits<F>::arg_types;
353 constexpr auto nColumns = ColTypes_t::list_size;
354 RDFInternal::CheckFilter(
f);
359 auto newColumns = ds ? RDFInternal::AddDSColumns(lm, cols, *customColumns, *ds, lm.
GetNSlots(),
365 delete customColumns;
367 jittedFilter->
SetFilter(std::make_unique<F_t>(std::move(
f), cols, *prevNodeOnHeap, newColumns,
name));
368 delete prevNodeOnHeap;
376 using ColTypes_t =
typename TTraits::CallableTraits<F>::arg_types;
377 constexpr auto nColumns = ColTypes_t::list_size;
380 auto newColumns = ds ? RDFInternal::AddDSColumns(*lm, cols, *customColumns, *ds, lm->
GetNSlots(),
386 delete customColumns;
389 std::make_unique<NewCol_t>(lm,
name, std::move(
f), cols, lm->
GetNSlots(), newColumns));
393template <
typename ActionTag,
typename... BranchTypes,
typename PrevNodeType,
typename ActionResultType>
394void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap,
const ColumnNames_t &bl,
const unsigned int nSlots,
395 const std::shared_ptr<ActionResultType> *rOnHeap,
396 std::shared_ptr<RJittedAction> *jittedActionOnHeap,
400 auto &prevNodePtr = *prevNodeOnHeap;
401 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
402 using ColTypes_t =
TypeList<BranchTypes...>;
403 constexpr auto nColumns = ColTypes_t::list_size;
404 auto ds = loopManager.GetDataSource();
405 auto newColumns = ds ? RDFInternal::AddDSColumns(loopManager, bl, *customColumns, *ds, loopManager.GetNSlots(),
409 auto actionPtr = BuildAction<BranchTypes...>(bl, *rOnHeap, nSlots, std::move(prevNodePtr), ActionTag{}, newColumns);
410 (*jittedActionOnHeap)->SetAction(std::move(actionPtr));
414 delete customColumns;
417 delete prevNodeOnHeap;
418 delete jittedActionOnHeap;
422template <typename T, bool Container = TTraits::IsContainer<T>::value && !std::is_same<T, std::string>::value>
423struct TMinReturnType {
428struct TMinReturnType<RInferredType, false> {
433struct TMinReturnType<
T, true> {
434 using type = TTraits::TakeFirstParameter_t<T>;
438template <
typename R,
typename F,
typename... Args>
441 return [
f](
unsigned int, Args...
a) ->
R {
return f(
a...); };
444template <
typename BranchType,
typename... Rest>
446 static constexpr bool value = TNeedJitting<Rest...>::value;
449template <
typename... Rest>
450struct TNeedJitting<RInferredType, Rest...> {
451 static constexpr bool value =
true;
455struct TNeedJitting<
T> {
456 static constexpr bool value =
false;
460struct TNeedJitting<RInferredType> {
461 static constexpr bool value =
true;
471 typename mergeArgsNoDecay_t =
typename CallableTraits<Merge>::arg_types_nodecay,
472 typename mergeArgs_t =
typename CallableTraits<Merge>::arg_types,
473 typename mergeRet_t =
typename CallableTraits<Merge>::ret_type>
476 constexpr bool isAggregatorOk =
477 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
478 static_assert(isAggregatorOk,
"aggregator function must have signature `U(U,T)` or `void(U&,T)`");
479 constexpr bool isMergeOk =
480 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
481 (std::is_same<
TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
482 std::is_same<void, mergeRet_t>::value);
483 static_assert(isMergeOk,
"merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
488template <
typename R,
typename T>
489void CheckAggregate(
T)
491 static_assert(
sizeof(
T) == 0,
"aggregator function must take exactly two arguments");
508std::vector<std::string>
GetFilterNames(
const std::shared_ptr<RLoopManager> &loopManager);
511template <
typename NodeType>
512std::vector<std::string>
GetFilterNames(
const std::shared_ptr<NodeType> &node)
514 std::vector<std::string> filterNames;
515 node->AddFilterName(filterNames);
524using IsTrueForAllImpl_t =
typename std::is_same<TBoolPack<bs...,
true>, TBoolPack<
true, bs...>>;
526template <
bool... Conditions>
528 static constexpr bool value = IsTrueForAllImpl_t<Conditions...>::value;
535struct IsList_t : std::false_type {};
538struct IsList_t<
std::list<T>> : std::true_type {};
541struct IsDeque_t : std::false_type {};
544struct IsDeque_t<
std::deque<T>> : std::true_type {};
558using MaxReturnType_t = MinReturnType_t<T>;
561using 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)())
A wrapper around a concrete RCustomColumn, which forwards all calls to it RJittedCustomColumn is a pl...
void SetCustomColumn(std::unique_ptr< RCustomColumnBase > c)
A wrapper around a concrete RFilter, which forwards all calls to it RJittedFilter is the type of the ...
void SetFilter(std::unique_ptr< RFilterBase > f)
The head node of a RDF computation graph.
void RegisterCustomColumn(RCustomColumnBase *column)
RDataSource * GetDataSource() const
unsigned int GetNSlots() const
virtual RLoopManager * GetLoopManagerUnchecked()
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.
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 object has a header with a name and a title.
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.
ColumnNames_t ConvertRegexToColumns(const ROOT::RDF::RNode &node, std::string_view columnNameRegexp, std::string_view callerName)
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)
ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns, const ColumnNames_t &definedCols, const ColumnNames_t &dataSourceColumns)
std::string JitBuildAction(const ColumnNames_t &bl, void *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::shared_ptr< RJittedAction > *jittedActionOnHeap, unsigned int namespaceID)
HeadNode_t CreateSnaphotRDF(const ColumnNames_t &validCols, const std::string &fullTreeName, const std::string &fileName, bool isLazy, RLoopManager &loopManager, std::unique_ptr< RDFInternal::RActionBase > actionPtr)
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 BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm, RDataSource *ds, const std::shared_ptr< RJittedCustomColumn > &jittedCustomColumn, const RDFInternal::RBookedCustomColumns &customCols, const ColumnNames_t &branches)
void BookFilterJit(RJittedFilter *jittedFilter, void *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, unsigned int namespaceID)
void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols, const std::map< std::string, std::string > &aliasMap, const ColumnNames_t &dataSourceColumns)
RInterface<::ROOT::Detail::RDF::RNodeBase, void > RNode
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.
Namespace for new ROOT classes and functions.
ROOT::Detail::RDF::ColumnNames_t ColumnNames_t
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)
basic_string_view< char > string_view
make_integer_sequence< size_t, _Np > make_index_sequence
Lightweight storage for a collection of types.