Foundation for parameter sweeping visualization.

This commit is contained in:
Jeremy Goecks
2012-06-05 17:10:23 -04:00
parent a0c13aa554
commit cc9381d436
6 changed files with 207 additions and 3 deletions
+10 -1
View File
@@ -2407,10 +2407,19 @@ class Tool:
if isinstance( input, DataToolParameter ):
param_dict.update( { 'type' : 'data', 'html' : urllib.quote( input.get_html( trans ) ) } )
elif isinstance( input, SelectToolParameter ):
param_dict.update( { 'type' : 'select', 'html' : urllib.quote( input.get_html( trans ) ) } )
param_dict.update( { 'type' : 'select',
'html' : urllib.quote( input.get_html( trans ) ),
'options': input.static_options
} )
elif isinstance( input, Conditional ):
# TODO.
pass
elif isinstance( input, ( IntegerToolParameter, FloatToolParameter ) ):
param_dict.update( { 'type' : 'number', 'init_value' : input.value,
'html' : urllib.quote( input.get_html( trans ) ),
'min': input.min,
'max': input.max
} )
else:
param_dict.update( { 'type' : '??', 'init_value' : input.value, \
'html' : urllib.quote( input.get_html( trans ) ) } )
+9
View File
@@ -762,6 +762,15 @@ class TracksController( BaseUIController, UsesVisualizationMixin, UsesHistoryMix
output_dataset = joda.dataset
return self.add_track_async( trans, output_dataset.id )
@web.expose
@web.require_login( "use Galaxy visualizations", use_panels=True )
def paramamonster( self, trans, hda_ldda, dataset_id ):
# Get dataset.
dataset = self._get_dataset( trans, hda_ldda, dataset_id )
return trans.fill_template_mako( "visualization/paramamonster.mako", dataset=dataset,
tool=self.app.toolbox.tools_by_id[ 'cufflinks' ].to_dict( trans, for_display=True ) )
@web.expose
@web.require_login( "use Galaxy visualizations", use_panels=True )
@@ -0,0 +1 @@
var ToolParameterTree=Backbone.Model.extend({defaults:{tool:null,samples:4},initialize:function(d){var c=this.get("tool"),b=this.get("samples"),a=c.get("inputs").filter(function(h){return(["number","select"].indexOf(h.get("type"))!==-1)}),f=_.map(a,function(h){return h.get("name")});sampling=_.map(a,function(h){var i=h.get("type");if(i==="number"){return d3.scale.linear().domain([h.get("min"),h.get("max")]).ticks(b)}else{if(i==="select"){return _.map(h.get("options"),function(j){return j[0]})}}});var g=function(j,h,i){if(h.length-1===i){return _.map(h[i],function(k){return{name:k}})}return _.map(h[i],function(k){return{name:j[i]+":"+k,children:g(j,h,i+1)}})};var e={name:"Parameter Tree for "+c.get("name"),children:g(f,sampling,0)};this.set("valid_inputs",a);this.set("tree_data",e)}});var TileView=Backbone.View.extend({});var ToolParameterTreeView=Backbone.View.extend({className:"paramamonster",initialize:function(a){this.model=a.model},render:function(){var e=960,b=2000;var a=d3.layout.cluster().size([b,e-160]);var d=d3.svg.diagonal().projection(function(i){return[i.y,i.x]});var h=d3.select(this.$el[0]).append("svg").attr("width",e).attr("height",b).append("g").attr("transform","translate(80, 0)");var c=a.nodes(this.model.get("tree_data"));var g=h.selectAll("path.link").data(a.links(c)).enter().append("path").attr("class","link").attr("d",d);var f=h.selectAll("g.node").data(c).enter().append("g").attr("class","node").attr("transform",function(i){return"translate("+i.y+","+i.x+")"});f.append("circle").attr("r",4.5);f.append("text").attr("dx",function(i){return i.children?-8:8}).attr("dy",3).attr("text-anchor",function(i){return i.children?"end":"start"}).text(function(i){return i.name})}});
+123
View File
@@ -0,0 +1,123 @@
/**
* Visualization and components for ParamaMonster, a visualization for exploring a tool's parameter space via
* genomic visualization.
*/
var ToolParameterTree = Backbone.Model.extend({
defaults: {
tool: null,
samples: 4
},
initialize: function(options) {
//
// -- Create tree data from tool. --
//
// Valid inputs for tree are number, select parameters.
var tool = this.get('tool'),
samples = this.get('samples'),
inputs = tool.get('inputs').filter(function(input) {
return ( ['number', 'select'].indexOf(input.get('type')) !== -1 );
}),
inputs_names = _.map(inputs, function(i) { return i.get('name')});
// Sample from all valid inputs.
sampling = _.map(inputs, function(input) {
var type = input.get('type');
if (type === 'number') {
return d3.scale.linear().domain([input.get('min'), input.get('max')]).ticks(samples);
}
else if (type === 'select') {
return _.map(input.get('options'), function(option) {
return option[0];
});
}
});
/**
* Returns tree data.
*/
var create_tree_data = function(param_names, param_settings, index) {
// Terminate when last parameter setting is reached.
if (param_settings.length - 1 === index) {
return _.map(param_settings[index], function(setting) {
return {
name: setting
}
});
}
// Recurse to handle other parameters.
return _.map(param_settings[index], function(setting) {
return {
name: param_names[index] + ':' + setting,
children: create_tree_data(param_names, param_settings, index + 1)
}
});
};
var tree_data = {
name: 'Parameter Tree for ' + tool.get('name'),
children: create_tree_data(inputs_names, sampling, 0)
};
// Set valid inputs, tree data for later use.
this.set('valid_inputs', inputs);
this.set('tree_data', tree_data);
}
});
var TileView = Backbone.View.extend({
});
var ToolParameterTreeView = Backbone.View.extend({
className: 'paramamonster',
initialize: function(options) {
this.model = options.model;
},
render: function() {
var width = 960,
height = 2000;
var cluster = d3.layout.cluster()
.size([height, width - 160]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var vis = d3.select(this.$el[0])
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(80, 0)");
var nodes = cluster.nodes(this.model.get('tree_data'));
var link = vis.selectAll("path.link")
.data(cluster.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("circle")
.attr("r", 4.5);
node.append("text")
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("dy", 3)
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.name; });
}
});
+2 -2
View File
@@ -16,7 +16,7 @@
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "libs/d3", "mvc/visualization" )}
${h.js( "libs/d3", "viz/visualization" )}
<script type="text/javascript">
$(function() {
@@ -81,7 +81,7 @@
// -- Render viz. --
circster.render();
$('#vis').append(circster.$el);
$('#vis').append(circster.$el);
});
</script>
</%def>
@@ -0,0 +1,62 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
self.has_left_panel=False
self.has_right_panel=False
self.active_view="visualization"
self.message_box_visible=False
%>
</%def>
<%def name="stylesheets()">
${parent.stylesheets()}
<style>
.unified-panel-body {
overflow: auto;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
.node {
font: 10px sans-serif;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
</%def>
<%def name="javascripts()">
${parent.javascripts()}
${h.templates( "tool_link", "panel_section", "tool_search" )}
${h.js( "libs/d3", "viz/visualization", "viz/paramamonster", "mvc/tools" )}
<script type="text/javascript">
$(function() {
// -- Viz set up. --
var tool = new Tool(JSON.parse('${ h.to_json_string( tool ) }')),
tool_param_tree = new ToolParameterTree({ tool: tool }),
tool_param_tree_view = new ToolParameterTreeView({ model: tool_param_tree });
tool_param_tree_view.render();
$('#vis').append(tool_param_tree_view.$el);
});
</script>
</%def>
<%def name="center_panel()">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div style="float:left;" id="title"></div>
</div>
<div style="clear: both"></div>
</div>
<div id="vis" class="unified-panel-body"></div>
</%def>