Logo ROOT  
Reference Guide
RResultMap.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, CERN 11/2021
2
3/*************************************************************************
4 * Copyright (C) 1995-2022, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDF_RRESULTMAP
12#define ROOT_RDF_RRESULTMAP
13
17#include "ROOT/RDF/Utils.hxx" // Union
18
19#include <memory>
20#include <stdexcept>
21#include <string>
22#include <unordered_map>
23#include <vector>
24
25namespace ROOT {
26
27namespace RDF {
28
29namespace Experimental {
30// fwd decl for MakeResultMap
31template <typename T>
32class RResultMap;
33} // namespace Experimental
34} // namespace RDF
35
36namespace Detail {
37namespace RDF {
38template <typename T>
39std::unique_ptr<RMergeableVariations<T>> GetMergeableValue(ROOT::RDF::Experimental::RResultMap<T> &rmap);
40} // namespace RDF
41} // namespace Detail
42
43namespace Internal {
44namespace RDF {
45template <typename T>
47MakeResultMap(std::shared_ptr<T> nominalResult, std::vector<std::shared_ptr<T>> &&variedResults,
48 std::vector<std::string> &&keys, RLoopManager &lm,
49 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
50 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction)
51{
52 return ROOT::RDF::Experimental::RResultMap<T>(std::move(nominalResult), std::move(variedResults), std::move(keys),
53 lm, std::move(nominalAction), std::move(variedAction));
54}
55} // namespace RDF
56} // namespace Internal
57
58namespace RDF {
59
60namespace Experimental {
61
62template <typename T>
64
65 std::vector<std::string> fKeys; // values are the keys available in fMap
66 std::unordered_map<std::string, std::shared_ptr<T>> fMap; // shared_ptrs are never null
68 std::shared_ptr<ROOT::Internal::RDF::RActionBase> fNominalAction; // never null
69 std::shared_ptr<ROOT::Internal::RDF::RActionBase> fVariedAction; // might be null if there are no variations
70
72 ROOT::Internal::RDF::MakeResultMap<T>(std::shared_ptr<T> nominalResult,
73 std::vector<std::shared_ptr<T>> &&variedResults,
74 std::vector<std::string> &&keys, ROOT::Detail::RDF::RLoopManager &lm,
75 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
76 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction);
77
78 friend std::unique_ptr<ROOT::Detail::RDF::RMergeableVariations<T>>
79 ROOT::Detail::RDF::GetMergeableValue<T>(RResultMap<T> &rmap);
80
81 // The preconditions are that results and keys have the same size, are ordered the same way, and keys are unique.
82 RResultMap(std::shared_ptr<T> &&nominalResult, std::vector<std::shared_ptr<T>> &&variedResults,
83 std::vector<std::string> &&keys, ROOT::Detail::RDF::RLoopManager &lm,
84 std::shared_ptr<ROOT::Internal::RDF::RActionBase> nominalAction,
85 std::shared_ptr<ROOT::Internal::RDF::RActionBase> variedAction)
86 : fKeys{ROOT::Internal::RDF::Union({"nominal"}, keys)}, fLoopManager(&lm),
87 fNominalAction(std::move(nominalAction)), fVariedAction(std::move(variedAction))
88 {
89 R__ASSERT(variedResults.size() == keys.size() && "Keys and values have different sizes!");
90 std::size_t i = 0u;
91 fMap.insert({"nominal", std::move(nominalResult)});
92 for (const auto &k : keys) {
93 auto it = fMap.insert({k, variedResults[i++]});
94 R__ASSERT(it.second &&
95 "Failed to insert an element in RResultMap, maybe a duplicated key? This should never happen.");
96 }
97 }
98
100 {
101 if ((fVariedAction != nullptr && !fVariedAction->HasRun()) || !fNominalAction->HasRun())
102 fLoopManager->Run();
103 }
104
105public:
106 using iterator = typename decltype(fMap)::iterator;
107 using const_iterator = typename decltype(fMap)::const_iterator;
108
109 // TODO: can we use a std::string_view here without having to create a temporary std::string anyway?
110 T &operator[](const std::string &key)
111 {
112 auto it = fMap.find(key);
113 if (it == fMap.end())
114 throw std::runtime_error("RResultMap: no result with key \"" + key + "\".");
115
116 RunEventLoopIfNeeded();
117 return *it->second;
118 }
119
120 /// Iterator to walk through key-value pairs of all variations for a given object.
121 /// Runs the event loop before returning if necessary.
123 {
124 RunEventLoopIfNeeded();
125 return fMap.begin();
126 }
127
129 {
130 RunEventLoopIfNeeded();
131 return fMap.cbegin();
132 }
133
135 {
136 RunEventLoopIfNeeded();
137 return fMap.end();
138 }
139
141 {
142 RunEventLoopIfNeeded();
143 return fMap.cend();
144 }
145
146 const std::vector<std::string> &GetKeys() const { return fKeys; }
147};
148
149} // namespace Experimental
150} // namespace RDF
151
152namespace Detail {
153namespace RDF {
154////////////////////////////////////////////////////////////////////////////////
155/// \brief Retrieve mergeable values after calling ROOT::RDF::VariationsFor .
156/// \param[in] rmap lvalue reference of an RResultMap object.
157/// \returns A container with the variation names and then variation values.
158///
159/// This function triggers the execution of the RDataFrame computation graph.
160/// Then retrieves an RMergeableVariations object created with the results held
161/// by the RResultMap input. The user obtains ownership of the mergeable, which
162/// in turn holds a copy variation names and variation results. The RResultMap
163/// is not destroyed in the process and will still retain (shared) ownership of
164/// the original results.
165///
166/// Example usage:
167/// ~~~{.cpp}
168/// auto df = ROOT::RDataFrame(10).Define("x", [] { return 1; });
169/// auto h = df.Vary("x", [](){return ROOT::RVecI{-1, 2};}, {}, 2).Histo1D<int>("x");
170/// auto hs = ROOT::RDF::Experimental::VariationsFor(h);
171/// std::unique_ptr<RMergeableVariations<T>> m = ROOT::Detail::RDF::GetMergeableValue(hs);
172/// ~~~
173template <typename T>
174std::unique_ptr<RMergeableVariations<T>> GetMergeableValue(ROOT::RDF::Experimental::RResultMap<T> &rmap)
175{
177
178 std::unique_ptr<RMergeableVariationsBase> mVariationsBase;
179 if (rmap.fVariedAction != nullptr) {
180 auto mValueBase = rmap.fVariedAction->GetMergeableValue();
181 mVariationsBase.reset(static_cast<RMergeableVariationsBase *>(mValueBase.release())); // downcast unique_ptr
182 } else {
183 mVariationsBase = std::unique_ptr<RMergeableVariationsBase>({}, {});
184 }
185 mVariationsBase->AddNominal(rmap.fNominalAction->GetMergeableValue());
186
187 return std::make_unique<RMergeableVariations<T>>(std::move(*mVariationsBase));
188}
189} // namespace RDF
190} // namespace Detail
191} // namespace ROOT
192
193#endif
#define R__ASSERT(e)
Definition: TError.h:118
The head node of a RDF computation graph.
A container for variation names and variation results.
typename decltype(fMap)::const_iterator const_iterator
Definition: RResultMap.hxx:107
T & operator[](const std::string &key)
Definition: RResultMap.hxx:110
ROOT::Detail::RDF::RLoopManager * fLoopManager
Definition: RResultMap.hxx:67
RResultMap(std::shared_ptr< T > &&nominalResult, std::vector< std::shared_ptr< T > > &&variedResults, std::vector< std::string > &&keys, ROOT::Detail::RDF::RLoopManager &lm, std::shared_ptr< ROOT::Internal::RDF::RActionBase > nominalAction, std::shared_ptr< ROOT::Internal::RDF::RActionBase > variedAction)
Definition: RResultMap.hxx:82
const std::vector< std::string > & GetKeys() const
Definition: RResultMap.hxx:146
typename decltype(fMap)::iterator iterator
Definition: RResultMap.hxx:106
std::shared_ptr< ROOT::Internal::RDF::RActionBase > fNominalAction
Definition: RResultMap.hxx:68
std::unordered_map< std::string, std::shared_ptr< T > > fMap
Definition: RResultMap.hxx:66
iterator begin()
Iterator to walk through key-value pairs of all variations for a given object.
Definition: RResultMap.hxx:122
std::vector< std::string > fKeys
Definition: RResultMap.hxx:65
std::shared_ptr< ROOT::Internal::RDF::RActionBase > fVariedAction
Definition: RResultMap.hxx:69
std::unique_ptr< RMergeableVariations< T > > GetMergeableValue(ROOT::RDF::Experimental::RResultMap< T > &rmap)
Retrieve mergeable values after calling ROOT::RDF::VariationsFor .
Definition: RResultMap.hxx:174
ROOT::RDF::Experimental::RResultMap< T > MakeResultMap(std::shared_ptr< T > nominalResult, std::vector< std::shared_ptr< T > > &&variedResults, std::vector< std::string > &&keys, RLoopManager &lm, std::shared_ptr< ROOT::Internal::RDF::RActionBase > nominalAction, std::shared_ptr< ROOT::Internal::RDF::RActionBase > variedAction)
Definition: RResultMap.hxx:47
std::vector< T > Union(const std::vector< T > &v1, const std::vector< T > &v2)
Return a vector with all elements of v1 and v2 and duplicates removed.
Definition: Utils.hxx:274
double T(double x)
Definition: ChebyshevPol.h:34
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.