MATSIM
MatsimGrapher.java
Go to the documentation of this file.
1 package org.matsim.guice;
2 
3 import com.google.inject.Injector;
4 import com.google.inject.Key;
5 import com.google.inject.TypeLiteral;
6 import com.google.inject.grapher.AbstractInjectorGrapher;
7 import com.google.inject.grapher.BindingEdge;
8 import com.google.inject.grapher.DependencyEdge;
9 import com.google.inject.grapher.Edge;
10 import com.google.inject.grapher.ImplementationNode;
11 import com.google.inject.grapher.InstanceNode;
12 import com.google.inject.grapher.InterfaceNode;
13 import com.google.inject.grapher.Node;
14 import com.google.inject.grapher.NodeId;
15 import org.jgrapht.Graph;
16 import org.jgrapht.Graphs;
17 import org.jgrapht.alg.connectivity.ConnectivityInspector;
18 import org.jgrapht.graph.DefaultDirectedGraph;
19 import org.jgrapht.graph.MaskSubgraph;
21 import org.matsim.api.core.v01.Scenario;
26 import org.matsim.core.config.Config;
40 
41 import java.io.PrintWriter;
42 import java.io.Writer;
43 import java.util.HashMap;
44 import java.util.Map;
45 import java.util.Set;
46 
47 public class MatsimGrapher extends AbstractInjectorGrapher {
48 
49  private Graph<Node, Edge> g;
50  private final Map<NodeId, Node> nodes = new HashMap<>();
51  private Writer writer;
52 
53  public MatsimGrapher(GrapherParameters options, Writer writer) {
54  super(options);
55  this.writer = writer;
56  g = new DefaultDirectedGraph<>(Edge.class);
57  }
58 
59  @Override
60  protected void reset() {
61  g = new DefaultDirectedGraph<>(Edge.class);
62  nodes.clear();
63  }
64 
65  @Override
66  protected void newInterfaceNode(InterfaceNode node) {
67  g.addVertex(node);
68  nodes.put(node.getId(), node);
69  }
70 
71  @Override
72  protected void newImplementationNode(ImplementationNode node) {
73  g.addVertex(node);
74  nodes.put(node.getId(), node);
75  }
76 
77  @Override
78  protected void newInstanceNode(InstanceNode node) {
79  g.addVertex(node);
80  nodes.put(node.getId(), node);
81  }
82 
83  @Override
84  protected void newDependencyEdge(DependencyEdge edge) {
85  g.addEdge(nodes.get(edge.getFromId()), nodes.get(edge.getToId()), edge);
86  }
87 
88  @Override
89  protected void newBindingEdge(BindingEdge edge) {
90  g.addEdge(nodes.get(edge.getFromId()), nodes.get(edge.getToId()), edge);
91  }
92 
93  @Override
94  protected void postProcess() {
95  // More or less arbitrarily filter out graph nodes that I think are unhelpful clutter, like config
96  // groups, scenario elements, and things that aren't usually overridden.
97  Graph<Node, Edge> filteredGraph = filterGraph();
98 
99  Graph<Node, Edge> graphComponentReachableFromControler = findGraphComponentReachableFromControler(filteredGraph);
100 
101  // Render a dot file. Can be converted to a PDF with
102  // dot -Tpdf modules.dot > modules.pdf
103  GraphvizRenderer graphvizRenderer = new GraphvizRenderer();
104  graphvizRenderer.setRankdir("LR");
105  graphvizRenderer.setOut((PrintWriter) writer);
106  graphvizRenderer.render(graphComponentReachableFromControler);
107  }
108 
109  private Graph<Node, Edge> filterGraph() {
110  return new MaskSubgraph<>(g, node -> {
111  if (ConfigGroup.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
112  return true;
113  }
114  if (Network.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
115  return true;
116  }
117  if (Population.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
118  return true;
119  }
120  if (DumpDataAtEnd.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
121  return true;
122  }
123  if (OutputDirectoryHierarchy.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
124  return true;
125  }
126  if (MatsimServices.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
127  return true;
128  }
129  if (Injector.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
130  return true;
131  }
132  if (PopulationFactory.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
133  return true;
134  }
135  if (Scenario.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
136  return true;
137  }
138  if (Config.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
139  return true;
140  }
141  if (IterationStopWatch.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
142  return true;
143  }
144  if (EventsManager.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
145  return true;
146  }
147  if (ReplanningContext.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
148  return true;
149  }
150  if (PlansDumping.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
151  return true;
152  }
153  if (ActivityFacilities.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
154  return true;
155  }
156  if (EventsHandling.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
157  return true;
158  }
159  if (TravelTimeCalculator.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
160  return true;
161  }
162  if (SingleModeNetworksCache.class.isAssignableFrom(node.getId().getKey().getTypeLiteral().getRawType())) {
163  return true;
164  }
165  if (ExperiencedPlansService.class.equals(node.getId().getKey().getTypeLiteral().getRawType())) {
166  return true;
167  }
168  if (node.getId().getKey().getTypeLiteral().toString().contains("ExperiencedPlansServiceImpl")) {
169  return true;
170  }
171  if (node.getId().getKey().getTypeLiteral().toString().contains("ControlerListener")) {
172  return true;
173  }
174  if (node.getId().getKey().getTypeLiteral().toString().contains("EventsToActivities")) {
175  return true;
176  }
177  if (node.getId().getKey().getTypeLiteral().toString().contains("EventsToLegs")) {
178  return true;
179  }
180  if (node.getId().getKey().getTypeLiteral().toString().contains("LeastCostPathCalculatorFactory")) {
181  return true;
182  }
183  if (node.getId().getKey().getTypeLiteral().toString().contains("MainModeIdentifier")) {
184  return true;
185  }
186  if (node.getId().getKey().getTypeLiteral().toString().contains("TerminationCriterion")) {
187  return true;
188  }
189  if (node.getId().getKey().getTypeLiteral().equals(new TypeLiteral<Set<MobsimListener>>(){})) {
190  return true;
191  }
192  return false;
193  }, edge -> false);
194  }
195 
196  private Graph<Node, Edge> findGraphComponentReachableFromControler(Graph<Node, Edge> filteredGraph) {
197  Graph<Node, Edge> graphComponentReachableFromControler = new DefaultDirectedGraph<>(Edge.class);
198  ConnectivityInspector<Node, Edge> ci = new ConnectivityInspector<>(filteredGraph);
199  Node controlerNode = nodes.get(NodeId.newTypeId(Key.get(ControlerI.class)));
200  Graphs.addGraph(graphComponentReachableFromControler, new MaskSubgraph<>(g, node -> !ci.connectedSetOf(controlerNode).contains(node), edge -> false));
201  return graphComponentReachableFromControler;
202  }
203 }
void newDependencyEdge(DependencyEdge edge)
void newInterfaceNode(InterfaceNode node)
MatsimGrapher(GrapherParameters options, Writer writer)
void newInstanceNode(InstanceNode node)
void render(Graph< Node, Edge > graph)
void newImplementationNode(ImplementationNode node)
Graph< Node, Edge > filterGraph()
Graph< Node, Edge > findGraphComponentReachableFromControler(Graph< Node, Edge > filteredGraph)
void newBindingEdge(BindingEdge edge)
final Map< NodeId, Node > nodes