Logo ROOT  
Reference Guide
RDFGraphUtils.cxx
Go to the documentation of this file.
2 
3 namespace ROOT {
4 namespace Internal {
5 namespace RDF {
6 namespace GraphDrawing {
7 
8 std::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 
28 std::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 
52 {
53  auto loopManager = rDataFrame.GetLoopManager();
54  // Jitting is triggered because nodes must not be empty at the time of the calling in order to draw the graph.
55  loopManager->Jit();
56 
57  return RepresentGraph(loopManager);
58 }
59 
61 {
62 
63  auto actions = loopManager->GetAllActions();
64  std::vector<std::shared_ptr<GraphNode>> leaves;
65  for (auto action : actions) {
66  // Triggers the graph construction. When action->GetGraph() will return, the node will be linked to all the branch
67  leaves.push_back(action->GetGraph());
68  }
69 
70  return FromGraphActionsToDot(leaves);
71 }
72 
73 std::shared_ptr<GraphNode>
74 CreateDefineNode(const std::string &columnName, const ROOT::Detail::RDF::RDefineBase *columnPtr)
75 {
76  // If there is already a node for this define (recognized by the custom column it is defining) return it. If there is
77  // not, return a new one.
78  auto &sColumnsMap = GraphCreatorHelper::GetStaticColumnsMap();
79  auto duplicateDefineIt = sColumnsMap.find(columnPtr);
80  if (duplicateDefineIt != sColumnsMap.end()) {
81  auto duplicateDefine = duplicateDefineIt->second.lock();
82  return duplicateDefine;
83  }
84 
85  auto node = std::make_shared<GraphNode>("Define\n" + columnName);
86  node->SetDefine();
87 
88  sColumnsMap[columnPtr] = node;
89  return node;
90 }
91 
92 std::shared_ptr<GraphNode> CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
93 {
94  // If there is already a node for this filter return it. If there is not, return a new one.
95  auto &sFiltersMap = GraphCreatorHelper::GetStaticFiltersMap();
96  auto duplicateFilterIt = sFiltersMap.find(filterPtr);
97  if (duplicateFilterIt != sFiltersMap.end()) {
98  auto duplicateFilter = duplicateFilterIt->second.lock();
99  duplicateFilter->SetIsNew(false);
100  return duplicateFilter;
101  }
102  auto filterName = (filterPtr->HasName() ? filterPtr->GetName() : "Filter");
103  auto node = std::make_shared<GraphNode>(filterName);
104 
105  sFiltersMap[filterPtr] = node;
106  node->SetFilter();
107  return node;
108 }
109 
110 std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
111 {
112  // If there is already a node for this range return it. If there is not, return a new one.
113  auto &sRangesMap = GraphCreatorHelper::GetStaticRangesMap();
114  auto duplicateRangeIt = sRangesMap.find(rangePtr);
115  if (duplicateRangeIt != sRangesMap.end()) {
116  auto duplicateRange = duplicateRangeIt->second.lock();
117  duplicateRange->SetIsNew(false);
118  return duplicateRange;
119  }
120  auto node = std::make_shared<GraphNode>("Range");
121  node->SetRange();
122 
123  sRangesMap[rangePtr] = node;
124  return node;
125 }
126 } // namespace GraphDrawing
127 } // namespace RDF
128 } // namespace Internal
129 } // namespace ROOT
ROOT::Detail::RDF::RFilterBase
Definition: RFilterBase.hxx:36
ROOT::Internal::RDF::GraphDrawing::CreateDefineNode
std::shared_ptr< GraphNode > CreateDefineNode(const std::string &columnName, const ROOT::Detail::RDF::RDefineBase *columnPtr)
Definition: RDFGraphUtils.cxx:74
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::FromGraphLeafToDot
std::string FromGraphLeafToDot(std::shared_ptr< GraphNode > leaf)
Starting from any leaf (Action, Filter, Range) it draws the dot representation of the branch.
Definition: RDFGraphUtils.cxx:8
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::GetStaticFiltersMap
static FiltersNodesMap_t & GetStaticFiltersMap()
Stores the filters defined and which node in the graph defined them.
Definition: GraphUtils.hxx:72
ROOT::Detail::RDF::RRangeBase
Definition: RRangeBase.hxx:32
ROOT::Detail::RDF::RFilterBase::GetName
std::string GetName() const
Definition: RFilterBase.cxx:30
ROOT::RDataFrame
ROOT's RDataFrame offers a high level interface for analyses of data stored in TTrees,...
Definition: RDataFrame.hxx:42
ROOT::Detail::RDF::RDefineBase
Definition: RDefineBase.hxx:34
ROOT::Detail::RDF::RFilterBase::HasName
bool HasName() const
Definition: RFilterBase.cxx:25
ROOT::Detail::RDF::RLoopManager::GetAllActions
std::vector< RDFInternal::RActionBase * > GetAllActions()
For all the actions, either booked or run.
Definition: RLoopManager.cxx:667
ROOT::Internal::RDF::GraphDrawing::CreateFilterNode
std::shared_ptr< GraphNode > CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
Definition: RDFGraphUtils.cxx:92
GraphUtils.hxx
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::GetStaticRangesMap
static RangesNodesMap_t & GetStaticRangesMap()
Stores the ranges defined and which node in the graph defined them.
Definition: GraphUtils.hxx:80
ROOT::Internal::RDF::GraphDrawing::CreateRangeNode
std::shared_ptr< GraphNode > CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
Definition: RDFGraphUtils.cxx:110
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::GetStaticColumnsMap
static DefinesNodesMap_t & GetStaticColumnsMap()
Stores the columns defined and which node in the graph defined them.
Definition: GraphUtils.hxx:64
ROOT::Detail::RDF::RLoopManager::Jit
void Jit()
Add RDF nodes that require just-in-time compilation to the computation graph.
Definition: RLoopManager.cxx:534
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::FromGraphActionsToDot
std::string FromGraphActionsToDot(std::vector< std::shared_ptr< GraphNode >> leaves)
Starting by an array of leaves, it draws the entire graph.
Definition: RDFGraphUtils.cxx:28
ROOT::RDF::RInterface::GetLoopManager
RLoopManager * GetLoopManager() const
Definition: RInterface.hxx:2424
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Detail::RDF::RLoopManager
The head node of a RDF computation graph.
Definition: RLoopManager.hxx:57
ROOT::Internal::RDF::GraphDrawing::GraphCreatorHelper::RepresentGraph
std::string RepresentGraph(ROOT::RDataFrame &rDataFrame)
Starting from the root node, prints the entire graph.
Definition: RDFGraphUtils.cxx:51