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