Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
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 
51 bool 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 
57 std::string GraphCreatorHelper::RepresentGraph(ROOT::RDataFrame &rDataFrame)
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  loopManager->Jit();
62 
63  return RepresentGraph(loopManager);
64 }
65 
66 std::string GraphCreatorHelper::RepresentGraph(RLoopManager *loopManager)
67 {
68 
69  auto actions = loopManager->GetAllActions();
70  std::vector<std::shared_ptr<GraphNode>> leaves;
71  for (auto action : actions) {
72  // Triggers the graph construction. When action->GetGraph() will return, the node will be linked to all the branch
73  leaves.push_back(action->GetGraph());
74  }
75 
76  return FromGraphActionsToDot(leaves);
77 }
78 
79 std::shared_ptr<GraphNode>
80 CreateDefineNode(const std::string &columnName, const ROOT::Detail::RDF::RCustomColumnBase *columnPtr)
81 {
82  // If there is already a node for this define (recognized by the custom column it is defining) return it. If there is
83  // not, return a new one.
84  auto &sColumnsMap = GraphCreatorHelper::GetStaticColumnsMap();
85  auto duplicateDefineIt = sColumnsMap.find(columnPtr);
86  if (duplicateDefineIt != sColumnsMap.end()) {
87  auto duplicateDefine = duplicateDefineIt->second.lock();
88  return duplicateDefine;
89  }
90 
91  auto node = std::make_shared<GraphNode>("Define\n" + columnName);
92  node->SetDefine();
93 
94  sColumnsMap[columnPtr] = node;
95  return node;
96 }
97 
98 std::shared_ptr<GraphNode> CreateFilterNode(const ROOT::Detail::RDF::RFilterBase *filterPtr)
99 {
100  // If there is already a node for this filter return it. If there is not, return a new one.
101  auto &sFiltersMap = GraphCreatorHelper::GetStaticFiltersMap();
102  auto duplicateFilterIt = sFiltersMap.find(filterPtr);
103  if (duplicateFilterIt != sFiltersMap.end()) {
104  auto duplicateFilter = duplicateFilterIt->second.lock();
105  duplicateFilter->SetIsNew(false);
106  return duplicateFilter;
107  }
108  auto filterName = (filterPtr->HasName() ? filterPtr->GetName() : "Filter");
109  auto node = std::make_shared<GraphNode>(filterName);
110 
111  sFiltersMap[filterPtr] = node;
112  node->SetFilter();
113  return node;
114 }
115 
116 std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr)
117 {
118  // If there is already a node for this range return it. If there is not, return a new one.
119  auto &sRangesMap = GraphCreatorHelper::GetStaticRangesMap();
120  auto duplicateRangeIt = sRangesMap.find(rangePtr);
121  if (duplicateRangeIt != sRangesMap.end()) {
122  auto duplicateRange = duplicateRangeIt->second.lock();
123  duplicateRange->SetIsNew(false);
124  return duplicateRange;
125  }
126  auto node = std::make_shared<GraphNode>("Range");
127  node->SetRange();
128 
129  sRangesMap[rangePtr] = node;
130  return node;
131 }
132 } // namespace GraphDrawing
133 } // namespace RDF
134 } // namespace Internal
135 } // namespace ROOT