Logo ROOT   6.16/01
Reference Guide
RDFGraphUtils.cxx
Go to the documentation of this file.
2
3namespace ROOT {
4namespace Internal {
5namespace RDF {
6namespace GraphDrawing {
7
8std::string GraphCreatorHelper::FromGraphLeafToDot(std::shared_ptr<GraphNode> leaf)
9{
10 // Only the mapping between node id and node label (i.e. name)
11 std::stringstream dotStringLabels;
12 // Representation of the relationships between nodes
13 std::stringstream dotStringGraph;
14
15 // Explore the graph bottom-up and store its dot representation.
16 while (leaf) {
17 dotStringLabels << "\t" << leaf->fCounter << " [label=\"" << leaf->fName << "\", style=\"filled\", fillcolor=\""
18 << leaf->fColor << "\", shape=\"" << leaf->fShape << "\"];\n";
19 if (leaf->fPrevNode) {
20 dotStringGraph << "\t" << leaf->fPrevNode->fCounter << " -> " << leaf->fCounter << ";\n";
21 }
22 leaf = leaf->fPrevNode;
23 }
24
25 return "digraph {\n" + dotStringLabels.str() + dotStringGraph.str() + "}";
26}
27
28std::string GraphCreatorHelper::FromGraphActionsToDot(std::vector<std::shared_ptr<GraphNode>> leaves)
29{
30 // Only the mapping between node id and node label (i.e. name)
31 std::stringstream dotStringLabels;
32 // Representation of the relationships between nodes
33 std::stringstream dotStringGraph;
34
35 for (auto leaf : leaves) {
36 while (leaf && !leaf->fIsExplored) {
37 dotStringLabels << "\t" << leaf->fCounter << " [label=\"" << leaf->fName
38 << "\", style=\"filled\", fillcolor=\"" << leaf->fColor << "\", shape=\"" << leaf->fShape
39 << "\"];\n";
40 if (leaf->fPrevNode) {
41 dotStringGraph << "\t" << leaf->fPrevNode->fCounter << " -> " << leaf->fCounter << ";\n";
42 }
43 // Multiple branches may share the same nodes. It is wrong to explore them more than once.
44 leaf->fIsExplored = true;
45 leaf = leaf->fPrevNode;
46 }
47 }
48 return "digraph {\n" + dotStringLabels.str() + dotStringGraph.str() + "}";
49}
50
51bool CheckIfDefaultOrDSColumn(const std::string &name,
52 const std::shared_ptr<ROOT::Detail::RDF::RCustomColumnBase> &column)
53{
54 return (ROOT::Internal::RDF::IsInternalColumn(name) || column->IsDataSourceColumn());
55}
56
58{
59 auto loopManager = rDataFrame.GetLoopManager();
60 // Jitting is triggered because nodes must not be empty at the time of the calling in order to draw the graph.
61 if (!loopManager->fToJit.empty())
62 loopManager->BuildJittedNodes();
63
64 return RepresentGraph(loopManager);
65}
66
68{
69
70 auto actions = loopManager->GetAllActions();
71 std::vector<std::shared_ptr<GraphNode>> leaves;
72 for (auto action : actions) {
73 // Triggers the graph construction. When action->GetGraph() will return, the node will be linked to all the branch
74 leaves.push_back(action->GetGraph());
75 }
76
77 return FromGraphActionsToDot(leaves);
78}
79
80std::shared_ptr<GraphNode>
81CreateDefineNode(const std::string &columnName, const ROOT::Detail::RDF::RCustomColumnBase *columnPtr)
82{
83 // If there is already a node for this define (recognized by the custom column it is defining) return it. If there is
84 // not, return a new one.
85 auto &sColumnsMap = GraphCreatorHelper::GetStaticColumnsMap();
86 auto duplicateDefineIt = sColumnsMap.find(columnPtr);
87 if (duplicateDefineIt != sColumnsMap.end()) {
88 auto duplicateDefine = duplicateDefineIt->second.lock();
89 return duplicateDefine;
90 }
91
92 auto node = std::make_shared<GraphNode>("Define\n" + columnName);
93 node->SetDefine();
94
95 sColumnsMap[columnPtr] = node;
96 return node;
97}
98
99std::shared_ptr<GraphNode> CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
100{
101 // If there is already a node for this filter return it. If there is not, return a new one.
102 auto &sFiltersMap = GraphCreatorHelper::GetStaticFiltersMap();
103 auto duplicateFilterIt = sFiltersMap.find(filterPtr);
104 if (duplicateFilterIt != sFiltersMap.end()) {
105 auto duplicateFilter = duplicateFilterIt->second.lock();
106 duplicateFilter->SetIsNew(false);
107 return duplicateFilter;
108 }
109 auto filterName = (filterPtr->HasName() ? filterPtr->GetName() : "Filter");
110 auto node = std::make_shared<GraphNode>(filterName);
111
112 sFiltersMap[filterPtr] = node;
113 node->SetFilter();
114 return node;
115}
116
117std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
118{
119 // If there is already a node for this range return it. If there is not, return a new one.
120 auto &sRangesMap = GraphCreatorHelper::GetStaticRangesMap();
121 auto duplicateRangeIt = sRangesMap.find(rangePtr);
122 if (duplicateRangeIt != sRangesMap.end()) {
123 auto duplicateRange = duplicateRangeIt->second.lock();
124 duplicateRange->SetIsNew(false);
125 return duplicateRange;
126 }
127 auto node = std::make_shared<GraphNode>("Range");
128 node->SetRange();
129
130 sRangesMap[rangePtr] = node;
131 return node;
132}
133} // namespace GraphDrawing
134} // namespace RDF
135} // namespace Internal
136} // namespace ROOT
std::string GetName() const
Definition: RFilterBase.cxx:30
The head node of a RDF computation graph.
std::vector< RDFInternal::RActionBase * > GetAllActions()
For all the actions, either booked or run.
void BuildJittedNodes()
Jit all actions that required runtime column type inference, and clean the fToJit member variable.
static ColumnsNodesMap_t & GetStaticColumnsMap()
Stores the columns defined and which node in the graph defined them.
Definition: GraphUtils.hxx:67
static FiltersNodesMap_t & GetStaticFiltersMap()
Stores the filters defined and which node in the graph defined them.
Definition: GraphUtils.hxx:75
std::string FromGraphLeafToDot(std::shared_ptr< GraphNode > leaf)
Starting from any leaf (Action, Filter, Range) it draws the dot representation of the branch.
std::string FromGraphActionsToDot(std::vector< std::shared_ptr< GraphNode > > leaves)
Starting by an array of leaves, it draws the entire graph.
std::string RepresentGraph(ROOT::RDataFrame &rDataFrame)
Starting from the root node, prints the entire graph.
static RangesNodesMap_t & GetStaticRangesMap()
Stores the ranges defined and which node in the graph defined them.
Definition: GraphUtils.hxx:83
RLoopManager * GetLoopManager() const
ROOT's RDataFrame offers a high level interface for analyses of data stored in TTrees,...
Definition: RDataFrame.hxx:41
bool CheckIfDefaultOrDSColumn(const std::string &name, const std::shared_ptr< ROOT::Detail::RDF::RCustomColumnBase > &column)
std::shared_ptr< GraphNode > CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
std::shared_ptr< GraphNode > CreateDefineNode(const std::string &columnName, const ROOT::Detail::RDF::RCustomColumnBase *columnPtr)
std::shared_ptr< GraphNode > CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
bool IsInternalColumn(std::string_view colName)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21