Belle II Software development
DataFlowVisualization Class Reference

class to visualize data flow between modules. More...

#include <DataFlowVisualization.h>

Public Member Functions

 DataFlowVisualization (const DependencyMap *dependencyMap)
 Constructor.
 
void visualizePath (const std::string &filename, const Path &path)
 Create graphs with datastore inputs/outputs of each module in path.
 

Static Public Member Functions

static void executeModuleAndCreateIOPlot (const std::string &module)
 Create independent I/O graph for a single module (without requiring a steering file).
 

Private Member Functions

void generateModulePlot (std::ofstream &file, const Module &mod, bool steeringFileFlow=false)
 Create I/O graph for a single module (written to file).
 
bool checkArrayUnknown (const std::string &name, const DependencyMap::ModuleInfo &info)
 If the given array name isn't found in any of info's fields, it is added to m_unknownArrays (and true returned).
 

Static Private Member Functions

static void plotPath (std::ofstream &file, const Path &path, const std::string &pathName="")
 Create a subgraph for the given Path (including conditional paths).
 

Private Attributes

const DependencyMapm_map
 Stores information on inputs/outputs of each module, as obtained by require()/createEntry();.
 
std::set< std::string > m_allInputs
 set of all inputs (including optionals), for steering file visualisation.
 
std::set< std::string > m_allOutputs
 set of all outputs, for steering file visualisation.
 
std::set< std::string > m_unknownArrays
 set of array only being used in relations, for steering file visualisation.
 
std::string m_fillcolor [DependencyMap::c_NEntryTypes]
 fill colors.
 
std::string m_arrowcolor [DependencyMap::c_NEntryTypes]
 arrow colors.
 

Detailed Description

class to visualize data flow between modules.

Definition at line 24 of file DataFlowVisualization.h.

Constructor & Destructor Documentation

◆ DataFlowVisualization()

DataFlowVisualization ( const DependencyMap dependencyMap)
explicit

Constructor.

Definition at line 26 of file DataFlowVisualization.cc.

26 :
27 m_map(dependencyMap)
28{
29 m_fillcolor[DependencyMap::c_Input] = "cornflowerblue";
32
33 m_arrowcolor[DependencyMap::c_Input] = "cornflowerblue";
36}
std::string m_arrowcolor[DependencyMap::c_NEntryTypes]
arrow colors.
std::string m_fillcolor[DependencyMap::c_NEntryTypes]
fill colors.
const DependencyMap * m_map
Stores information on inputs/outputs of each module, as obtained by require()/createEntry();.
@ c_Input
required input.
Definition: DependencyMap.h:33
@ c_Output
registered output.
Definition: DependencyMap.h:35
@ c_OptionalInput
optional input.
Definition: DependencyMap.h:34

Member Function Documentation

◆ checkArrayUnknown()

bool checkArrayUnknown ( const std::string &  name,
const DependencyMap::ModuleInfo info 
)
private

If the given array name isn't found in any of info's fields, it is added to m_unknownArrays (and true returned).

Definition at line 189 of file DataFlowVisualization.cc.

190{
191 for (const auto& entry : info.entries) {
192 if (entry.count(name) != 0)
193 return false; //found
194 }
195
196 //not found
197 m_unknownArrays.insert(name);
198 return true;
199}
std::set< std::string > m_unknownArrays
set of array only being used in relations, for steering file visualisation.

◆ executeModuleAndCreateIOPlot()

void executeModuleAndCreateIOPlot ( const std::string &  module)
static

Create independent I/O graph for a single module (without requiring a steering file).

Output will be saved to ModuleName.dot.

Definition at line 165 of file DataFlowVisualization.cc.

166{
167 // construct given module and gearbox
168 std::shared_ptr<Module> modulePtr = ModuleManager::Instance().registerModule(module);
169 std::shared_ptr<Module> gearboxPtr = ModuleManager::Instance().registerModule("Gearbox");
170
171 // call initialize() method
172 //may throw some ERRORs, but that's OK.
173 // TODO:(ignore missing inputs)
174 gearboxPtr->initialize();
176 modulePtr->initialize();
177
178 // create plot
179 const std::string filename = module + ".dot";
180 DataFlowVisualization v(&DataStore::Instance().getDependencyMap());
181 std::ofstream file(filename.c_str());
182 v.generateModulePlot(file, *modulePtr, false);
183
184 //clean up to avoid problems with ~TROOT
185 modulePtr->terminate();
186 gearboxPtr->terminate();
187}
class to visualize data flow between modules.
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
DependencyMap & getDependencyMap()
Return map of depedencies between modules.
Definition: DataStore.h:524
void setModule(const Module &mod)
Set the current module (for getCurrentModuleInfo())
Definition: DependencyMap.h:60
std::shared_ptr< Module > registerModule(const std::string &moduleName, std::string sharedLibPath="") noexcept(false)
Creates an instance of a module and registers it to the ModuleManager.
static ModuleManager & Instance()
Exception is thrown if the requested module could not be created by the ModuleManager.

