Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RDefaultValueFor.hxx
Go to the documentation of this file.
1// Author: Vincenzo Eduardo Padulano, CERN 09/2024
2
3/*************************************************************************
4 * Copyright (C) 1995-2024, 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_RDefaultValueFor
12#define ROOT_RDF_RDefaultValueFor
13
18#include "ROOT/RDF/Utils.hxx"
19#include <string_view>
20#include "ROOT/TypeTraits.hxx"
21#include "RtypesCore.h"
22
23#include <deque>
24#include <type_traits>
25#include <utility> // std::index_sequence
26#include <vector>
27
28class TTreeReader;
29
30namespace ROOT {
31namespace Detail {
32namespace RDF {
33
34using namespace ROOT::TypeTraits;
35
36/**
37 * \brief The implementation of the DefaultValueFor transformation.
38 *
39 * The class takes in the default value provided by the user to fill-in missing
40 * values of the input column. During the Update step, the class checks for the
41 * presence of the value of the column at the current event. If that value is
42 * missing, it will return the default value to requesting nodes of the graph.
43 */
44template <typename T>
45class R__CLING_PTRCHECK(off) RDefaultValueFor final : public RDefineBase {
47 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
48 // Avoid instantiating vector<bool> as `operator[]` returns temporaries in that case. Use std::deque instead.
49 using ValuesPerSlot_t = std::conditional_t<std::is_same<T, bool>::value, std::deque<T>, std::vector<T>>;
50
53 // One column reader per slot
54 std::vector<RColumnReaderBase *> fValues;
55
56 /// Define objects corresponding to systematic variations other than nominal for this defined column.
57 /// The map key is the full variation name, e.g. "pt:up".
58 std::unordered_map<std::string, std::unique_ptr<RDefineBase>> fVariedDefines;
59
60 T &GetValueOrDefault(unsigned int slot, Long64_t entry)
61 {
62 if (auto *value = fValues[slot]->template TryGet<T>(entry))
63 return *value;
64 else
65 return fDefaultValue;
66 };
67
68public:
69 RDefaultValueFor(std::string_view name, std::string_view type, const T &defaultValue,
70 const ROOT::RDF::ColumnNames_t &columns, const RDFInternal::RColumnRegister &colRegister,
71 RLoopManager &lm, const std::string &variationName = "nominal")
72 : RDefineBase(name, type, colRegister, lm, columns, variationName),
73 fDefaultValue(defaultValue),
74 fLastResults(lm.GetNSlots() * RDFInternal::CacheLineStep<T>()),
75 fValues(lm.GetNSlots())
76 {
77 fLoopManager->Register(this);
78 // We suppress errors that TTreeReader prints regarding the missing branch
79 fLoopManager->GetSuppressErrorsForMissingBranches().push_back(fColumnNames[0]);
80 }
81
87 {
88 fLoopManager->Deregister(this);
89 ROOT::Internal::RDF::Erase(fColumnNames[0], fLoopManager->GetSuppressErrorsForMissingBranches());
90 }
91
92 void InitSlot(TTreeReader *r, unsigned int slot) final
93 {
94 fValues[slot] = RDFInternal::GetColumnReader<T>(
95 slot, fColRegister.GetReader(slot, fColumnNames[0], fVariation, typeid(T)), *fLoopManager, r, fColumnNames[0]);
96 fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
97 }
98
99 /// Return the (type-erased) address of the Define'd value for the given processing slot.
100 void *GetValuePtr(unsigned int slot) final
101 {
102 return static_cast<void *>(&fLastResults[slot * RDFInternal::CacheLineStep<T>()]);
103 }
104
105 /// Update the value at the address returned by GetValuePtr with the content corresponding to the given entry
106 void Update(unsigned int slot, Long64_t entry) final
107 {
108 if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
109 // evaluate this define expression, cache the result
110 fLastResults[slot * RDFInternal::CacheLineStep<T>()] = GetValueOrDefault(slot, entry);
111 fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
112 }
113 }
114
115 void Update(unsigned int /*slot*/, const ROOT::RDF::RSampleInfo & /*id*/) final {}
116
117 const std::type_info &GetTypeId() const final { return typeid(T); }
118
119 /// Clean-up operations to be performed at the end of a task.
120 void FinalizeSlot(unsigned int slot) final
121 {
122 fValues[slot] = nullptr;
123
124 for (auto &e : fVariedDefines)
125 e.second->FinalizeSlot(slot);
126 }
127
128 /// Create clones of this Define that work with values in varied "universes".
129 void MakeVariations(const std::vector<std::string> &variations) final
130 {
131 for (const auto &variation : variations) {
132 if (std::find(fVariationDeps.begin(), fVariationDeps.end(), variation) == fVariationDeps.end()) {
133 // this Defined quantity does not depend on this variation, so no need to create a varied RDefine
134 continue;
135 }
136 if (fVariedDefines.find(variation) != fVariedDefines.end())
137 continue; // we already have this variation stored
138
139 // the varied defines get a copy of the callable object.
140 // TODO document this
141 auto variedDefine = std::unique_ptr<RDefineBase>(
142 new RDefaultValueFor(fName, fType, fDefaultValue, fColumnNames, fColRegister, *fLoopManager, variation));
143 fVariedDefines.insert({variation, std::move(variedDefine)});
144 }
145 }
146
147 /// Return a clone of this Define that works with values in the variationName "universe".
148 RDefineBase &GetVariedDefine(const std::string &variationName) final
149 {
150 auto it = fVariedDefines.find(variationName);
151 if (it == fVariedDefines.end()) {
152 // We don't have a varied RDefine for this variation.
153 // This means we don't depend on it and we can return ourselves, i.e. the RDefine for the nominal universe.
154 assert(std::find(fVariationDeps.begin(), fVariationDeps.end(), variationName) == fVariationDeps.end());
155 return *this;
156 }
157
158 return *(it->second);
159 }
160};
161
162} // namespace RDF
163} // namespace Detail
164} // namespace ROOT
165
166#endif // ROOT_RDF_RDefaultValueFor
#define e(i)
Definition RSha256.hxx:103
long long Long64_t
Definition RtypesCore.h:69
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
The implementation of the DefaultValueFor transformation.
void * GetValuePtr(unsigned int slot) final
Return the (type-erased) address of the Define'd value for the given processing slot.
std::unordered_map< std::string, std::unique_ptr< RDefineBase > > fVariedDefines
Define objects corresponding to systematic variations other than nominal for this defined column.
RDefaultValueFor(RDefaultValueFor &&)=delete
std::vector< RColumnReaderBase * > fValues
RDefineBase & GetVariedDefine(const std::string &variationName) final
Return a clone of this Define that works with values in the variationName "universe".
void InitSlot(TTreeReader *r, unsigned int slot) final
void FinalizeSlot(unsigned int slot) final
Clean-up operations to be performed at the end of a task.
std::conditional_t< std::is_same< T, bool >::value, std::deque< T >, std::vector< T > > ValuesPerSlot_t
std::make_index_sequence< ColumnTypes_t::list_size > TypeInd_t
RDefaultValueFor & operator=(const RDefaultValueFor &)=delete
const std::type_info & GetTypeId() const final
RDefaultValueFor(const RDefaultValueFor &)=delete
RDefaultValueFor & operator=(RDefaultValueFor &&)=delete
void Update(unsigned int, const ROOT::RDF::RSampleInfo &) final
Update function to be called once per sample, used if the derived type is a RDefinePerSample.
T & GetValueOrDefault(unsigned int slot, Long64_t entry)
RDefaultValueFor(std::string_view name, std::string_view type, const T &defaultValue, const ROOT::RDF::ColumnNames_t &columns, const RDFInternal::RColumnRegister &colRegister, RLoopManager &lm, const std::string &variationName="nominal")
void Update(unsigned int slot, Long64_t entry) final
Update the value at the address returned by GetValuePtr with the content corresponding to the given e...
void MakeVariations(const std::vector< std::string > &variations) final
Create clones of this Define that work with values in varied "universes".
The head node of a RDF computation graph.
A binder for user-defined columns, variations and aliases.
This type represents a sample identifier, to be used in conjunction with RDataFrame features such as ...
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
void Erase(const T &that, std::vector< T > &v)
Erase that element from vector v
Definition Utils.hxx:189
std::vector< std::string > ColumnNames_t
ROOT type_traits extensions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Lightweight storage for a collection of types.