File indexing completed on 2025-09-15 09:11:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef ROOT_RDF_TINTERFACE_UTILS
0012 #define ROOT_RDF_TINTERFACE_UTILS
0013
0014 #include "RColumnRegister.hxx"
0015 #include <ROOT/RDF/RAction.hxx>
0016 #include <ROOT/RDF/ActionHelpers.hxx> // for BuildAction
0017 #include <ROOT/RDF/RColumnRegister.hxx>
0018 #include <ROOT/RDF/RDefine.hxx>
0019 #include <ROOT/RDF/RDefinePerSample.hxx>
0020 #include <ROOT/RDF/RFilter.hxx>
0021 #include <ROOT/RDF/Utils.hxx>
0022 #include <ROOT/RDF/RJittedAction.hxx>
0023 #include <ROOT/RDF/RJittedDefine.hxx>
0024 #include <ROOT/RDF/RJittedFilter.hxx>
0025 #include <ROOT/RDF/RJittedVariation.hxx>
0026 #include <ROOT/RDF/RLoopManager.hxx>
0027 #include <string_view>
0028 #include <ROOT/RDF/RVariation.hxx>
0029 #include <ROOT/TypeTraits.hxx>
0030 #include <TError.h> // gErrorIgnoreLevel
0031 #include <TH1.h>
0032 #include <TROOT.h> // IsImplicitMTEnabled
0033
0034 #include <deque>
0035 #include <functional>
0036 #include <map>
0037 #include <memory>
0038 #include <string>
0039 #include <type_traits>
0040 #include <typeinfo>
0041 #include <vector>
0042 #include <unordered_map>
0043
0044 class TObjArray;
0045 class TTree;
0046 namespace ROOT {
0047 namespace Detail {
0048 namespace RDF {
0049 class RNodeBase;
0050 }
0051 }
0052 namespace RDF {
0053 template <typename T>
0054 class RResultPtr;
0055 template<typename T, typename V>
0056 class RInterface;
0057 using RNode = RInterface<::ROOT::Detail::RDF::RNodeBase, void>;
0058 class RDataSource;
0059 }
0060
0061 }
0062
0063
0064
0065 namespace ROOT {
0066 namespace Internal {
0067 namespace RDF {
0068 using namespace ROOT::Detail::RDF;
0069 using namespace ROOT::RDF;
0070 namespace TTraits = ROOT::TypeTraits;
0071
0072 std::string DemangleTypeIdName(const std::type_info &typeInfo);
0073
0074 ColumnNames_t
0075 ConvertRegexToColumns(const ColumnNames_t &colNames, std::string_view columnNameRegexp, std::string_view callerName);
0076
0077
0078 class RIgnoreErrorLevelRAII {
0079 private:
0080 int fCurIgnoreErrorLevel = gErrorIgnoreLevel;
0081
0082 public:
0083 RIgnoreErrorLevelRAII(int errorIgnoreLevel) { gErrorIgnoreLevel = errorIgnoreLevel; }
0084 ~RIgnoreErrorLevelRAII() { gErrorIgnoreLevel = fCurIgnoreErrorLevel; }
0085 };
0086
0087
0088
0089
0090
0091 namespace ActionTags {
0092 struct Histo1D{};
0093 struct Histo2D{};
0094 struct Histo3D{};
0095 struct HistoND{};
0096 struct Graph{};
0097 struct GraphAsymmErrors{};
0098 struct Profile1D{};
0099 struct Profile2D{};
0100 struct Min{};
0101 struct Max{};
0102 struct Sum{};
0103 struct Mean{};
0104 struct Fill{};
0105 struct StdDev{};
0106 struct Display{};
0107 struct Snapshot{};
0108 struct Book{};
0109 }
0110
0111
0112 template <typename T, bool ISV6HISTO = std::is_base_of<TH1, std::decay_t<T>>::value>
0113 struct HistoUtils {
0114 static void SetCanExtendAllAxes(T &h) { h.SetCanExtend(::TH1::kAllAxes); }
0115 static bool HasAxisLimits(T &h)
0116 {
0117 auto xaxis = h.GetXaxis();
0118 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
0119 }
0120 };
0121
0122 template <typename T>
0123 struct HistoUtils<T, false> {
0124 static void SetCanExtendAllAxes(T &) {}
0125 static bool HasAxisLimits(T &) { return true; }
0126 };
0127
0128
0129 template <typename... ColTypes, typename ActionTag, typename ActionResultType, typename PrevNodeType>
0130 std::unique_ptr<RActionBase>
0131 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &h, const unsigned int nSlots,
0132 std::shared_ptr<PrevNodeType> prevNode, ActionTag, const RColumnRegister &colRegister)
0133 {
0134 using Helper_t = FillHelper<ActionResultType>;
0135 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0136 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0137 }
0138
0139
0140 template <typename... ColTypes, typename PrevNodeType>
0141 std::unique_ptr<RActionBase>
0142 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<::TH1D> &h, const unsigned int nSlots,
0143 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Histo1D, const RColumnRegister &colRegister)
0144 {
0145 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*h);
0146
0147 if (hasAxisLimits || !IsImplicitMTEnabled()) {
0148 using Helper_t = FillHelper<::TH1D>;
0149 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0150 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0151 } else {
0152 using Helper_t = BufferedFillHelper;
0153 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0154 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0155 }
0156 }
0157
0158 template <typename... ColTypes, typename PrevNodeType>
0159 std::unique_ptr<RActionBase>
0160 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<TGraph> &g, const unsigned int nSlots,
0161 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Graph, const RColumnRegister &colRegister)
0162 {
0163 using Helper_t = FillTGraphHelper;
0164 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0165 return std::make_unique<Action_t>(Helper_t(g, nSlots), bl, std::move(prevNode), colRegister);
0166 }
0167
0168 template <typename... ColTypes, typename PrevNodeType>
0169 std::unique_ptr<RActionBase>
0170 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<TGraphAsymmErrors> &g, const unsigned int nSlots,
0171 std::shared_ptr<PrevNodeType> prevNode, ActionTags::GraphAsymmErrors, const RColumnRegister &colRegister)
0172 {
0173 using Helper_t = FillTGraphAsymmErrorsHelper;
0174 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0175 return std::make_unique<Action_t>(Helper_t(g, nSlots), bl, std::move(prevNode), colRegister);
0176 }
0177
0178
0179 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0180 std::unique_ptr<RActionBase>
0181 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &minV, const unsigned int nSlots,
0182 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Min, const RColumnRegister &colRegister)
0183 {
0184 using Helper_t = MinHelper<ActionResultType>;
0185 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0186 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), colRegister);
0187 }
0188
0189
0190 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0191 std::unique_ptr<RActionBase>
0192 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &maxV, const unsigned int nSlots,
0193 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Max, const RColumnRegister &colRegister)
0194 {
0195 using Helper_t = MaxHelper<ActionResultType>;
0196 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0197 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), colRegister);
0198 }
0199
0200
0201 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0202 std::unique_ptr<RActionBase>
0203 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &sumV, const unsigned int nSlots,
0204 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Sum, const RColumnRegister &colRegister)
0205 {
0206 using Helper_t = SumHelper<ActionResultType>;
0207 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0208 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), colRegister);
0209 }
0210
0211
0212 template <typename ColType, typename PrevNodeType>
0213 std::unique_ptr<RActionBase>
0214 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<double> &meanV, const unsigned int nSlots,
0215 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Mean, const RColumnRegister &colRegister)
0216 {
0217 using Helper_t = MeanHelper;
0218 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0219 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), colRegister);
0220 }
0221
0222
0223 template <typename ColType, typename PrevNodeType>
0224 std::unique_ptr<RActionBase>
0225 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<double> &stdDeviationV, const unsigned int nSlots,
0226 std::shared_ptr<PrevNodeType> prevNode, ActionTags::StdDev, const RColumnRegister &colRegister)
0227 {
0228 using Helper_t = StdDevHelper;
0229 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0230 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, colRegister);
0231 }
0232
0233 using displayHelperArgs_t = std::pair<size_t, std::shared_ptr<ROOT::RDF::RDisplay>>;
0234
0235
0236 template <typename... ColTypes, typename PrevNodeType>
0237 std::unique_ptr<RActionBase>
0238 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<displayHelperArgs_t> &helperArgs, const unsigned int,
0239 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Display, const RColumnRegister &colRegister)
0240 {
0241 using Helper_t = DisplayHelper<PrevNodeType>;
0242 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0243 return std::make_unique<Action_t>(Helper_t(helperArgs->first, helperArgs->second, prevNode), bl, prevNode,
0244 colRegister);
0245 }
0246
0247 struct SnapshotHelperArgs {
0248 std::string fFileName;
0249 std::string fDirName;
0250 std::string fTreeName;
0251 std::vector<std::string> fOutputColNames;
0252 ROOT::RDF::RSnapshotOptions fOptions;
0253 ROOT::Detail::RDF::RLoopManager *fOutputLoopManager;
0254 ROOT::Detail::RDF::RLoopManager *fInputLoopManager;
0255 bool fToNTuple;
0256 };
0257
0258
0259 template <typename... ColTypes, typename PrevNodeType>
0260 std::unique_ptr<RActionBase>
0261 BuildAction(const ColumnNames_t &colNames, const std::shared_ptr<SnapshotHelperArgs> &snapHelperArgs,
0262 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode, ActionTags::Snapshot,
0263 const RColumnRegister &colRegister)
0264 {
0265 const auto &filename = snapHelperArgs->fFileName;
0266 const auto &dirname = snapHelperArgs->fDirName;
0267 const auto &treename = snapHelperArgs->fTreeName;
0268 const auto &outputColNames = snapHelperArgs->fOutputColNames;
0269 const auto &options = snapHelperArgs->fOptions;
0270 const auto &lmPtr = snapHelperArgs->fOutputLoopManager;
0271 const auto &inputLM = snapHelperArgs->fInputLoopManager;
0272
0273 auto sz = sizeof...(ColTypes);
0274 std::vector<bool> isDefine(sz);
0275 for (auto i = 0u; i < sz; ++i)
0276 isDefine[i] = colRegister.IsDefineOrAlias(colNames[i]);
0277
0278 std::unique_ptr<RActionBase> actionPtr;
0279 if (snapHelperArgs->fToNTuple) {
0280 if (!ROOT::IsImplicitMTEnabled()) {
0281
0282 using Helper_t = SnapshotRNTupleHelper<ColTypes...>;
0283 using Action_t = RAction<Helper_t, PrevNodeType>;
0284
0285 actionPtr.reset(new Action_t(
0286 Helper_t(filename, dirname, treename, colNames, outputColNames, options, lmPtr, std::move(isDefine)),
0287 colNames, prevNode, colRegister));
0288 } else {
0289
0290
0291 throw std::runtime_error("Snapshot: Snapshotting to RNTuple with IMT enabled is not supported yet.");
0292 }
0293
0294 return actionPtr;
0295 } else {
0296 if (!ROOT::IsImplicitMTEnabled()) {
0297
0298 using Helper_t = SnapshotTTreeHelper<ColTypes...>;
0299 using Action_t = RAction<Helper_t, PrevNodeType>;
0300 actionPtr.reset(new Action_t(Helper_t(filename, dirname, treename, colNames, outputColNames, options,
0301 std::move(isDefine), lmPtr, inputLM),
0302 colNames, prevNode, colRegister));
0303 } else {
0304
0305 using Helper_t = SnapshotTTreeHelperMT<ColTypes...>;
0306 using Action_t = RAction<Helper_t, PrevNodeType>;
0307 actionPtr.reset(new Action_t(Helper_t(nSlots, filename, dirname, treename, colNames, outputColNames, options,
0308 std::move(isDefine), lmPtr, inputLM),
0309 colNames, prevNode, colRegister));
0310 }
0311 }
0312 return actionPtr;
0313 }
0314
0315
0316 template <typename... ColTypes, typename PrevNodeType, typename Helper_t>
0317 std::unique_ptr<RActionBase>
0318 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<Helper_t> &h, const unsigned int ,
0319 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Book, const RColumnRegister &colRegister)
0320 {
0321 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0322 return std::make_unique<Action_t>(Helper_t(std::move(*h)), bl, std::move(prevNode), colRegister);
0323 }
0324
0325
0326
0327 template <typename Filter>
0328 void CheckFilter(Filter &)
0329 {
0330 using FilterRet_t = typename RDF::CallableTraits<Filter>::ret_type;
0331 static_assert(std::is_convertible<FilterRet_t, bool>::value,
0332 "filter expression returns a type that is not convertible to bool");
0333 }
0334
0335 ColumnNames_t FilterArraySizeColNames(const ColumnNames_t &columnNames, const std::string &action);
0336
0337 void CheckValidCppVarName(std::string_view var, const std::string &where);
0338
0339 void CheckForRedefinition(const std::string &where, std::string_view definedCol, const RColumnRegister &colRegister,
0340 const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns);
0341
0342 void CheckForDefinition(const std::string &where, std::string_view definedColView, const RColumnRegister &colRegister,
0343 const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns);
0344
0345 void CheckForNoVariations(const std::string &where, std::string_view definedColView,
0346 const RColumnRegister &colRegister);
0347
0348 std::string PrettyPrintAddr(const void *const addr);
0349
0350 std::shared_ptr<RJittedFilter> BookFilterJit(std::shared_ptr<RNodeBase> *prevNodeOnHeap, std::string_view name,
0351 std::string_view expression, const ColumnNames_t &branches,
0352 const RColumnRegister &colRegister, TTree *tree, RDataSource *ds);
0353
0354 std::shared_ptr<RJittedDefine> BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm,
0355 RDataSource *ds, const RColumnRegister &colRegister,
0356 const ColumnNames_t &branches, std::shared_ptr<RNodeBase> *prevNodeOnHeap);
0357
0358 std::shared_ptr<RJittedDefine> BookDefinePerSampleJit(std::string_view name, std::string_view expression,
0359 RLoopManager &lm, const RColumnRegister &colRegister,
0360 std::shared_ptr<RNodeBase> *upcastNodeOnHeap);
0361
0362 std::shared_ptr<RJittedVariation>
0363 BookVariationJit(const std::vector<std::string> &colNames, std::string_view variationName,
0364 const std::vector<std::string> &variationTags, std::string_view expression, RLoopManager &lm,
0365 RDataSource *ds, const RColumnRegister &colRegister, const ColumnNames_t &branches,
0366 std::shared_ptr<RNodeBase> *upcastNodeOnHeap, bool isSingleColumn);
0367
0368 std::string JitBuildAction(const ColumnNames_t &bl, std::shared_ptr<RDFDetail::RNodeBase> *prevNode,
0369 const std::type_info &art, const std::type_info &at, void *rOnHeap, TTree *tree,
0370 const unsigned int nSlots, const RColumnRegister &colRegister, RDataSource *ds,
0371 std::weak_ptr<RJittedAction> *jittedActionOnHeap, const bool vector2RVec = true);
0372
0373
0374
0375
0376
0377
0378
0379 template <typename T>
0380 std::weak_ptr<T> *MakeWeakOnHeap(const std::shared_ptr<T> &shPtr)
0381 {
0382 return new std::weak_ptr<T>(shPtr);
0383 }
0384
0385
0386 template <typename T>
0387 std::shared_ptr<T> *MakeSharedOnHeap(const std::shared_ptr<T> &shPtr)
0388 {
0389 return new std::shared_ptr<T>(shPtr);
0390 }
0391
0392 bool AtLeastOneEmptyString(const std::vector<std::string_view> strings);
0393
0394
0395
0396 std::shared_ptr<RNodeBase> UpcastNode(std::shared_ptr<RNodeBase> ptr);
0397
0398 ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns,
0399 const RColumnRegister &validDefines, RDataSource *ds);
0400
0401 std::vector<std::string> GetValidatedArgTypes(const ColumnNames_t &colNames, const RColumnRegister &colRegister,
0402 TTree *tree, RDataSource *ds, const std::string &context,
0403 bool vector2RVec);
0404
0405 std::vector<bool> FindUndefinedDSColumns(const ColumnNames_t &requestedCols, const ColumnNames_t &definedDSCols);
0406
0407 template <typename T>
0408 void AddDSColumnsHelper(const std::string &colName, RLoopManager &lm, RDataSource &ds, RColumnRegister &colRegister)
0409 {
0410
0411 if (colRegister.IsDefineOrAlias(colName))
0412 return;
0413
0414 if (lm.HasDataSourceColumnReaders(colName, typeid(T)))
0415 return;
0416
0417 if (!ds.HasColumn(colName) &&
0418 lm.GetSuppressErrorsForMissingBranches().find(colName) == lm.GetSuppressErrorsForMissingBranches().end())
0419 return;
0420
0421 const auto nSlots = lm.GetNSlots();
0422 std::vector<std::unique_ptr<RColumnReaderBase>> colReaders;
0423 colReaders.reserve(nSlots);
0424
0425 const auto valuePtrs = ds.GetColumnReaders<T>(colName);
0426 if (!valuePtrs.empty()) {
0427 for (auto *ptr : valuePtrs)
0428 colReaders.emplace_back(new RDSColumnReader<T>(ptr));
0429
0430 } else {
0431
0432 for (auto slot = 0u; slot < lm.GetNSlots(); ++slot)
0433 colReaders.emplace_back(
0434 ROOT::Internal::RDF::CreateColumnReader(ds, slot, colName, typeid(T), nullptr));
0435 }
0436
0437 lm.AddDataSourceColumnReaders(colName, std::move(colReaders), typeid(T));
0438 }
0439
0440
0441
0442 template <typename... ColumnTypes>
0443 void AddDSColumns(const std::vector<std::string> &requiredCols, RLoopManager &lm, RDataSource &ds,
0444 TTraits::TypeList<ColumnTypes...>, RColumnRegister &colRegister)
0445 {
0446
0447 using expander = int[];
0448 int i = 0;
0449 (void)expander{(AddDSColumnsHelper<ColumnTypes>(requiredCols[i], lm, ds, colRegister), ++i)..., 0};
0450 }
0451
0452
0453 template <typename F, typename PrevNode>
0454 void JitFilterHelper(F &&f, const char **colsPtr, std::size_t colsSize, std::string_view name,
0455 std::weak_ptr<RJittedFilter> *wkJittedFilter, std::shared_ptr<PrevNode> *prevNodeOnHeap,
0456 RColumnRegister *colRegister) noexcept
0457 {
0458 if (wkJittedFilter->expired()) {
0459
0460
0461 delete wkJittedFilter;
0462 delete colRegister;
0463 delete prevNodeOnHeap;
0464 return;
0465 }
0466
0467 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0468 delete[] colsPtr;
0469
0470 const auto jittedFilter = wkJittedFilter->lock();
0471
0472
0473 using Callable_t = std::decay_t<F>;
0474 using F_t = RFilter<Callable_t, PrevNode>;
0475 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0476 constexpr auto nColumns = ColTypes_t::list_size;
0477 CheckFilter(f);
0478
0479 auto &lm = *jittedFilter->GetLoopManagerUnchecked();
0480 auto ds = lm.GetDataSource();
0481
0482 if (ds != nullptr)
0483 AddDSColumns(cols, lm, *ds, ColTypes_t(), *colRegister);
0484
0485 jittedFilter->SetFilter(
0486 std::unique_ptr<RFilterBase>(new F_t(std::forward<F>(f), cols, *prevNodeOnHeap, *colRegister, name)));
0487
0488
0489 delete colRegister;
0490 delete prevNodeOnHeap;
0491 delete wkJittedFilter;
0492 }
0493
0494 namespace DefineTypes {
0495 struct RDefineTag {};
0496 struct RDefinePerSampleTag {};
0497 }
0498
0499 template <typename F>
0500 auto MakeDefineNode(DefineTypes::RDefineTag, std::string_view name, std::string_view dummyType, F &&f,
0501 const ColumnNames_t &cols, RColumnRegister &colRegister, RLoopManager &lm)
0502 {
0503 return std::unique_ptr<RDefineBase>(new RDefine<std::decay_t<F>, ExtraArgsForDefine::None>(
0504 name, dummyType, std::forward<F>(f), cols, colRegister, lm));
0505 }
0506
0507 template <typename F>
0508 auto MakeDefineNode(DefineTypes::RDefinePerSampleTag, std::string_view name, std::string_view dummyType, F &&f,
0509 const ColumnNames_t &, RColumnRegister &, RLoopManager &lm)
0510 {
0511 return std::unique_ptr<RDefineBase>(
0512 new RDefinePerSample<std::decay_t<F>>(name, dummyType, std::forward<F>(f), lm));
0513 }
0514
0515
0516
0517
0518 template <typename RDefineTypeTag, typename F>
0519 void JitDefineHelper(F &&f, const char **colsPtr, std::size_t colsSize, std::string_view name, RLoopManager *lm,
0520 std::weak_ptr<RJittedDefine> *wkJittedDefine, RColumnRegister *colRegister,
0521 std::shared_ptr<RNodeBase> *prevNodeOnHeap) noexcept
0522 {
0523
0524 auto doDeletes = [&] {
0525 delete wkJittedDefine;
0526 delete colRegister;
0527 delete prevNodeOnHeap;
0528 delete[] colsPtr;
0529 };
0530
0531 if (wkJittedDefine->expired()) {
0532
0533
0534 doDeletes();
0535 return;
0536 }
0537
0538 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0539
0540 auto jittedDefine = wkJittedDefine->lock();
0541
0542 using Callable_t = std::decay_t<F>;
0543 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0544
0545 auto ds = lm->GetDataSource();
0546 if (ds != nullptr && colsPtr)
0547 AddDSColumns(cols, *lm, *ds, ColTypes_t(), *colRegister);
0548
0549
0550
0551 const auto dummyType = "jittedCol_t";
0552
0553 std::unique_ptr<RDefineBase> newCol{
0554 MakeDefineNode(RDefineTypeTag{}, name, dummyType, std::forward<F>(f), cols, *colRegister, *lm)};
0555 jittedDefine->SetDefine(std::move(newCol));
0556
0557 doDeletes();
0558 }
0559
0560 template <bool IsSingleColumn, typename F>
0561 void JitVariationHelper(F &&f, const char **colsPtr, std::size_t colsSize, const char **variedCols,
0562 std::size_t variedColsSize, const char **variationTags, std::size_t variationTagsSize,
0563 std::string_view variationName, RLoopManager *lm,
0564 std::weak_ptr<RJittedVariation> *wkJittedVariation, RColumnRegister *colRegister,
0565 std::shared_ptr<RNodeBase> *prevNodeOnHeap) noexcept
0566 {
0567
0568 auto doDeletes = [&] {
0569 delete[] colsPtr;
0570 delete[] variedCols;
0571 delete[] variationTags;
0572
0573 delete wkJittedVariation;
0574 delete colRegister;
0575 delete prevNodeOnHeap;
0576 };
0577
0578 if (wkJittedVariation->expired()) {
0579
0580
0581 doDeletes();
0582 return;
0583 }
0584
0585 const ColumnNames_t inputColNames(colsPtr, colsPtr + colsSize);
0586 std::vector<std::string> variedColNames(variedCols, variedCols + variedColsSize);
0587 std::vector<std::string> tags(variationTags, variationTags + variationTagsSize);
0588
0589 auto jittedVariation = wkJittedVariation->lock();
0590
0591 using Callable_t = std::decay_t<F>;
0592 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0593
0594 auto ds = lm->GetDataSource();
0595 if (ds != nullptr)
0596 AddDSColumns(inputColNames, *lm, *ds, ColTypes_t(), *colRegister);
0597
0598
0599 std::unique_ptr<RVariationBase> newVariation{new RVariation<std::decay_t<F>, IsSingleColumn>(
0600 std::move(variedColNames), variationName, std::forward<F>(f), std::move(tags), jittedVariation->GetTypeName(),
0601 *colRegister, *lm, inputColNames)};
0602 jittedVariation->SetVariation(std::move(newVariation));
0603
0604 doDeletes();
0605 }
0606
0607
0608 template <typename ActionTag, typename... ColTypes, typename PrevNodeType, typename HelperArgType>
0609 void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap, const char **colsPtr, std::size_t colsSize,
0610 const unsigned int nSlots, std::shared_ptr<HelperArgType> *helperArgOnHeap,
0611 std::weak_ptr<RJittedAction> *wkJittedActionOnHeap, RColumnRegister *colRegister) noexcept
0612 {
0613
0614 auto doDeletes = [&] {
0615 delete[] colsPtr;
0616 delete helperArgOnHeap;
0617 delete wkJittedActionOnHeap;
0618
0619
0620 delete colRegister;
0621 delete prevNodeOnHeap;
0622 };
0623
0624 if (wkJittedActionOnHeap->expired()) {
0625
0626
0627 doDeletes();
0628 return;
0629 }
0630
0631 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0632
0633 auto jittedActionOnHeap = wkJittedActionOnHeap->lock();
0634
0635
0636 auto &prevNodePtr = *prevNodeOnHeap;
0637 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
0638 using ColTypes_t = TypeList<ColTypes...>;
0639 constexpr auto nColumns = ColTypes_t::list_size;
0640 auto ds = loopManager.GetDataSource();
0641 if (ds != nullptr)
0642 AddDSColumns(cols, loopManager, *ds, ColTypes_t(), *colRegister);
0643
0644 auto actionPtr = BuildAction<ColTypes...>(cols, std::move(*helperArgOnHeap), nSlots, std::move(prevNodePtr),
0645 ActionTag{}, *colRegister);
0646 jittedActionOnHeap->SetAction(std::move(actionPtr));
0647
0648 doDeletes();
0649 }
0650
0651
0652 template <typename T, bool Container = IsDataContainer<T>::value && !std::is_same<T, std::string>::value>
0653 struct RMinReturnType {
0654 using type = T;
0655 };
0656
0657 template <>
0658 struct RMinReturnType<RInferredType, false> {
0659 using type = double;
0660 };
0661
0662 template <typename T>
0663 struct RMinReturnType<T, true> {
0664 using type = TTraits::TakeFirstParameter_t<T>;
0665 };
0666
0667
0668 template <typename R, typename F, typename... Args>
0669 std::function<R(unsigned int, Args...)> AddSlotParameter(F &f, TypeList<Args...>)
0670 {
0671 return [f](unsigned int, Args... a) mutable -> R { return f(a...); };
0672 }
0673
0674 template <typename ColType, typename... Rest>
0675 struct RNeedJittingHelper {
0676 static constexpr bool value = RNeedJittingHelper<Rest...>::value;
0677 };
0678
0679 template <typename... Rest>
0680 struct RNeedJittingHelper<RInferredType, Rest...> {
0681 static constexpr bool value = true;
0682 };
0683
0684 template <typename T>
0685 struct RNeedJittingHelper<T> {
0686 static constexpr bool value = false;
0687 };
0688
0689 template <>
0690 struct RNeedJittingHelper<RInferredType> {
0691 static constexpr bool value = true;
0692 };
0693
0694 template <typename ...ColTypes>
0695 struct RNeedJitting {
0696 static constexpr bool value = RNeedJittingHelper<ColTypes...>::value;
0697 };
0698
0699 template <>
0700 struct RNeedJitting<> {
0701 static constexpr bool value = false;
0702 };
0703
0704
0705
0706
0707
0708 template <typename R, typename Merge, typename U, typename T, typename decayedU = std::decay_t<U>,
0709 typename mergeArgsNoDecay_t = typename CallableTraits<Merge>::arg_types_nodecay,
0710 typename mergeArgs_t = typename CallableTraits<Merge>::arg_types,
0711 typename mergeRet_t = typename CallableTraits<Merge>::ret_type>
0712 void CheckAggregate(TypeList<U, T>)
0713 {
0714 constexpr bool isAggregatorOk =
0715 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
0716 static_assert(isAggregatorOk, "aggregator function must have signature `U(U,T)` or `void(U&,T)`");
0717 constexpr bool isMergeOk =
0718 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
0719 (std::is_same<TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
0720 std::is_same<void, mergeRet_t>::value);
0721 static_assert(isMergeOk, "merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
0722 }
0723
0724
0725
0726 template <typename R, typename T>
0727 void CheckAggregate(T)
0728 {
0729 static_assert(sizeof(T) == 0, "aggregator function must take exactly two arguments");
0730 }
0731
0732
0733
0734 void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames);
0735
0736
0737 const ColumnNames_t SelectColumns(unsigned int nArgs, const ColumnNames_t &bl, const ColumnNames_t &defBl);
0738
0739
0740 ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns,
0741 const RColumnRegister &definedCols, const ColumnNames_t &dataSourceColumns);
0742
0743
0744 std::vector<std::string> GetFilterNames(const std::shared_ptr<RLoopManager> &loopManager);
0745
0746
0747 template <typename NodeType>
0748 std::vector<std::string> GetFilterNames(const std::shared_ptr<NodeType> &node)
0749 {
0750 std::vector<std::string> filterNames;
0751 node->AddFilterName(filterNames);
0752 return filterNames;
0753 }
0754
0755 struct ParsedTreePath {
0756 std::string fTreeName;
0757 std::string fDirName;
0758 };
0759
0760 ParsedTreePath ParseTreePath(std::string_view fullTreeName);
0761
0762
0763 template <bool...>
0764 struct TBoolPack;
0765
0766 template <bool... bs>
0767 using IsTrueForAllImpl_t = typename std::is_same<TBoolPack<bs..., true>, TBoolPack<true, bs...>>;
0768
0769 template <bool... Conditions>
0770 struct TEvalAnd {
0771 static constexpr bool value = IsTrueForAllImpl_t<Conditions...>::value;
0772 };
0773
0774
0775
0776
0777 template <typename>
0778 struct IsList_t : std::false_type {};
0779
0780 template <typename T>
0781 struct IsList_t<std::list<T>> : std::true_type {};
0782
0783 template <typename>
0784 struct IsDeque_t : std::false_type {};
0785
0786 template <typename T>
0787 struct IsDeque_t<std::deque<T>> : std::true_type {};
0788
0789
0790 void CheckForDuplicateSnapshotColumns(const ColumnNames_t &cols);
0791
0792 template <typename T>
0793 struct InnerValueType {
0794 using type = T;
0795 };
0796
0797 template <typename Elem>
0798 struct InnerValueType<ROOT::VecOps::RVec<ROOT::VecOps::RVec<Elem>>> {
0799 using type = Elem;
0800 };
0801
0802 template <typename T>
0803 using InnerValueType_t = typename InnerValueType<T>::type;
0804
0805 std::pair<std::vector<std::string>, std::vector<std::string>>
0806 AddSizeBranches(const std::vector<std::string> &branches, ROOT::RDF::RDataSource *ds,
0807 std::vector<std::string> &&colsWithoutAliases, std::vector<std::string> &&colsWithAliases);
0808
0809 void RemoveDuplicates(ColumnNames_t &columnNames);
0810 void RemoveRNTupleSubFields(ColumnNames_t &columnNames);
0811
0812 }
0813 }
0814
0815 namespace Detail {
0816 namespace RDF {
0817
0818
0819 template <typename T>
0820 using MinReturnType_t = typename RDFInternal::RMinReturnType<T>::type;
0821
0822 template <typename T>
0823 using MaxReturnType_t = MinReturnType_t<T>;
0824
0825 template <typename T>
0826 using SumReturnType_t = MinReturnType_t<T>;
0827
0828 }
0829 }
0830 }
0831
0832
0833
0834 #endif