Warning, file /include/root/ROOT/RDF/RDefine.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_RDEFINE
0012 #define ROOT_RDF_RDEFINE
0013
0014 #include "ROOT/RDF/ColumnReaderUtils.hxx"
0015 #include "ROOT/RDF/RColumnReaderBase.hxx"
0016 #include "ROOT/RDF/RDefineBase.hxx"
0017 #include "ROOT/RDF/RLoopManager.hxx"
0018 #include "ROOT/RDF/Utils.hxx"
0019 #include <string_view>
0020 #include "ROOT/TypeTraits.hxx"
0021 #include "RtypesCore.h"
0022
0023 #include <array>
0024 #include <deque>
0025 #include <type_traits>
0026 #include <utility> // std::index_sequence
0027 #include <vector>
0028
0029 class TTreeReader;
0030
0031 namespace ROOT {
0032 namespace Detail {
0033 namespace RDF {
0034
0035 using namespace ROOT::TypeTraits;
0036
0037
0038 namespace ExtraArgsForDefine {
0039 struct None{};
0040 struct Slot{};
0041 struct SlotAndEntry{};
0042 }
0043
0044
0045 template <typename F, typename ExtraArgsTag = ExtraArgsForDefine::None>
0046 class R__CLING_PTRCHECK(off) RDefine final : public RDefineBase {
0047
0048 using NoneTag = ExtraArgsForDefine::None;
0049 using SlotTag = ExtraArgsForDefine::Slot;
0050 using SlotAndEntryTag = ExtraArgsForDefine::SlotAndEntry;
0051
0052 using FunParamTypes_t = typename CallableTraits<F>::arg_types;
0053 using ColumnTypesTmp_t =
0054 RDFInternal::RemoveFirstParameterIf_t<std::is_same<ExtraArgsTag, SlotTag>::value, FunParamTypes_t>;
0055 using ColumnTypes_t =
0056 RDFInternal::RemoveFirstTwoParametersIf_t<std::is_same<ExtraArgsTag, SlotAndEntryTag>::value, ColumnTypesTmp_t>;
0057 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
0058 using ret_type = typename CallableTraits<F>::ret_type;
0059
0060 using ValuesPerSlot_t =
0061 std::conditional_t<std::is_same<ret_type, bool>::value, std::deque<ret_type>, std::vector<ret_type>>;
0062
0063 F fExpression;
0064 ValuesPerSlot_t fLastResults;
0065
0066
0067 std::vector<std::array<RColumnReaderBase *, ColumnTypes_t::list_size>> fValues;
0068
0069
0070
0071 std::unordered_map<std::string, std::unique_ptr<RDefineBase>> fVariedDefines;
0072
0073 template <typename ColType>
0074 auto GetValueChecked(unsigned int slot, std::size_t readerIdx, Long64_t entry) -> ColType &
0075 {
0076 if (auto *val = fValues[slot][readerIdx]->template TryGet<ColType>(entry))
0077 return *val;
0078
0079 throw std::out_of_range{"RDataFrame: Define could not retrieve value for column '" + fColumnNames[readerIdx] +
0080 "' for entry " + std::to_string(entry) +
0081 ". You can use the DefaultValueFor operation to provide a default value, or "
0082 "FilterAvailable/FilterMissing to discard/keep entries with missing values instead."};
0083 }
0084
0085 template <typename... ColTypes, std::size_t... S>
0086 void UpdateHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>, NoneTag)
0087 {
0088 fLastResults[slot * RDFInternal::CacheLineStep<ret_type>()] =
0089 fExpression(GetValueChecked<ColTypes>(slot, S, entry)...);
0090 (void)entry;
0091 }
0092
0093 template <typename... ColTypes, std::size_t... S>
0094 void UpdateHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>, SlotTag)
0095 {
0096 fLastResults[slot * RDFInternal::CacheLineStep<ret_type>()] =
0097 fExpression(slot, GetValueChecked<ColTypes>(slot, S, entry)...);
0098 (void)entry;
0099 }
0100
0101 template <typename... ColTypes, std::size_t... S>
0102 void
0103 UpdateHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>, SlotAndEntryTag)
0104 {
0105 fLastResults[slot * RDFInternal::CacheLineStep<ret_type>()] =
0106 fExpression(slot, entry, GetValueChecked<ColTypes>(slot, S, entry)...);
0107 }
0108
0109 public:
0110 RDefine(std::string_view name, std::string_view type, F expression, const ROOT::RDF::ColumnNames_t &columns,
0111 const RDFInternal::RColumnRegister &colRegister, RLoopManager &lm,
0112 const std::string &variationName = "nominal")
0113 : RDefineBase(name, type, colRegister, lm, columns, variationName), fExpression(std::move(expression)),
0114 fLastResults(lm.GetNSlots() * RDFInternal::CacheLineStep<ret_type>()), fValues(lm.GetNSlots())
0115 {
0116 fLoopManager->Register(this);
0117 }
0118
0119 RDefine(const RDefine &) = delete;
0120 RDefine &operator=(const RDefine &) = delete;
0121 ~RDefine() { fLoopManager->Deregister(this); }
0122
0123 void InitSlot(TTreeReader *r, unsigned int slot) final
0124 {
0125 RDFInternal::RColumnReadersInfo info{fColumnNames, fColRegister, fIsDefine.data(), *fLoopManager};
0126 fValues[slot] = RDFInternal::GetColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation);
0127 fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
0128 }
0129
0130
0131 void *GetValuePtr(unsigned int slot) final
0132 {
0133 return static_cast<void *>(&fLastResults[slot * RDFInternal::CacheLineStep<ret_type>()]);
0134 }
0135
0136
0137 void Update(unsigned int slot, Long64_t entry) final
0138 {
0139 if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
0140
0141 UpdateHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{}, ExtraArgsTag{});
0142 fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
0143 }
0144 }
0145
0146 void Update(unsigned int , const ROOT::RDF::RSampleInfo &) final {}
0147
0148 const std::type_info &GetTypeId() const final { return typeid(ret_type); }
0149
0150
0151 void FinalizeSlot(unsigned int slot) final
0152 {
0153 fValues[slot].fill(nullptr);
0154
0155 for (auto &e : fVariedDefines)
0156 e.second->FinalizeSlot(slot);
0157 }
0158
0159
0160 void MakeVariations(const std::vector<std::string> &variations) final
0161 {
0162 for (const auto &variation : variations) {
0163 if (std::find(fVariationDeps.begin(), fVariationDeps.end(), variation) == fVariationDeps.end()) {
0164
0165 continue;
0166 }
0167 if (fVariedDefines.find(variation) != fVariedDefines.end())
0168 continue;
0169
0170
0171
0172 auto variedDefine = std::unique_ptr<RDefineBase>(
0173 new RDefine(fName, fType, fExpression, fColumnNames, fColRegister, *fLoopManager, variation));
0174
0175 fVariedDefines[variation] = std::move(variedDefine);
0176 }
0177 }
0178
0179
0180 RDefineBase &GetVariedDefine(const std::string &variationName) final
0181 {
0182 auto it = fVariedDefines.find(variationName);
0183 if (it == fVariedDefines.end()) {
0184
0185
0186 assert(std::find(fVariationDeps.begin(), fVariationDeps.end(), variationName) == fVariationDeps.end());
0187 return *this;
0188 }
0189
0190 return *(it->second);
0191 }
0192 };
0193
0194 }
0195 }
0196 }
0197
0198 #endif