1
0
mirror of https://github.com/gsi-upm/soil synced 2024-11-14 23:42:29 +00:00

Running new simulations

This commit is contained in:
Tasio Mendez 2018-02-01 19:37:10 +01:00
parent c93f3fafc7
commit 05c1b5c003
7 changed files with 501 additions and 422 deletions

View File

@ -61,7 +61,6 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
if self.application.verbose: if self.application.verbose:
logger.info('Socket opened!') logger.info('Socket opened!')
def check_origin(self, origin): def check_origin(self, origin):
return True return True
@ -75,9 +74,9 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
if self.application.verbose: if self.application.verbose:
print(msg['data']) print(msg['data'])
config = list(yaml.load_all(msg['data'])) self.config = list(yaml.load_all(msg['data']))
if len(config) > 1: if len(self.config) > 1:
error = 'Please, provide only one configuration.' error = 'Please, provide only one configuration.'
if self.application.verbose: if self.application.verbose:
logger.error(error) logger.error(error)
@ -85,16 +84,18 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
'error': error}) 'error': error})
return return
else: else:
config = config[0] self.config = self.config[0]
self.send_log('INFO.soil', 'Using config: {name}'.format(name=config['name'])) self.send_log('INFO.soil', 'Using config: {name}'.format(name=self.config['name']))
self.name = config['name'] self.name = self.config['name']
self.run_simulation()
settings = [] settings = []
for key in config['environment_params']: for key in self.config['environment_params']:
if type(config['environment_params'][key]) == float: if type(self.config['environment_params'][key]) == float:
setting_type = 'number' setting_type = 'number'
elif type(config['environment_params'][key]) == bool: elif type(self.config['environment_params'][key]) == bool:
setting_type = 'boolean' setting_type = 'boolean'
else: else:
setting_type = 'undefined' setting_type = 'undefined'
@ -102,22 +103,12 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
settings.append({ settings.append({
'label': key, 'label': key,
'type': setting_type, 'type': setting_type,
'value': config['environment_params'][key] 'value': self.config['environment_params'][key]
}) })
self.write_message({'type': 'settings', self.write_message({'type': 'settings',
'data': settings}) 'data': settings})
# Run simulation and capture logs
with self.logging(self.application.model.name):
self.application.model.run(config)
trials = []
for i in range(config['num_trials']):
trials.append('{}_trial_{}'.format(self.name, i))
self.write_message({'type': 'trials',
'data': trials })
elif msg['type'] == 'get_trial': elif msg['type'] == 'get_trial':
if self.application.verbose: if self.application.verbose:
logger.info('Trial {} requested!'.format(msg['data'])) logger.info('Trial {} requested!'.format(msg['data']))
@ -125,6 +116,11 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
self.write_message({'type': 'get_trial', self.write_message({'type': 'get_trial',
'data': self.application.model.get_trial(self.name, msg['data']) }) 'data': self.application.model.get_trial(self.name, msg['data']) })
elif msg['type'] == 'run_simulation':
self.send_log('INFO.soil', 'Running new simulation for {name}'.format(name=self.config['name']))
self.config['environment_params'] = msg['data']
self.run_simulation()
else: else:
if self.application.verbose: if self.application.verbose:
logger.info('Unexpected message!') logger.info('Unexpected message!')
@ -148,6 +144,17 @@ class SocketHandler(tornado.websocket.WebSocketHandler):
'logger': logger, 'logger': logger,
'logging': logging }) 'logging': logging })
def run_simulation(self):
# Run simulation and capture logs
with self.logging(self.application.model.name):
self.application.model.run(self.config)
trials = []
for i in range(self.config['num_trials']):
trials.append('{}_trial_{}'.format(self.name, i))
self.write_message({'type': 'trials',
'data': trials })
@contextmanager @contextmanager
def logging(self, logger): def logging(self, logger):
self.capture_logging = True self.capture_logging = True

View File

@ -24,6 +24,10 @@ html, body {
margin-right: 10px !important; margin-right: 10px !important;
} }
.nav.navbar-right a {
outline: none !important;
}
.dropdown-menu > li > a:hover { .dropdown-menu > li > a:hover {
background-color: #d4d3d3; background-color: #d4d3d3;
cursor: pointer; cursor: pointer;
@ -398,3 +402,9 @@ table#link-distance .max {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
/** MODAL **/
.modal-footer,
.modal-header {
border: none !important;
}

View File

@ -97,40 +97,38 @@
$('.config-item #properties').change(function() { $('.config-item #properties').change(function() {
self.GraphVisualization.update_graph($(this).val(), slider.value(), function() { self.GraphVisualization.update_graph($(this).val(), slider.value(), function() {
update_statistics_table(); update_statistics_table();
}) });
}); });
chart_nodes = c3.generate({ // Run simulation
size: { $('#simulation_modal .btn-success').click(function() {
width: width_chart, if ( !jQuery.isEmptyObject(run_simulation()) ) {
height: height_chart self.GraphVisualization.reset();
}, $('#load').show().addClass('loader');;
data: { _socket.send(run_simulation(), 'run_simulation');
columns: [], $('.console').append('<br/>');
type: 'area-spline' }
}, $('#simulation_modal').modal('hide')
axis: {
x: { label: 'Time' },
y: { label: 'Number of nodes' }
},
point: { show: false },
bindto: '#chart_nodes'
}); });
chart_attrs = c3.generate({
size: { chart_nodes = create_chart(width_chart, height_chart, 'Time', 'Number of nodes', '#chart_nodes');
width: width_chart, chart_attrs = create_chart(width_chart, height_chart, 'Time', 'Attributes', '#chart_attrs');
height: height_chart
}, // Fill modal window
data: { $('#simulation_modal').on('show.bs.modal', function(e) {
columns: [], var variables = run_simulation()
type: 'area-spline' var x = 0,
}, row;
axis: { for (var i in variables) {
x: { label: 'Time' }, if ( x % 2 === 0 ) row = $('<tr>').appendTo('#simulation_modal table tbody');
y: { label: 'Attributes' } $('<td>').text(i).appendTo(row);
}, $('<td>').text(variables[i]).appendTo(row);
point: { show: false }, x++;
bindto: '#chart_attrs' }
});
$('#simulation_modal').on('hide.bs.modal', function(e) {
$('#simulation_modal table tbody').empty();
}); });
} }
@ -190,7 +188,7 @@
</li> </li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="#">Run simulation</a></li> <li><a href="#" id="run_simulation" role="button">Run simulation</a></li>
</ul> </ul>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
@ -319,6 +317,29 @@
</div> </div>
<div class="modal fade" tabindex="-1" role="dialog" id="simulation_modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">New simulation</h4>
</div>
<div class="modal-body">
<p>You are going to run a new simulation, all charts and trials are going to be lost. A new ones will be available after the simulation.</p>
<p>Check your new environment variables for this simulation.</p>
<table class="table">
<thead><tr><th>Variable</th><th>Value</th><th>Variable</th><th>Value</th></tr></thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-success">Run</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body> </body>
</html> </html>

View File

@ -38,6 +38,11 @@ ws.onmessage = function(message) {
$('#charts .chart').removeClass('no-data'); $('#charts .chart').removeClass('no-data');
set_chart_nodes(msg['data']['graph'], chart_nodes) set_chart_nodes(msg['data']['graph'], chart_nodes)
set_chart_attrs(msg['data']['graph'], chart_attrs, $('.config-item #properties').val()) set_chart_attrs(msg['data']['graph'], 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())
});
break; break;
case 'settings': case 'settings':
@ -168,6 +173,9 @@ var set_configuration = function() {
$('#link-distance-slider').slider('enable').on('change', function(value) { $('#link-distance-slider').slider('enable').on('change', function(value) {
self.GraphVisualization.set_link_distance(value.value.newValue); self.GraphVisualization.set_link_distance(value.value.newValue);
}); });
// Enable 'Run configuration' button
$('#run_simulation').attr('data-toggle', 'modal').attr('data-target', '#simulation_modal');
} }
var reset_configuration = function() { var reset_configuration = function() {
@ -340,3 +348,40 @@ var set_chart_attrs = function(graph, chart, property) {
}); });
chart.axis.labels({y: property}); chart.axis.labels({y: property});
} }
var create_chart = function(width, height, label_x, label_y, bind_to) {
return c3.generate({
size: {
width: width,
height: height
},
data: {
columns: [],
type: 'area-spline'
},
axis: {
x: { label: label_x },
y: { label: label_y }
},
point: { show: false },
bindto: bind_to
});
}
var run_simulation = function() {
var environment_variables = {}
$('#wrapper-settings input').each(function() {
switch(this.type) {
case 'text':
environment_variables[this.id] = Number(this.value);
break;
case 'checkbox':
environment_variables[this.id] = ($(this).is(':checked')) ? true : false;
break;
default:
break;
}
});
return environment_variables;
}

View File

@ -1,10 +1,6 @@
// Add model parameters that can be edited prior to a model run // Add model parameters that can be edited prior to a model run
var initGUI = function(model_params) { var initGUI = function(model_params) {
var onSubmitCallback = function(param_name, value) {
// SEND SOCKET REQUEST
};
var addBooleanInput = function(name, value) { var addBooleanInput = function(name, value) {
var checked = (value) ? 'checked' : 'value'; var checked = (value) ? 'checked' : 'value';
@ -79,14 +75,14 @@ var initGUI = function(model_params) {
var param_str = String(option); var param_str = String(option);
switch (model_params[option]['type']) { switch (model_params[option]['type']) {
case "boolean": case 'boolean':
addBooleanInput(model_params[option]['label'], model_params[option]['value']); addBooleanInput(model_params[option]['label'], model_params[option]['value']);
break; break;
case "number": case 'number':
addSliderInput(model_params[option]['label'], model_params[option]['value']); addSliderInput(model_params[option]['label'], model_params[option]['value']);
break; break;
case "object": default:
addParamInput(param_str, model_params[option]); // catch-all for params that use Option class console.log('Input type not defined!');
break; break;
} }
} }

View File

@ -294,17 +294,17 @@
function importJSON(json, attributes, callback) { function importJSON(json, attributes, callback) {
reset() reset()
graph = json; graph = json;
model = attributes 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 = model;
// 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(model.dynamic[0].title, 0);
if (callback) { callback(); } if (callback) { callback(); }
} }