json works now
This commit is contained in:
parent
3961ee0030
commit
de370416ac
@ -1,3 +1,6 @@
|
||||
// Put the real domain here
|
||||
var baseUrl = "http://localhost"
|
||||
|
||||
var network;
|
||||
var simulationData;
|
||||
animationPlaying = false;
|
||||
@ -8,6 +11,34 @@ const stepSlider = document.querySelector('#stepRange');
|
||||
const stepField = document.querySelector('#stepField');
|
||||
const animationDurationSlider = document.querySelector('#animationDurationRange');
|
||||
const animationDurationField = document.querySelector('#animationDurationField');
|
||||
|
||||
var selectedGraph;
|
||||
var horizon;
|
||||
var states;
|
||||
var initial_distribution;
|
||||
var rules;
|
||||
var colors;
|
||||
|
||||
// Debuging
|
||||
//selectedGraph = "strict graph GraphHello {\n0 -- 1;\n1 -- 2;\n1 -- 3;\n}";
|
||||
//selectedGraph = "strict graph Default {\n0 -- 1;\n1 -- 2;\n2 -- 3;\n3 -- 4;\n4 -- 5;\n0 -- 5;\n0 -- 3;\n0 -- 4;\n0 -- 2;\n1 -- 4;\n1 -- 5;\n1 -- 6;\n3 -- 5;\n3 -- 6;\n3 -- 4;\n}"
|
||||
|
||||
selectedGraph = "strict graph Default {\n0 -- 10;\n0 -- 1;\n1 -- 11;\n1 -- 2;\n2 -- 12;\n2 -- 3;\n3 -- 13;\n3 -- 4;\n4 -- 14;\n4 -- 5;\n5 -- 15;\n5 -- 6;\n6 -- 16;\n6 -- 7;\n7 -- 17;\n7 -- 8;\n8 -- 18;\n8 -- 9;\n9 -- 19;\n10 -- 20;\n10 -- 11;\n11 -- 21;\n11 -- 12;\n12 -- 22;\n12 -- 13;\n13 -- 23;\n13 -- 14;\n14 -- 24;\n14 -- 15;\n15 -- 25;\n15 -- 16;\n16 -- 26;\n16 -- 17;\n17 -- 27;\n17 -- 18;\n18 -- 28;\n18 -- 19;\n19 -- 29;\n20 -- 30;\n20 -- 21;\n21 -- 31;\n21 -- 22;\n22 -- 32;\n22 -- 23;\n23 -- 33;\n23 -- 24;\n24 -- 34;\n24 -- 25;\n25 -- 35;\n25 -- 26;\n26 -- 36;\n26 -- 27;\n27 -- 37;\n27 -- 28;\n28 -- 38;\n28 -- 29;\n29 -- 39;\n30 -- 40;\n30 -- 31;\n31 -- 41;\n31 -- 32;\n32 -- 42;\n32 -- 33;\n33 -- 43;\n33 -- 34;\n34 -- 44;\n34 -- 35;\n35 -- 45;\n35 -- 36;\n36 -- 46;\n36 -- 37;\n37 -- 47;\n37 -- 38;\n38 -- 48;\n38 -- 39;\n39 -- 49;\n40 -- 50;\n40 -- 41;\n41 -- 51;\n41 -- 42;\n42 -- 52;\n42 -- 43;\n43 -- 53;\n43 -- 44;\n44 -- 54;\n44 -- 45;\n45 -- 55;\n45 -- 46;\n46 -- 56;\n46 -- 47;\n47 -- 57;\n47 -- 48;\n48 -- 58;\n48 -- 49;\n49 -- 59;\n50 -- 60;\n50 -- 51;\n51 -- 61;\n51 -- 52;\n52 -- 62;\n52 -- 53;\n53 -- 63;\n53 -- 54;\n54 -- 64;\n54 -- 55;\n55 -- 65;\n55 -- 56;\n56 -- 66;\n56 -- 57;\n57 -- 67;\n57 -- 58;\n58 -- 68;\n58 -- 59;\n59 -- 69;\n60 -- 70;\n60 -- 61;\n61 -- 71;\n61 -- 62;\n62 -- 72;\n62 -- 63;\n63 -- 73;\n63 -- 64;\n64 -- 74;\n64 -- 65;\n65 -- 75;\n65 -- 66;\n66 -- 76;\n66 -- 67;\n67 -- 77;\n67 -- 68;\n68 -- 78;\n68 -- 69;\n69 -- 79;\n70 -- 80;\n70 -- 71;\n71 -- 81;\n71 -- 72;\n72 -- 82;\n72 -- 73;\n73 -- 83;\n73 -- 74;\n74 -- 84;\n74 -- 75;\n75 -- 85;\n75 -- 76;\n76 -- 86;\n76 -- 77;\n77 -- 87;\n77 -- 78;\n78 -- 88;\n78 -- 79;\n79 -- 89;\n80 -- 90;\n80 -- 81;\n81 -- 91;\n81 -- 82;\n82 -- 92;\n82 -- 83;\n83 -- 93;\n83 -- 84;\n84 -- 94;\n84 -- 85;\n85 -- 95;\n85 -- 86;\n86 -- 96;\n86 -- 87;\n87 -- 97;\n87 -- 88;\n88 -- 98;\n88 -- 89;\n89 -- 99;\n90 -- 91;\n91 -- 92;\n92 -- 93;\n93 -- 94;\n94 -- 95;\n95 -- 96;\n96 -- 97;\n97 -- 98;\n98 -- 99;}"
|
||||
|
||||
horizon = 20.0;
|
||||
//states = ["S", "I", "R"];
|
||||
states = ["N", "I", "V"];
|
||||
//initial_distribution = [0.5, 0.5, 0];
|
||||
initial_distribution = [0.9, 0.1, 0];
|
||||
//rules = "I R 1.0 R S 0.7 I S I I I I 0.8";
|
||||
rules = "N V 0.1 I N I I 0.5 I I N I I I 0.9 I N 0.2";
|
||||
// S I R
|
||||
colors = {
|
||||
"N" : "#000000",
|
||||
"I" : "#ffffff",
|
||||
"V" : "#75c44c"
|
||||
}
|
||||
|
||||
function createGraphFromDot(dotString){
|
||||
var parsedData = vis.parseDOTNetwork(dotString);
|
||||
// create a network
|
||||
@ -62,32 +93,37 @@ function createGraphFromDot(dotString){
|
||||
function visualizeOneStep(step){
|
||||
for(i = 0; i < step.length; i++){
|
||||
n = network.body.nodes[i];
|
||||
//console.log(step[i])
|
||||
if(step[i][0] == 0){
|
||||
n.setOptions({
|
||||
color:{
|
||||
background: "#0000ff",
|
||||
background: colors[step[i]]
|
||||
}
|
||||
});
|
||||
}else{
|
||||
n.setOptions({
|
||||
color:{
|
||||
background: "#ff0000",
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
network.redraw();
|
||||
}
|
||||
|
||||
|
||||
function getSimulation(){
|
||||
fetch("http://localhost/simulate")
|
||||
//prepare the json data
|
||||
json = {
|
||||
graph: selectedGraph,
|
||||
horizon: horizon,
|
||||
states: states,
|
||||
initial_distribution : initial_distribution,
|
||||
rules : rules
|
||||
}
|
||||
|
||||
//combine url
|
||||
url = baseUrl + "/simulate?data=" + JSON.stringify(json);
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(response =>{
|
||||
console.log(response)
|
||||
simulationData = response;
|
||||
stepSlider.max = simulationData.steps - 1;
|
||||
createGraphFromDot(simulationData.dotGraph);
|
||||
stepSlider.max = simulationData.states.length - 1;
|
||||
//createGraphFromDot(simulationData.dotGraph);
|
||||
createGraphFromDot(json.graph);
|
||||
visualizeOneStep(simulationData.states[0]);
|
||||
//kelvin to celsius
|
||||
//let temp = Math.ceil(response.main.temp - 273.15);
|
||||
@ -102,7 +138,7 @@ function playAnimation(){
|
||||
//Play the animation
|
||||
animationInterval = setInterval(function(){
|
||||
//This is the animation routine
|
||||
if(currentAnimationStep == simulationData.steps){
|
||||
if(currentAnimationStep == simulationData.states.length - 1){
|
||||
//At the end of animation
|
||||
clearInterval(animationInterval);
|
||||
animationPlaying = false;
|
||||
|
||||
BIN
visualizer/public/python/__pycache__/graphUtils.cpython-39.pyc
Normal file
BIN
visualizer/public/python/__pycache__/graphUtils.cpython-39.pyc
Normal file
Binary file not shown.
21
visualizer/public/python/graphUtils.py
Normal file
21
visualizer/public/python/graphUtils.py
Normal file
@ -0,0 +1,21 @@
|
||||
def edgelistToDot(name, inp):
|
||||
output = "strict graph \"" + name + "\" {\n"
|
||||
for (x,y) in inp:
|
||||
output += f" {x} -- {y};\n"
|
||||
|
||||
output += "}"
|
||||
return output
|
||||
|
||||
def dotToEdgelist(graph):
|
||||
outStr = []
|
||||
graph = graph.split("\n")
|
||||
name = graph[0].split(" ")[2]
|
||||
name = name[1:len(name) - 1]
|
||||
for i in range(len(graph) - 1):
|
||||
if(i == 0):
|
||||
continue
|
||||
nodes = graph[i].split("--")
|
||||
node1 = int(nodes[0])
|
||||
node2 = int(nodes[1][0:len(nodes[1]) - 1])
|
||||
outStr.append((node1, node2,))
|
||||
return (name, outStr)
|
||||
159787
visualizer/public/python/json
Normal file
159787
visualizer/public/python/json
Normal file
File diff suppressed because it is too large
Load Diff
241
visualizer/public/python/simulationAdvanced.py
Normal file
241
visualizer/public/python/simulationAdvanced.py
Normal file
@ -0,0 +1,241 @@
|
||||
# example execution
|
||||
# python simulationAdvanced.py '{
|
||||
# "graph": "strict graph GraphHello {\n0 -- 1;\n1 -- 2;\n1 -- 3;\n}",
|
||||
# "horizon": 20.0,
|
||||
# "states": ["S", "I", "R"],
|
||||
# "initial_distribution": [0.5, 0.5, 0],
|
||||
# "rules": "I R 1.0 R S 0.7 I S I I 0.8"
|
||||
# }'
|
||||
|
||||
import numpy as np
|
||||
import sys
|
||||
import graphUtils
|
||||
import json
|
||||
# statesComp = ["S", "I", "R"]
|
||||
rulesComp = [("I", "R", 1.0), # spontaneous rule I -> R with rate 1.0
|
||||
("R", "S", 0.7), # spontaneous rule R -> S with rate 0.7
|
||||
(("I","S","I"),("I","I","I"), 0.8)] # contact rule I+S -> I+I with rate 0.4
|
||||
|
||||
simulation = []
|
||||
|
||||
class Rule:
|
||||
def __init__(self, ruleParts, probability):
|
||||
self.ruleParts = ruleParts
|
||||
self.probability = probability
|
||||
|
||||
def getString(self):
|
||||
output = "("
|
||||
for part in self.ruleParts:
|
||||
output += f"({part.getFromState().getValue()}, {part.getToState().getValue()}), "
|
||||
output = output[0:len(output)-2]
|
||||
output += f"), {self.probability})"
|
||||
return output
|
||||
|
||||
def getOutput(self):
|
||||
# index of to state is ruleParts / 2
|
||||
toStateIndex = int(len(self.ruleParts) / 2)
|
||||
fromTuple = []
|
||||
toTuple = []
|
||||
for i in range(toStateIndex):
|
||||
fromTuple.append(self.ruleParts[i])
|
||||
toTuple.append(self.ruleParts[i + toStateIndex])
|
||||
|
||||
if(len(fromTuple) > 1):
|
||||
fromTuple = tuple(fromTuple)
|
||||
toTuple = tuple(toTuple)
|
||||
return (fromTuple, toTuple, self.probability,)
|
||||
else:
|
||||
return (fromTuple[0], toTuple[0], self.probability,)
|
||||
|
||||
|
||||
|
||||
def parseState(string):
|
||||
output = ""
|
||||
i = 0
|
||||
while(not(string[i].isdigit() or string[i] == " ")):
|
||||
output += string[i]
|
||||
i += 1
|
||||
return (output, string[i+1:],)
|
||||
|
||||
def parseRate(string):
|
||||
output = ""
|
||||
i = 0
|
||||
while(not string[i] == " "):
|
||||
output += string[i]
|
||||
i += 1
|
||||
if(i == len(string)):
|
||||
break
|
||||
return(float(output), string[i+1:])
|
||||
|
||||
|
||||
# Extract rules from string
|
||||
# example: "Inf Inf Inf R 0.8"
|
||||
def stringToRule(Input):
|
||||
allRules = []
|
||||
rulePartsBuffer = []
|
||||
while(len(Input) > 0):
|
||||
newString = parseState(Input)
|
||||
rulePartsBuffer.append(newString[0])
|
||||
|
||||
# check if we are at the end
|
||||
if(newString[1][0].isdigit()):
|
||||
newString = parseRate(newString[1])
|
||||
allRules.append(Rule(rulePartsBuffer.copy(), newString[0]))
|
||||
rulePartsBuffer.clear()
|
||||
|
||||
Input = newString[1]
|
||||
|
||||
output = []
|
||||
for r in allRules:
|
||||
output.append(r.getOutput())
|
||||
return output
|
||||
|
||||
def stringToStates(inp):
|
||||
inp = inp.split(" ")
|
||||
out = []
|
||||
for s in inp:
|
||||
out.append(s)
|
||||
return out
|
||||
|
||||
def stringToDistr(inp):
|
||||
inp = inp.split(" ")
|
||||
out = []
|
||||
for i in inp:
|
||||
out.append(float(i))
|
||||
return out
|
||||
|
||||
# parse the input wohooooo
|
||||
# rules = stringToRule(sys.argv[1])
|
||||
# states = stringToStates(sys.argv[2])
|
||||
# initial_distribution = stringToDistr(sys.argv[3])
|
||||
|
||||
jsonInput = json.loads(sys.argv[1])
|
||||
# print(jsonInput["graph"])
|
||||
graph_as_edgelist = graphUtils.dotToEdgelist(jsonInput["graph"])[1]
|
||||
horizon = jsonInput["horizon"]
|
||||
states = jsonInput["states"]
|
||||
initial_distribution = jsonInput["initial_distribution"]
|
||||
rules = stringToRule(jsonInput["rules"])
|
||||
# print(graph_as_edgelist)
|
||||
|
||||
|
||||
#graph_as_edgelist = [(0, 4), (0, 1), (1, 5), (1, 2), (2, 6), (2, 3), (3, 7), (4, 8), (4, 5), (5, 9), (5, 6), (6, 10), (6, 7), (7, 11), (8, 12), (8, 9), (9, 13), (9, 10), (10, 14), (10, 11), (11, 15), (12, 13), (13, 14), (14, 15)]
|
||||
|
||||
# print(graphUtils.edgelistToDot("testGraph", graph_as_edgelist))
|
||||
# print(graphUtils.dotToEdgelist("strict graph 'testGraph' {\n0 -- 4;\n0 -- 1;\n1 -- 5;\n}")[0])
|
||||
|
||||
# horizon = 20.0 # wie lange wird simuliert
|
||||
# initial_distribution = [0.5, 0.5, 0.0] # gleiche Reihenfolge wie states, musss zu rules passen und normalisiert werden
|
||||
timepoint_num = 101
|
||||
def get_next_state(current_labels):
|
||||
fastes_firing_time = 10000000.0 #dummy
|
||||
firing_rule = None
|
||||
firing_node = None
|
||||
firing_edge = None
|
||||
|
||||
# iterate over nodes
|
||||
for node in nodes:
|
||||
current_state = current_labels[node]
|
||||
for rule in rules:
|
||||
if 'tuple' in str(type(rule[0])):
|
||||
# is contact rule
|
||||
continue
|
||||
if current_state == rule[0]:
|
||||
current_fireing_time = np.random.exponential(1.0/rule[2])
|
||||
if current_fireing_time < fastes_firing_time:
|
||||
fastes_firing_time = current_fireing_time
|
||||
firing_rule = rule
|
||||
firing_node = node
|
||||
firing_edge = None
|
||||
|
||||
|
||||
# iterate over edges:
|
||||
for edge in graph_as_edgelist:
|
||||
node1, node2 = edge
|
||||
current_state1 = current_labels[node1]
|
||||
current_state2 = current_labels[node2]
|
||||
for rule in rules:
|
||||
if 'str' in str(type(rule[0])):
|
||||
# is spont. rule
|
||||
continue
|
||||
if (current_state1 == rule[0][0] and current_state2 == rule[0][1]) or (current_state2 == rule[0][0] and current_state1 == rule[0][1]):
|
||||
current_fireing_time = np.random.exponential(1.0/rule[2])
|
||||
if current_fireing_time < fastes_firing_time:
|
||||
fastes_firing_time = current_fireing_time
|
||||
firing_rule = rule
|
||||
firing_node = None
|
||||
firing_edge = edge
|
||||
|
||||
|
||||
if firing_rule is None:
|
||||
# no rule could fire
|
||||
return None, fastes_firing_time # would happen anyway but still
|
||||
|
||||
# apply rule
|
||||
new_labels = list(current_labels) # copy
|
||||
|
||||
if firing_node is not None:
|
||||
new_labels[firing_node] = firing_rule[1]
|
||||
return new_labels, fastes_firing_time
|
||||
|
||||
assert(firing_edge is not None)
|
||||
change_node1 = firing_edge[0]
|
||||
change_node2 = firing_edge[1]
|
||||
# we have to check which node changes in which direction
|
||||
if new_labels[change_node1] == firing_rule[0][0] and new_labels[change_node2] == firing_rule[0][1]:
|
||||
new_labels[change_node1] = firing_rule[1][0]
|
||||
new_labels[change_node2] = firing_rule[1][1]
|
||||
else:
|
||||
new_labels[change_node1] = firing_rule[1][1]
|
||||
new_labels[change_node2] = firing_rule[1][0]
|
||||
|
||||
|
||||
return new_labels, fastes_firing_time
|
||||
|
||||
def count_states(current_labels):
|
||||
counter = [0 for _ in states]
|
||||
simulation.append(current_labels)
|
||||
for label in current_labels:
|
||||
index = states.index(label)
|
||||
counter[index] += 1
|
||||
return counter
|
||||
|
||||
nodes = sorted(list(set([e[0] for e in graph_as_edgelist] + [e[1] for e in graph_as_edgelist])))
|
||||
assert(nodes == list(range(len(nodes)))) # nodes haben labels 0...<N-1>
|
||||
|
||||
# setup
|
||||
timepoints_samples = np.linspace(0.0, horizon, timepoint_num)
|
||||
timepoints_samples_static = np.linspace(0.0, horizon, timepoint_num)
|
||||
initial_labels = list(np.random.choice(states, len(nodes), p=initial_distribution))
|
||||
current_labels = initial_labels
|
||||
global_clock = 0.0
|
||||
labels = list()
|
||||
timepoints = list()
|
||||
state_counts = list()
|
||||
|
||||
|
||||
# simulate
|
||||
while len(timepoints_samples) > 0:
|
||||
new_labels, time_passed = get_next_state(current_labels)
|
||||
global_clock += time_passed
|
||||
while len(timepoints_samples) > 0 and global_clock > timepoints_samples[0]:
|
||||
labels.append(list(current_labels))
|
||||
state_counts.append(count_states(current_labels))
|
||||
timepoints_samples = timepoints_samples[1:]
|
||||
current_labels = new_labels
|
||||
|
||||
|
||||
for l in simulation:
|
||||
# print(l)
|
||||
pass
|
||||
|
||||
# if(rulesComp == rules):
|
||||
# print("Rules were parsed correctly")
|
||||
# else:
|
||||
# print("Rules were not parsed correctly")
|
||||
|
||||
# prepare the output json file
|
||||
outputJson = {
|
||||
"states": simulation
|
||||
}
|
||||
print(json.dumps(outputJson))
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
@ -18,20 +19,43 @@ class SimulationController extends AbstractController
|
||||
]);
|
||||
}
|
||||
#[Route('/simulate', name: 'run_simulation')]
|
||||
public function simulate(): Response
|
||||
public function simulate(Request $request): Response
|
||||
{
|
||||
$process1 = new Process(['python3', 'python/simulation.py']);
|
||||
//$process = new Process(['cat', 'python/graph.dot']);
|
||||
$process1->run();
|
||||
//$process->run();
|
||||
$input = $request->query->get('data');
|
||||
$process = new Process(['python3', 'python/simulationAdvanced.py', $input]);
|
||||
//$process = new Process(['python3', 'python/simulationAdvanced.py', '{
|
||||
//"graph": "strict graph GraphHello {\n0 -- 1;\n1 -- 2;\n1 -- 3;\n}",
|
||||
//"horizon": 20.0,
|
||||
//"states": ["S", "I", "R"],
|
||||
//"initial_distribution": [0.5, 0.5, 0],
|
||||
//"rules": "I R 1.0 R S 0.7 I S I I 0.8"
|
||||
//}']);
|
||||
$process->run();
|
||||
|
||||
// executes after the command finishes
|
||||
if (!$process1->isSuccessful()) {
|
||||
throw new ProcessFailedException($process1);
|
||||
if (!$process->isSuccessful()) {
|
||||
throw new ProcessFailedException($process);
|
||||
}
|
||||
|
||||
$output = $process1->getOutput();
|
||||
$output = $process->getOutput();
|
||||
$response = new Response($output);
|
||||
return $response;
|
||||
}
|
||||
//#[Route('/simulate', name: 'run_simulation')]
|
||||
//public function simulate(): Response
|
||||
//{
|
||||
//$process1 = new Process(['python3', 'python/simulation.py']);
|
||||
////$process = new Process(['cat', 'python/graph.dot']);
|
||||
//$process1->run();
|
||||
////$process->run();
|
||||
//
|
||||
//// executes after the command finishes
|
||||
//if (!$process1->isSuccessful()) {
|
||||
//throw new ProcessFailedException($process1);
|
||||
//}
|
||||
//
|
||||
//$output = $process1->getOutput();
|
||||
//$response = new Response($output);
|
||||
//return $response;
|
||||
//}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user