◆ generateModulePlot()

void generateModulePlot ( std::ofstream &  file,
const Module mod,
bool  steeringFileFlow = false 
)
private

Create I/O graph for a single module (written to file).

Definition at line 106 of file DataFlowVisualization.cc.

107{
108 const std::string& name = DependencyMap::getModuleID(mod);
109 const std::string& label = mod.getName();
110 if (!steeringFileFlow)
111 file << "digraph \"" << name << "\" {\n";
112 file << " " << name << " [label=\"" << label << "\"];\n";
113
114 const auto foundInfoIter = m_map->getModuleInfoMap().find(name);
115 if (foundInfoIter != m_map->getModuleInfoMap().end()) {
116 const DependencyMap::ModuleInfo& moduleInfo = foundInfoIter->second;
117 for (int i = 0; i < DependencyMap::c_NEntryTypes; i++) {
118 const std::set<std::string>& entries = moduleInfo.entries[i];
119 const std::set<std::string>& relations = moduleInfo.relations[i];
120 const std::string fillcolor = m_fillcolor[i];
121 const std::string arrowcolor = m_arrowcolor[i];
122
123 for (const std::string& dsentry : entries) {
124 if (!steeringFileFlow)
125 file << " \"" << dsentry << "\" [shape=box,style=filled,fillcolor=" << fillcolor << "];\n";
126 if (i == DependencyMap::c_Output) {
127 m_allOutputs.insert(dsentry);
128 file << " \"" << name << "\" -> \"" << dsentry << "\" [color=" << arrowcolor << "];\n";
129 } else {
130 m_allInputs.insert(dsentry);
131 file << " \"" << dsentry << "\" -> \"" << name << "\" [color=" << arrowcolor << "];\n";
132 }
133 }
134
135 for (const std::string& relname : relations) {
136 size_t pos = relname.rfind("To");
137 if (pos == std::string::npos or pos != relname.find("To")) {
138 B2WARNING("generateModulePlot(): couldn't split relation name!");
139 //Searching for parts in input/output lists might be helpful...
140 continue;
141 }
142
143 const std::string from = relname.substr(0, pos);
144 const std::string to = relname.substr(pos + 2);
145
146 //any connected arrays that are neither input nor output?
147 if (checkArrayUnknown(from, moduleInfo)) {
148 if (!steeringFileFlow)
149 file << " \"" << from << "\" [shape=box,style=filled,fillcolor=" << unknownfillcolor << "];\n";
150 }
151 if (checkArrayUnknown(to, moduleInfo)) {
152 if (!steeringFileFlow)
153 file << " \"" << to << "\" [shape=box,style=filled,fillcolor=" << unknownfillcolor << "];\n";
154 }
155
156 file << " \"" << from << "\" -> \"" << to << "\" [color=" << arrowcolor << ",style=dashed];\n";
157 }
158 }
159 }
160 if (!steeringFileFlow)
161 file << "}\n\n";
162}
std::set< std::string > m_allInputs
set of all inputs (including optionals), for steering file visualisation.
bool checkArrayUnknown(const std::string &name, const DependencyMap::ModuleInfo &info)
If the given array name isn't found in any of info's fields, it is added to m_unknownArrays (and true...
std::set< std::string > m_allOutputs
set of all outputs, for steering file visualisation.
@ c_NEntryTypes
size of this enum.
Definition: DependencyMap.h:37
const std::map< std::string, ModuleInfo > & getModuleInfoMap() const
return information on inputs/outputs of each module, as obtained by requireInput()/optionalInput()/re...
Definition: DependencyMap.h:66
static std::string getModuleID(const Module &mod)
Return unique ID for given module.
Stores information on inputs/outputs of a module, as obtained by requireInput()/optionalInput()/regis...
Definition: DependencyMap.h:41
std::set< std::string > entries[c_NEntryTypes]
objects/arrays.
Definition: DependencyMap.h:42
std::set< std::string > relations[c_NEntryTypes]
relations between them.
Definition: DependencyMap.h:43

◆ plotPath()

void plotPath ( std::ofstream &  file,
const Path path,
const std::string &  pathName = "" 
)
staticprivate

Create a subgraph for the given Path (including conditional paths).

Definition at line 71 of file DataFlowVisualization.cc.

72{
73 //graph name must begin with cluster for fancy graphics!
74 const std::string graphname = pathName.empty() ? "clusterMain" : ("cluster" + pathName);
75 file << " subgraph \"" << graphname << "\" {\n";
76 if (pathName.empty()) {
77 file << " rank=min;\n";
78 } else {
79 file << " rank=same;\n";
80 }
81 file << " style=solid;\n";
82 file << " color=grey;\n";
83 file << " \"" << graphname << "_inv\" [shape=point,style=invis];\n";
84 std::string lastModule("");
85 //connect modules in right order...
86 for (const ModulePtr& mod : path.getModules()) {
87 const std::string& module = DependencyMap::getModuleID(*mod);
88 file << " \"" << module << "\";\n";
89 if (!lastModule.empty()) {
90 file << " \"" << lastModule << "\" -> \"" << module << "\" [color=black];\n";
91 }
92 if (mod->hasCondition()) {
93 for (const auto& condition : mod->getAllConditions()) {
94 const std::string& conditionName = condition.getString();
95 plotPath(file, *condition.getPath(), conditionName);
96 file << " \"" << module << "\" -> \"cluster" << conditionName << "_inv\" " <<
97 "[color=grey,lhead=\"cluster" << conditionName << "\",label=\"" << conditionName << "\",fontcolor=grey];\n";
98 }
99 }
100
101 lastModule = module;
102 }
103 file << " }\n";
104}
static void plotPath(std::ofstream &file, const Path &path, const std::string &pathName="")
Create a subgraph for the given Path (including conditional paths).
std::shared_ptr< Module > ModulePtr
Defines a pointer to a module object as a boost shared pointer.
Definition: Module.h:43

◆ visualizePath()

void visualizePath ( const std::string &  filename,
const Path path 
)

Create graphs with datastore inputs/outputs of each module in path.

Parameters
filenamefile saved to (in DOT format).
pathPath to visualize.

Definition at line 38 of file DataFlowVisualization.cc.

39{
40 std::ofstream file(filename.c_str());
41 file << "digraph allModules {\n";
42 file << " rankdir=LR;\n"; //left -> right
43 file << " compound=true;\n"; //allow edges to subgraphs
44
45 //for steering file data flow graph, we may get multiple definitions of each node
46 //graphviz merges these into the last one, so we'll go through module list in reverse (all boxes should be coloured as outputs)
47 const bool steeringFileFlow = true;
48 for (const ModulePtr& mod : path.buildModulePathList())
49 generateModulePlot(file, *mod, steeringFileFlow);
50
51 plotPath(file, path);
52
53 //add nodes
54 for (const std::string& name : m_allOutputs) {
55 file << " \"" << name << "\" [shape=box,style=filled,fillcolor=" << m_fillcolor[DependencyMap::c_Output] << "];\n";
56 }
57 for (const std::string& name : m_allInputs) {
58 if (m_allOutputs.count(name) == 0)
59 file << " \"" << name << "\" [shape=box,style=filled,fillcolor=" << m_fillcolor[DependencyMap::c_Input] << "];\n";
60 }
61 for (const std::string& name : m_unknownArrays) {
62 if (m_allOutputs.count(name) == 0 && m_allInputs.count(name) == 0)
63 file << " \"" << name << "\" [shape=box,style=filled,fillcolor=" << unknownfillcolor << "];\n";
64 }
65
66 file << "}\n\n";
67
68 B2INFO("Data flow diagram created. You can use 'dot dataflow.dot -Tps -o dataflow.ps' to create a PostScript file from it.");
69}
void generateModulePlot(std::ofstream &file, const Module &mod, bool steeringFileFlow=false)
Create I/O graph for a single module (written to file).

Member Data Documentation

◆ m_allInputs

std::set<std::string> m_allInputs
private

set of all inputs (including optionals), for steering file visualisation.

Definition at line 54 of file DataFlowVisualization.h.

◆ m_allOutputs

std::set<std::string> m_allOutputs
private

set of all outputs, for steering file visualisation.

Definition at line 55 of file DataFlowVisualization.h.

◆ m_arrowcolor

std::string m_arrowcolor[DependencyMap::c_NEntryTypes]
private

arrow colors.

Definition at line 59 of file DataFlowVisualization.h.

◆ m_fillcolor

std::string m_fillcolor[DependencyMap::c_NEntryTypes]
private

fill colors.

Definition at line 58 of file DataFlowVisualization.h.

◆ m_map

const DependencyMap* m_map
private

Stores information on inputs/outputs of each module, as obtained by require()/createEntry();.

Definition at line 52 of file DataFlowVisualization.h.

◆ m_unknownArrays

std::set<std::string> m_unknownArrays
private

set of array only being used in relations, for steering file visualisation.

Definition at line 56 of file DataFlowVisualization.h.


The documentation for this class was generated from the following files: