1
0
mirror of https://github.com/gsi-upm/soil synced 2024-11-26 21:02:29 +00:00

Dumping results as option

This commit is contained in:
Tasio Mendez 2018-02-02 15:01:17 +01:00
parent 05c1b5c003
commit 20aea9da33
7 changed files with 56 additions and 53 deletions

View File

@ -1,6 +1,6 @@
name: ControlModelM2_sim name: ControlModelM2_sim
max_time: 100 max_time: 15
num_trials: 2 num_trials: 1
network_params: network_params:
generator: barabasi_albert_graph generator: barabasi_albert_graph
n: 100 n: 100

2
run.py
View File

@ -11,5 +11,5 @@ def run(model, params=None):
if __name__ == "__main__": if __name__ == "__main__":
soil = Model(dump=True) soil = Model(dump=False)
run(soil) run(soil)

View File

@ -12,6 +12,7 @@ import logging
import logging import logging
import threading import threading
import io import io
import networkx as nx
from datetime import timedelta from datetime import timedelta
from contextlib import contextmanager 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.send_log('INFO.soil', 'Using config: {name}'.format(name=self.config['name']))
self.name = self.config['name'] self.name = self.config['name']
self.run_simulation() self.run_simulation()
settings = [] settings = []
@ -114,7 +114,7 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
logger.info('Trial {} requested!'.format(msg['data'])) logger.info('Trial {} requested!'.format(msg['data']))
self.send_log('INFO.user', 'Trial {} requested!'.format(msg['data'])) self.send_log('INFO.user', 'Trial {} requested!'.format(msg['data']))
self.write_message({'type': 'get_trial', 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': elif msg['type'] == 'run_simulation':
self.send_log('INFO.soil', 'Running new simulation for {name}'.format(name=self.config['name'])) 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): def run_simulation(self):
# Run simulation and capture logs # Run simulation and capture logs
with self.logging(self.application.model.name): with self.logging(self.application.model.name):
self.application.model.run(self.config) self.simulation = self.application.model.run(self.config)
trials = [] trials = []
for i in range(self.config['num_trials']): for i in range(self.config['num_trials']):
@ -155,6 +155,10 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
self.write_message({'type': 'trials', self.write_message({'type': 'trials',
'data': trials }) 'data': trials })
def get_trial(self, trial):
G = self.simulation[trial].history_to_graph()
return nx.node_link_data(G)
@contextmanager @contextmanager
def logging(self, logger): def logging(self, logger):
self.capture_logging = True self.capture_logging = True

View File

@ -21,27 +21,27 @@ ws.onmessage = function(message) {
break; break;
case 'get_trial': case 'get_trial':
console.log(msg['data']); //console.log(msg['data']);
GraphVisualization.import(convertJSON(msg['data']['graph']), msg['data']['models'], function() { GraphVisualization.import(convertJSON(msg['data']), function() {
$('#load').hide(); $('#load').hide();
reset_configuration(); reset_configuration();
set_configuration(); set_configuration();
$('#home_menu').click(function() { $('#home_menu').click(function() {
setTimeout(function() { setTimeout(function() {
reset_timeline(); reset_timeline();
set_timeline(msg['data']['graph']); set_timeline(msg['data']);
}, 1000); }, 1000);
}); });
reset_timeline(); reset_timeline();
set_timeline(msg['data']['graph']); set_timeline(msg['data']);
}); });
$('#charts .chart').removeClass('no-data'); $('#charts .chart').removeClass('no-data');
set_chart_nodes(msg['data']['graph'], chart_nodes) set_chart_nodes(msg['data'], chart_nodes)
set_chart_attrs(msg['data']['graph'], chart_attrs, $('.config-item #properties').val()) set_chart_attrs(msg['data'], chart_attrs, $('.config-item #properties').val())
$('.config-item #properties').change(function() { $('.config-item #properties').change(function() {
chart_attrs.destroy(); chart_attrs.destroy();
chart_attrs = create_chart(width_chart, height_chart, 'Time', 'Attributes', '#chart_attrs'); 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; break;

View File

@ -82,7 +82,7 @@ var initGUI = function(model_params) {
addSliderInput(model_params[option]['label'], model_params[option]['value']); addSliderInput(model_params[option]['label'], model_params[option]['value']);
break; break;
default: default:
console.log('Input type not defined!'); console.log(model_params[option]['type'] + ' not defined!');
break; break;
} }
} }

View File

@ -13,7 +13,8 @@
// Private constants // Private constants
var focus_opacity = 0.1, var focus_opacity = 0.1,
radius = 8; radius = 8,
required_node = ['id', 'index', 'label', 'px', 'py', 'spells', 'weight', 'x', 'y'];
// Private variables // Private variables
var width, var width,
@ -43,6 +44,13 @@
return ( this > min && this <= max ) || ( min === 0 && this === 0 ); 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 lastFocusNode;
var _helpers = { var _helpers = {
set_node: function(node, property, time) { set_node: function(node, property, time) {
@ -118,6 +126,13 @@
link.style('opacity', function(o) { link.style('opacity', function(o) {
return o.source.index == d.index || o.target.index == d.index ? 1 : focus_opacity; 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 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 * Public API
@ -287,24 +318,21 @@
* A function that imports the graph and the attributes of all the nodes. * A function that imports the graph and the attributes of all the nodes.
* *
* @param {object} json The json structure of the graph. * @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. * @param {object} callback A function called at the end.
*/ */
function importJSON(json, attributes, callback) { function importJSON(json, callback) {
reset() reset()
graph = json; graph = json;
model = attributes;
// Create the graph itself // Create the graph itself
Graph(); Graph();
self.GraphVisualization.nodes = graph.nodes.length; self.GraphVisualization.nodes = graph.nodes.length;
self.GraphVisualization.links = graph.links.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 // 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(); } if (callback) { callback(); }
} }

View File

@ -1,5 +1,4 @@
import os import os
import networkx as nx
from server import VisualizationElement from server import VisualizationElement
from soil.simulation import SoilSimulation from soil.simulation import SoilSimulation
from xml.etree import ElementTree from xml.etree import ElementTree
@ -7,10 +6,11 @@ from xml.etree import ElementTree
class Model(): class Model():
def __init__(self, dump=True, dir_path='output'): def __init__(self, dump=False, dir_path='output'):
self.name = 'soil' self.name = 'soil'
self.dump = dump self.dump = dump
self.dir_path = dir_path self.dir_path = dir_path
self.simulation = list()
def run(self, config): def run(self, config):
name = config['name'] name = config['name']
@ -22,40 +22,11 @@ class Model():
print('Dumping results to {} : {}'.format(sim.dir_path, sim.dump)) print('Dumping results to {} : {}'.format(sim.dir_path, sim.dump))
sim.run_simulation() return 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
def reset(self): def reset(self):
pass 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): class GraphVisualization(VisualizationElement):
package_includes = [] package_includes = []