mirror of
https://github.com/gsi-upm/soil
synced 2024-12-23 00:28:11 +00:00
Dumping results as option
This commit is contained in:
parent
05c1b5c003
commit
20aea9da33
@ -1,6 +1,6 @@
|
||||
name: ControlModelM2_sim
|
||||
max_time: 100
|
||||
num_trials: 2
|
||||
max_time: 15
|
||||
num_trials: 1
|
||||
network_params:
|
||||
generator: barabasi_albert_graph
|
||||
n: 100
|
||||
|
2
run.py
2
run.py
@ -11,5 +11,5 @@ def run(model, params=None):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
soil = Model(dump=True)
|
||||
soil = Model(dump=False)
|
||||
run(soil)
|
||||
|
10
server.py
10
server.py
@ -12,6 +12,7 @@ import logging
|
||||
import logging
|
||||
import threading
|
||||
import io
|
||||
import networkx as nx
|
||||
from datetime import timedelta
|
||||
from contextlib import contextmanager
|
||||
|
||||
@ -88,7 +89,6 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
self.send_log('INFO.soil', 'Using config: {name}'.format(name=self.config['name']))
|
||||
|
||||
self.name = self.config['name']
|
||||
|
||||
self.run_simulation()
|
||||
|
||||
settings = []
|
||||
@ -114,7 +114,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
logger.info('Trial {} requested!'.format(msg['data']))
|
||||
self.send_log('INFO.user', 'Trial {} requested!'.format(msg['data']))
|
||||
self.write_message({'type': 'get_trial',
|
||||
'data': self.application.model.get_trial(self.name, msg['data']) })
|
||||
'data': self.get_trial( int(msg['data'] )) })
|
||||
|
||||
elif msg['type'] == 'run_simulation':
|
||||
self.send_log('INFO.soil', 'Running new simulation for {name}'.format(name=self.config['name']))
|
||||
@ -147,7 +147,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
def run_simulation(self):
|
||||
# Run simulation and capture logs
|
||||
with self.logging(self.application.model.name):
|
||||
self.application.model.run(self.config)
|
||||
self.simulation = self.application.model.run(self.config)
|
||||
|
||||
trials = []
|
||||
for i in range(self.config['num_trials']):
|
||||
@ -155,6 +155,10 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
|
||||
self.write_message({'type': 'trials',
|
||||
'data': trials })
|
||||
|
||||
def get_trial(self, trial):
|
||||
G = self.simulation[trial].history_to_graph()
|
||||
return nx.node_link_data(G)
|
||||
|
||||
@contextmanager
|
||||
def logging(self, logger):
|
||||
self.capture_logging = True
|
||||
|
@ -21,27 +21,27 @@ ws.onmessage = function(message) {
|
||||
break;
|
||||
|
||||
case 'get_trial':
|
||||
console.log(msg['data']);
|
||||
GraphVisualization.import(convertJSON(msg['data']['graph']), msg['data']['models'], function() {
|
||||
//console.log(msg['data']);
|
||||
GraphVisualization.import(convertJSON(msg['data']), function() {
|
||||
$('#load').hide();
|
||||
reset_configuration();
|
||||
set_configuration();
|
||||
$('#home_menu').click(function() {
|
||||
setTimeout(function() {
|
||||
reset_timeline();
|
||||
set_timeline(msg['data']['graph']);
|
||||
set_timeline(msg['data']);
|
||||
}, 1000);
|
||||
});
|
||||
reset_timeline();
|
||||
set_timeline(msg['data']['graph']);
|
||||
set_timeline(msg['data']);
|
||||
});
|
||||
$('#charts .chart').removeClass('no-data');
|
||||
set_chart_nodes(msg['data']['graph'], chart_nodes)
|
||||
set_chart_attrs(msg['data']['graph'], chart_attrs, $('.config-item #properties').val())
|
||||
set_chart_nodes(msg['data'], chart_nodes)
|
||||
set_chart_attrs(msg['data'], chart_attrs, $('.config-item #properties').val())
|
||||
$('.config-item #properties').change(function() {
|
||||
chart_attrs.destroy();
|
||||
chart_attrs = create_chart(width_chart, height_chart, 'Time', 'Attributes', '#chart_attrs');
|
||||
set_chart_attrs(msg['data']['graph'], chart_attrs, $('.config-item #properties').val())
|
||||
set_chart_attrs(msg['data'], chart_attrs, $('.config-item #properties').val())
|
||||
});
|
||||
break;
|
||||
|
||||
|
@ -82,7 +82,7 @@ var initGUI = function(model_params) {
|
||||
addSliderInput(model_params[option]['label'], model_params[option]['value']);
|
||||
break;
|
||||
default:
|
||||
console.log('Input type not defined!');
|
||||
console.log(model_params[option]['type'] + ' not defined!');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
// Private constants
|
||||
var focus_opacity = 0.1,
|
||||
radius = 8;
|
||||
radius = 8,
|
||||
required_node = ['id', 'index', 'label', 'px', 'py', 'spells', 'weight', 'x', 'y'];
|
||||
|
||||
// Private variables
|
||||
var width,
|
||||
@ -43,6 +44,13 @@
|
||||
return ( this > min && this <= max ) || ( min === 0 && this === 0 );
|
||||
};
|
||||
|
||||
Number.prototype.type = function() {
|
||||
if ( typeof(this) === 'number' )
|
||||
return ( Number.isInteger(this) ) ? 'int' : 'float';
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
var lastFocusNode;
|
||||
var _helpers = {
|
||||
set_node: function(node, property, time) {
|
||||
@ -118,7 +126,14 @@
|
||||
link.style('opacity', function(o) {
|
||||
return o.source.index == d.index || o.target.index == d.index ? 1 : focus_opacity;
|
||||
});
|
||||
},
|
||||
push_once: function(array, item, key) {
|
||||
for (var i in array) {
|
||||
if ( array[i][key] == item[key] ) return false;
|
||||
}
|
||||
array.push(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -253,6 +268,22 @@
|
||||
self.GraphVisualization.statistics = statistics
|
||||
}
|
||||
|
||||
function get_models(graph) {
|
||||
|
||||
var models = { 'dynamic': [], 'static': [] }
|
||||
|
||||
graph['nodes'].forEach(function(node) {
|
||||
for ( var att in node ) {
|
||||
if (!required_node.includes(att)) {
|
||||
if ( Array.isArray(node[att]) ) _helpers.push_once(models['dynamic'], { 'title': att, 'type': node[att][0][0].type() }, 'title');
|
||||
else _helpers.push_once(models['static'], { 'title': att, 'type': typeof(node[att]) }, 'title');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return models;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Public API
|
||||
@ -287,24 +318,21 @@
|
||||
* A function that imports the graph and the attributes of all the nodes.
|
||||
*
|
||||
* @param {object} json The json structure of the graph.
|
||||
* @param {object} attributes Definition of the attributes of the nodes
|
||||
* (statics and dynamics).
|
||||
* @param {object} callback A function called at the end.
|
||||
*/
|
||||
function importJSON(json, attributes, callback) {
|
||||
function importJSON(json, callback) {
|
||||
reset()
|
||||
graph = json;
|
||||
model = attributes;
|
||||
|
||||
// Create the graph itself
|
||||
Graph();
|
||||
|
||||
self.GraphVisualization.nodes = graph.nodes.length;
|
||||
self.GraphVisualization.links = graph.links.length;
|
||||
self.GraphVisualization.model = model;
|
||||
self.GraphVisualization.model = get_models(json);
|
||||
|
||||
// Draw graph with default property and time for the first time
|
||||
update_data(model.dynamic[0].title, 0);
|
||||
update_data(self.GraphVisualization.model.dynamic[0].title, 0);
|
||||
|
||||
if (callback) { callback(); }
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import os
|
||||
import networkx as nx
|
||||
from server import VisualizationElement
|
||||
from soil.simulation import SoilSimulation
|
||||
from xml.etree import ElementTree
|
||||
@ -7,10 +6,11 @@ from xml.etree import ElementTree
|
||||
|
||||
class Model():
|
||||
|
||||
def __init__(self, dump=True, dir_path='output'):
|
||||
def __init__(self, dump=False, dir_path='output'):
|
||||
self.name = 'soil'
|
||||
self.dump = dump
|
||||
self.dir_path = dir_path
|
||||
self.simulation = list()
|
||||
|
||||
def run(self, config):
|
||||
name = config['name']
|
||||
@ -22,40 +22,11 @@ class Model():
|
||||
|
||||
print('Dumping results to {} : {}'.format(sim.dir_path, sim.dump))
|
||||
|
||||
sim.run_simulation()
|
||||
|
||||
|
||||
def get_trial(self, name, trial):
|
||||
graph = nx.read_gexf(os.path.join(self.dir_path, name, '{}_trial_{}.gexf'.format(name, trial)))
|
||||
|
||||
attributes = self.get_attributes(os.path.join(self.dir_path, name, '{}_trial_{}.gexf'.format(name, trial)))
|
||||
json = {}
|
||||
json['graph'] = nx.node_link_data(graph)
|
||||
json['models'] = attributes
|
||||
return json
|
||||
return sim.run_simulation()
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
|
||||
def get_attributes(self, path_gexf):
|
||||
attributes = {}
|
||||
tree = ElementTree.parse(path_gexf)
|
||||
root = tree.getroot()
|
||||
|
||||
ns = { 'gexf': 'http://www.gexf.net/1.2draft' }
|
||||
|
||||
for mode in root[0].findall('gexf:attributes', ns):
|
||||
attributes[mode.attrib['mode']] = []
|
||||
for attribute in mode:
|
||||
values = {
|
||||
'id' : attribute.attrib['id'],
|
||||
'title' : attribute.attrib['title'],
|
||||
'type' : attribute.attrib['type']
|
||||
}
|
||||
attributes[mode.attrib['mode']].append(values)
|
||||
|
||||
return attributes
|
||||
|
||||
|
||||
class GraphVisualization(VisualizationElement):
|
||||
package_includes = []
|
||||
|
Loading…
Reference in New Issue
Block a user