Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RActionCustomLoader.hxx
Go to the documentation of this file.
1// Author: Vincenzo Eduardo Padulano CERN 10/2026
2// Author: Silia Taider CERN 10/2026
3
4#ifndef ROOT_RActionCustomLoader
5#define ROOT_RActionCustomLoader
6
13
14#include <cstddef> // std::size_t
15#include <memory>
16#include <string>
17#include <vector>
18
19namespace ROOT::Internal::RDF {
20
21template <typename Helper, typename PrevNode>
22class R__CLING_PTRCHECK(off) RActionCustomLoader final : public RActionBase {
23
24 // Template needed to avoid dependency on ActionHelpers.hxx
25 Helper fHelper;
26
27 // If the PrevNode is a RJittedFilter, our collection of previous nodes will have to use the RFilterBase type:
28 // we'll have a RJittedFilter for the nominal case, but the others will be concrete filters.
29 using PrevNodeCommon_t = std::conditional_t<std::is_same_v<PrevNode, ROOT::Detail::RDF::RJittedFilter>,
31 /// Previous nodes in the computation graph. First element is nominal, others are varied.
32 std::vector<std::shared_ptr<PrevNodeCommon_t>> fPrevNodes;
33
34 /// Column readers per slot and per input column
35 std::vector<std::vector<RColumnReaderBase *>> fValues;
36
37 /// Value addresses of the current entry per slot, reused for every entry
38 std::vector<std::vector<void *>> fValueAddresses;
39
40 // Types of input columns
41 std::vector<const std::type_info *> fColTypeIDs;
42
43 ROOT::RDF::SampleCallback_t GetSampleCallback() final { return fHelper.GetSampleCallback(); }
44
45public:
46 RActionCustomLoader(Helper &&h, const std::vector<std::string> &columns,
47 const std::vector<const std::type_info *> &colTypeIDs, std::shared_ptr<PrevNode> pd,
48 const RColumnRegister &colRegister)
49 : RActionBase(pd->GetLoopManagerUnchecked(), columns, colRegister, pd->GetVariations()),
50 fHelper(std::move(h)),
51 fPrevNodes{std::static_pointer_cast<PrevNodeCommon_t>(pd)},
52 fValues(GetNSlots()),
53 fValueAddresses(GetNSlots()),
54 fColTypeIDs(colTypeIDs)
55 {
56 fLoopManager->Register(this);
57 }
58
63
64 ~RActionCustomLoader() final { fLoopManager->Deregister(this); }
65
66 /**
67 Retrieve a wrapper to the result of the action that knows how to merge
68 with others of the same type.
69 */
70 std::unique_ptr<ROOT::Detail::RDF::RMergeableValueBase> GetMergeableValue() const final
71 {
72 return fHelper.GetMergeableValue();
73 }
74
75 void Initialize() final { fHelper.Initialize(); }
76
77 void InitSlot(TTreeReader *r, unsigned int slot) final
78 {
79 fValues[slot] = GetUntypedColumnReaders(slot, r, RActionBase::GetColRegister(), *fLoopManager,
80 RActionBase::GetColumnNames(), fColTypeIDs);
81 fHelper.InitTask(r, slot);
82 }
83
84 void *GetValue(unsigned int slot, std::size_t readerIdx, Long64_t entry)
85 {
86 assert(slot < fValues.size());
87 assert(readerIdx < fValues[slot].size());
88 if (auto *val = fValues[slot][readerIdx]->template TryGet<void>(entry))
89 return val;
90
91 throw std::out_of_range{"RDataFrame: Action (" + fHelper.GetActionName() +
92 ") could not retrieve value for column '" + fColumnNames[readerIdx] + "' for entry " +
93 std::to_string(entry) +
94 ". You can use the DefaultValueFor operation to provide a default value, or "
95 "FilterAvailable/FilterMissing to discard/keep entries with missing values instead."};
96 }
97
98 void CallExec(unsigned int slot, Long64_t entry)
99 {
100 auto &untypedValues = fValueAddresses[slot];
101 auto nReaders = fValues[slot].size();
102 untypedValues.resize(nReaders);
103 for (decltype(nReaders) readerIdx{}; readerIdx < nReaders; readerIdx++)
104 untypedValues[readerIdx] = GetValue(slot, readerIdx, entry);
105
106 fHelper.Exec(slot, untypedValues);
107 }
108
109 void Run(unsigned int slot, Long64_t entry) final
110 {
111
112 if (fPrevNodes.front()->CheckFilters(slot, entry))
113 CallExec(slot, entry);
114 }
115
117 {
118 for (auto const &node : fPrevNodes)
119 node->IncrChildrenCount();
120 }
121
122 /// Clean-up operations to be performed at the end of a task.
123 void FinalizeSlot(unsigned int slot) final
124 {
125 fValues[slot].clear();
126 fHelper.CallFinalizeTask(slot);
127 }
128
129 /// Clean-up and finalize the action result (e.g. merging slot-local results).
130 /// It invokes the helper's Finalize method.
131 void Finalize() final
132 {
133 fHelper.Finalize();
134 SetHasRun();
135 }
136
137 std::shared_ptr<GraphDrawing::GraphNode>
138 GetGraph(std::unordered_map<void *, std::shared_ptr<GraphDrawing::GraphNode>> &visitedMap) final
139 {
140 // Action nodes do not need to go through CreateFilterNode: they are never common nodes between multiple branches
141 const auto nodeType = HasRun() ? GraphDrawing::ENodeType::kUsedAction : GraphDrawing::ENodeType::kAction;
142 auto thisNode = std::make_shared<GraphDrawing::GraphNode>(fHelper.GetActionName(), visitedMap.size(), nodeType);
143 visitedMap[(void *)this] = thisNode;
144
145 for (auto const &node : fPrevNodes) {
146 auto prevNode = node->GetGraph(visitedMap);
147 const auto &prevColumns = prevNode->GetDefinedColumns();
148 auto upmostNode = AddDefinesToGraph(thisNode, GetColRegister(), prevColumns, visitedMap);
149
150 thisNode->AddDefinedColumns(GetColRegister().GenerateColumnNames());
151 upmostNode->SetPrevNode(prevNode);
152 }
153 return thisNode;
154 }
155
156 /// Forwards to the action helpers; will throw since PartialUpdate not supported for most snapshot helpers.
157 void *PartialUpdate(unsigned int slot) final { return fHelper.CallPartialUpdate(slot); }
158
159 [[maybe_unused]] std::unique_ptr<RActionBase> MakeVariedAction(std::vector<void *> && /*results*/) final
160 {
161 throw std::runtime_error("not implemented.");
162 }
163
164 /**
165 * \brief Returns a new action with a cloned helper.
166 *
167 * \param[in] newResult The result to be filled by the new action (needed to clone the helper).
168 * \return A unique pointer to the new action.
169 */
170 std::unique_ptr<RActionBase> CloneAction(void *newResult) final
171 {
172 return std::make_unique<RActionCustomLoader>(fHelper.CallMakeNew(newResult), GetColumnNames(), fColTypeIDs,
173 std::static_pointer_cast<PrevNode>(fPrevNodes.front()),
174 GetColRegister());
175 }
176};
177
178} // namespace ROOT::Internal::RDF
179
180#endif // ROOT_RActionCustomLoader
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
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
RActionCustomLoader(Helper &&h, const std::vector< std::string > &columns, const std::vector< const std::type_info * > &colTypeIDs, std::shared_ptr< PrevNode > pd, const RColumnRegister &colRegister)
std::conditional_t< std::is_same_v< PrevNode, ROOT::Detail::RDF::RJittedFilter >, ROOT::Detail::RDF::RFilterBase, PrevNode > PrevNodeCommon_t
void Finalize() final
Clean-up and finalize the action result (e.g.
std::vector< std::vector< RColumnReaderBase * > > fValues
Column readers per slot and per input column.
std::vector< std::vector< void * > > fValueAddresses
Value addresses of the current entry per slot, reused for every entry.
std::vector< std::shared_ptr< PrevNodeCommon_t > > fPrevNodes
Previous nodes in the computation graph. First element is nominal, others are varied.
void * PartialUpdate(unsigned int slot) final
Forwards to the action helpers; will throw since PartialUpdate not supported for most snapshot helper...
void * GetValue(unsigned int slot, std::size_t readerIdx, Long64_t entry)
std::unique_ptr< RActionBase > MakeVariedAction(std::vector< void * > &&) final
RActionCustomLoader & operator=(const RActionCustomLoader &)=delete
RActionCustomLoader(RActionCustomLoader &&)=delete
void InitSlot(TTreeReader *r, unsigned int slot) final
void CallExec(unsigned int slot, Long64_t entry)
std::shared_ptr< GraphDrawing::GraphNode > GetGraph(std::unordered_map< void *, std::shared_ptr< GraphDrawing::GraphNode > > &visitedMap) final
ROOT::RDF::SampleCallback_t GetSampleCallback() final
void FinalizeSlot(unsigned int slot) final
Clean-up operations to be performed at the end of a task.
std::unique_ptr< RActionBase > CloneAction(void *newResult) final
Returns a new action with a cloned helper.
std::unique_ptr< ROOT::Detail::RDF::RMergeableValueBase > GetMergeableValue() const final
Retrieve a wrapper to the result of the action that knows how to merge with others of the same type.
void Run(unsigned int slot, Long64_t entry) final
RActionCustomLoader(const RActionCustomLoader &)=delete
std::vector< const std::type_info * > fColTypeIDs
RActionCustomLoader & operator=(RActionCustomLoader &&)=delete
A binder for user-defined columns, variations and aliases.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
unsigned int GetNSlots()
Definition RDFUtils.cxx:423
std::vector< RDFDetail::RColumnReaderBase * > GetUntypedColumnReaders(unsigned int slot, TTreeReader *treeReader, ROOT::Internal::RDF::RColumnRegister &colRegister, ROOT::Detail::RDF::RLoopManager &lm, const std::vector< std::string > &colNames, const std::vector< const std::type_info * > &colTypeIDs, const std::string &variationName="nominal")
std::function< void(unsigned int, const ROOT::RDF::RSampleInfo &)> SampleCallback_t
The type of a data-block callback, registered with an RDataFrame computation graph via e....