aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java')
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java125
1 files changed, 85 insertions, 40 deletions
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
index 06cc8113..531969b4 100644
--- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
@@ -21,38 +21,52 @@ import java.util.stream.Collectors;
21public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { 21public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
22 private final Model model; 22 private final Model model;
23 private final ModelVisualizerStoreAdapter storeAdapter; 23 private final ModelVisualizerStoreAdapter storeAdapter;
24 private final Map<AnySymbol, Interpretation<?>> interpretations; 24 private final Map<AnySymbol, Interpretation<?>> allInterpretations;
25 private final StringBuilder designSpaceBuilder = new StringBuilder(); 25 private final StringBuilder designSpaceBuilder = new StringBuilder();
26 private final Map<Version, Integer> states = new HashMap<>(); 26 private final Map<Version, Integer> states = new HashMap<>();
27 private int transitionCounter = 0; 27 private int transitionCounter = 0;
28 private Integer numberOfStates = 0; 28 private Integer numberOfStates = 0;
29 private static final Map<Object, String> truthValueToDot = new HashMap<>() 29 private final String outputPath;
30 {{ 30 private final Set<FileFormat> formats;
31 put(TruthValue.TRUE, "1"); 31 private final boolean renderDesignSpace;
32 put(TruthValue.FALSE, "0"); 32 private final boolean renderStates;
33 put(TruthValue.UNKNOWN, "½"); 33
34 put(TruthValue.ERROR, "E"); 34 private static final Map<Object, String> truthValueToDot = Map.of(
35 put(true, "1"); 35 TruthValue.TRUE, "1",
36 put(false, "0"); 36 TruthValue.FALSE, "0",
37 }}; 37 TruthValue.UNKNOWN, "½",
38 TruthValue.ERROR, "E",
39 true, "1",
40 false, "0"
41 );
38 42
39 public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { 43 public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) {
40 this.model = model; 44 this.model = model;
41 this.storeAdapter = storeAdapter; 45 this.storeAdapter = storeAdapter;
42 this.interpretations = new HashMap<>(); 46 this.outputPath = storeAdapter.getOutputPath();
47 this.formats = storeAdapter.getFormats();
48 if (formats.isEmpty()) {
49 formats.add(FileFormat.SVG);
50 }
51 this.renderDesignSpace = storeAdapter.isRenderDesignSpace();
52 this.renderStates = storeAdapter.isRenderStates();
53
54 this.allInterpretations = new HashMap<>();
43 for (var symbol : storeAdapter.getStore().getSymbols()) { 55 for (var symbol : storeAdapter.getStore().getSymbols()) {
44 var arity = symbol.arity(); 56 var arity = symbol.arity();
45 if (arity < 1 || arity > 2) { 57 if (arity < 1 || arity > 2) {
46 continue; 58 continue;
47 } 59 }
48 var interpretation = (Interpretation<?>) model.getInterpretation(symbol); 60 var interpretation = (Interpretation<?>) model.getInterpretation(symbol);
49 interpretations.put(symbol, interpretation); 61 allInterpretations.put(symbol, interpretation);
50 } 62 }
51 designSpaceBuilder.append("digraph designSpace {\n"); 63 designSpaceBuilder.append("digraph designSpace {\n");
52 designSpaceBuilder.append(""" 64 designSpaceBuilder.append("""
65 nodesep=0
66 ranksep=5
53 node[ 67 node[
54 style=filled 68 \tstyle=filled
55 fillcolor=white 69 \tfillcolor=white
56 ] 70 ]
57 """); 71 """);
58 } 72 }
@@ -67,8 +81,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
67 return storeAdapter; 81 return storeAdapter;
68 } 82 }
69 83
70 @Override 84 private String createDotForCurrentModelState() {
71 public String createDotForCurrentModelState() {
72 85
73 var unaryTupleToInterpretationsMap = new HashMap<Tuple, LinkedHashSet<Interpretation<?>>>(); 86 var unaryTupleToInterpretationsMap = new HashMap<Tuple, LinkedHashSet<Interpretation<?>>>();
74 87
@@ -90,7 +103,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
90 ] 103 ]
91 """); 104 """);
92 105
93 for (var entry : interpretations.entrySet()) { 106 for (var entry : allInterpretations.entrySet()) {
94 var key = entry.getKey(); 107 var key = entry.getKey();
95 var arity = key.arity(); 108 var arity = key.arity();
96 var cursor = entry.getValue().getAll(); 109 var cursor = entry.getValue().getAll();
@@ -228,8 +241,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
228 }; 241 };
229 } 242 }
230 243
231 @Override 244 private String createDotForModelState(Version version) {
232 public String createDotForModelState(Version version) {
233 var currentVersion = model.getState(); 245 var currentVersion = model.getState();
234 model.restore(version); 246 model.restore(version);
235 var graph = createDotForCurrentModelState(); 247 var graph = createDotForCurrentModelState();
@@ -237,8 +249,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
237 return graph; 249 return graph;
238 } 250 }
239 251
240 @Override 252 private boolean saveDot(String dot, String filePath) {
241 public boolean saveDot(String dot, String filePath) {
242 File file = new File(filePath); 253 File file = new File(filePath);
243 file.getParentFile().mkdirs(); 254 file.getParentFile().mkdirs();
244 255
@@ -251,13 +262,11 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
251 return true; 262 return true;
252 } 263 }
253 264
254 @Override 265 private boolean renderDot(String dot, String filePath) {
255 public boolean renderDot(String dot, String filePath) {
256 return renderDot(dot, FileFormat.SVG, filePath); 266 return renderDot(dot, FileFormat.SVG, filePath);
257 } 267 }
258 268
259 @Override 269 private boolean renderDot(String dot, FileFormat format, String filePath) {
260 public boolean renderDot(String dot, FileFormat format, String filePath) {
261 try { 270 try {
262 Process process = new ProcessBuilder("dot", "-T" + format.getFormat(), "-o", filePath).start(); 271 Process process = new ProcessBuilder("dot", "-T" + format.getFormat(), "-o", filePath).start();
263 272
@@ -303,6 +312,26 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
303 } 312 }
304 313
305 @Override 314 @Override
315 public void addState(Version state, Collection<Double> fitness) {
316 var labelBuilder = new StringBuilder();
317 for (var f : fitness) {
318 labelBuilder.append(f).append(", ");
319 }
320 addState(state, labelBuilder.toString());
321 }
322
323 @Override
324 public void addState(Version state, String label) {
325 if (states.containsKey(state)) {
326 return;
327 }
328 states.put(state, numberOfStates++);
329 designSpaceBuilder.append(states.get(state)).append(" [label = \"").append(states.get(state)).append(" (");
330 designSpaceBuilder.append(label);
331 designSpaceBuilder.append(")\"\n").append("URL=\"./").append(states.get(state)).append(".svg\"]\n");
332 }
333
334 @Override
306 public void addSolution(Version state) { 335 public void addSolution(Version state) {
307 addState(state); 336 addState(state);
308 designSpaceBuilder.append(states.get(state)).append(" [shape = doublecircle]\n"); 337 designSpaceBuilder.append(states.get(state)).append(" [shape = doublecircle]\n");
@@ -313,8 +342,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
313 return designSpaceBuilder.toString(); 342 return designSpaceBuilder.toString();
314 } 343 }
315 344
316 @Override 345 private boolean saveDesignSpace(String path) {
317 public boolean saveDesignSpace(String path) {
318 saveDot(buildDesignSpaceDot(), path + "/designSpace.dot"); 346 saveDot(buildDesignSpaceDot(), path + "/designSpace.dot");
319 for (var entry : states.entrySet()) { 347 for (var entry : states.entrySet()) {
320 saveDot(createDotForModelState(entry.getKey()), path + "/" + entry.getValue() + ".dot"); 348 saveDot(createDotForModelState(entry.getKey()), path + "/" + entry.getValue() + ".dot");
@@ -322,21 +350,38 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
322 return true; 350 return true;
323 } 351 }
324 352
325 @Override 353 private void renderDesignSpace(String path, Set<FileFormat> formats) {
326 public boolean renderDesignSpace(String path) { 354 File filePath = new File(path);
327 return renderDesignSpace(path, FileFormat.SVG); 355 filePath.mkdirs();
356 if (renderStates) {
357 for (var entry : states.entrySet()) {
358 var stateId = entry.getValue();
359 var stateDot = createDotForModelState(entry.getKey());
360 for (var format : formats) {
361 if (format == FileFormat.DOT) {
362 saveDot(stateDot, path + "/" + stateId + ".dot");
363 }
364 else {
365 renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat());
366 }
367 }
368 }
369 }
370 if (renderDesignSpace) {
371 var designSpaceDot = buildDesignSpaceDot();
372 for (var format : formats) {
373 if (format == FileFormat.DOT) {
374 saveDot(designSpaceDot, path + "/designSpace.dot");
375 }
376 else {
377 renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat());
378 }
379 }
380 }
328 } 381 }
329 382
330 @Override 383 @Override
331 public boolean renderDesignSpace(String path, FileFormat format) { 384 public void visualize() {
332 for (var entry : states.entrySet()) { 385 renderDesignSpace(outputPath, formats);
333 var stateId = entry.getValue();
334 var stateDot = createDotForModelState(entry.getKey());
335 saveDot(stateDot, path + "/" + stateId + ".dot");
336 renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat());
337 }
338 var designSpaceDot = buildDesignSpaceDot();
339 saveDot(designSpaceDot, path + "/designSpace.dot");
340 return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat());
341 } 386 }
342} 387}