File indexing completed on 2025-01-18 10:10:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef ROOT_RDF_RRESULTMAP
0012 #define ROOT_RDF_RRESULTMAP
0013
0014 #include "ROOT/RDF/RActionBase.hxx"
0015 #include "ROOT/RDF/RLoopManager.hxx"
0016 #include "ROOT/RDF/RMergeableValue.hxx"
0017 #include "ROOT/RDF/Utils.hxx" // Union
0018
0019 #include <memory>
0020 #include <stdexcept>
0021 #include <string>
0022 #include <unordered_map>
0023 #include <vector>
0024
0025 namespace ROOT {
0026
0027 namespace RDF {
0028
0029 namespace Experimental {
0030
0031 template <typename T>
0032 class RResultMap;
0033 }
0034 }
0035
0036 namespace Detail {
0037 namespace RDF {
0038 template <typename T>
0039 std::unique_ptr<RMergeableVariations<T>> GetMergeableValue(ROOT::RDF::Experimental::RResultMap<T> &rmap);
0040 }
0041 }
0042
0043 namespace Internal {
0044 namespace RDF {
0045 template <typename T>
0046 ROOT::RDF::Experimental::RResultMap<T>
0047 MakeResultMap(std::shared_ptr<T> nominalResult, std::vector<std::shared_ptr<T>> &&variedResults,
0048 std::vector<std::string> &&keys, RLoopManager &lm,
0049 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
0050 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction)
0051 {
0052 return ROOT::RDF::Experimental::RResultMap<T>(std::move(nominalResult), std::move(variedResults), std::move(keys),
0053 lm, std::move(nominalAction), std::move(variedAction));
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <typename T>
0064 ROOT::RDF::Experimental::RResultMap<T> CloneResultAndAction(const ROOT::RDF::Experimental::RResultMap<T> &inmap)
0065 {
0066 std::shared_ptr<T> nominalResult{inmap.fMap.at("nominal")};
0067 auto nominalAction{inmap.fNominalAction->CloneAction(reinterpret_cast<void *>(&nominalResult))};
0068
0069 std::size_t nVariations{inmap.fMap.size() - 1};
0070 std::vector<std::shared_ptr<T>> variedResults;
0071 variedResults.reserve(nVariations);
0072 for (auto i = 0u; i < nVariations; ++i)
0073 variedResults.emplace_back(new T{*nominalResult});
0074
0075 std::vector<void *> typeErasedResults;
0076 typeErasedResults.reserve(nVariations);
0077 for (auto &res : variedResults)
0078 typeErasedResults.push_back(&res);
0079 auto variedAction{inmap.fVariedAction->CloneAction(reinterpret_cast<void *>(&typeErasedResults))};
0080
0081 std::vector<std::string> variationNames{inmap.fKeys};
0082 Erase<std::string>("nominal", variationNames);
0083
0084 return ROOT::RDF::Experimental::RResultMap<T>(std::move(nominalResult), std::move(variedResults),
0085 std::move(variationNames), *(inmap.fLoopManager),
0086 std::move(nominalAction), std::move(variedAction));
0087 }
0088 }
0089 }
0090
0091 namespace RDF {
0092
0093 class RResultHandle;
0094
0095 namespace Experimental {
0096
0097 template <typename T>
0098 class RResultMap {
0099
0100 std::vector<std::string> fKeys;
0101 std::unordered_map<std::string, std::shared_ptr<T>> fMap;
0102 ROOT::Detail::RDF::RLoopManager *fLoopManager;
0103 std::shared_ptr<ROOT::Internal::RDF::RActionBase> fNominalAction;
0104 std::shared_ptr<ROOT::Internal::RDF::RActionBase> fVariedAction;
0105
0106 friend RResultMap
0107 ROOT::Internal::RDF::MakeResultMap<T>(std::shared_ptr<T> nominalResult,
0108 std::vector<std::shared_ptr<T>> &&variedResults,
0109 std::vector<std::string> &&keys, ROOT::Detail::RDF::RLoopManager &lm,
0110 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
0111 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction);
0112
0113 friend RResultMap ROOT::Internal::RDF::CloneResultAndAction<T>(const RResultMap<T> &inmap);
0114 friend std::unique_ptr<ROOT::Detail::RDF::RMergeableVariations<T>>
0115 ROOT::Detail::RDF::GetMergeableValue<T>(RResultMap<T> &rmap);
0116 friend class ::ROOT::RDF::RResultHandle;
0117
0118
0119 RResultMap(std::shared_ptr<T> &&nominalResult, std::vector<std::shared_ptr<T>> &&variedResults,
0120 std::vector<std::string> &&keys, ROOT::Detail::RDF::RLoopManager &lm,
0121 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
0122 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction)
0123 : fKeys{ROOT::Internal::RDF::Union({std::string("nominal")}, keys)}, fLoopManager(&lm),
0124 fNominalAction(std::move(nominalAction)), fVariedAction(std::move(variedAction))
0125 {
0126 R__ASSERT(variedResults.size() == keys.size() && "Keys and values have different sizes!");
0127 std::size_t i = 0u;
0128 fMap.insert({"nominal", std::move(nominalResult)});
0129 for (const auto &k : keys) {
0130 auto it = fMap.insert({k, variedResults[i++]});
0131 R__ASSERT(it.second &&
0132 "Failed to insert an element in RResultMap, maybe a duplicated key? This should never happen.");
0133 }
0134 }
0135
0136 void RunEventLoopIfNeeded()
0137 {
0138 if ((fVariedAction != nullptr && !fVariedAction->HasRun()) || !fNominalAction->HasRun())
0139 fLoopManager->Run();
0140 }
0141
0142 public:
0143 using iterator = typename decltype(fMap)::iterator;
0144 using const_iterator = typename decltype(fMap)::const_iterator;
0145
0146
0147 T &operator[](const std::string &key)
0148 {
0149 auto it = fMap.find(key);
0150 if (it == fMap.end())
0151 throw std::runtime_error("RResultMap: no result with key \"" + key + "\".");
0152
0153 RunEventLoopIfNeeded();
0154 return *it->second;
0155 }
0156
0157
0158
0159 iterator begin()
0160 {
0161 RunEventLoopIfNeeded();
0162 return fMap.begin();
0163 }
0164
0165 const_iterator cbegin()
0166 {
0167 RunEventLoopIfNeeded();
0168 return fMap.cbegin();
0169 }
0170
0171 iterator end()
0172 {
0173 RunEventLoopIfNeeded();
0174 return fMap.end();
0175 }
0176
0177 const_iterator cend() const
0178 {
0179 RunEventLoopIfNeeded();
0180 return fMap.cend();
0181 }
0182
0183 const std::vector<std::string> &GetKeys() const { return fKeys; }
0184 };
0185
0186 }
0187 }
0188
0189 namespace Detail {
0190 namespace RDF {
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 template <typename T>
0211 std::unique_ptr<RMergeableVariations<T>> GetMergeableValue(ROOT::RDF::Experimental::RResultMap<T> &rmap)
0212 {
0213 rmap.RunEventLoopIfNeeded();
0214
0215 std::unique_ptr<RMergeableVariationsBase> mVariationsBase;
0216 if (rmap.fVariedAction != nullptr) {
0217 auto mValueBase = rmap.fVariedAction->GetMergeableValue();
0218 mVariationsBase.reset(static_cast<RMergeableVariationsBase *>(mValueBase.release()));
0219 } else {
0220 mVariationsBase = std::unique_ptr<RMergeableVariationsBase>({}, {});
0221 }
0222 mVariationsBase->AddNominal(rmap.fNominalAction->GetMergeableValue());
0223
0224 return std::make_unique<RMergeableVariations<T>>(std::move(*mVariationsBase));
0225 }
0226 }
0227 }
0228 }
0229
0230 #endif