Navigation Menu

Skip to content

Commit

Permalink
WIP: web UI for editing configs
Browse files Browse the repository at this point in the history
  • Loading branch information
akeshavan committed Jan 1, 2013
1 parent d8ba451 commit e92fe9e
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -1,2 +1,6 @@
*.pyc
*.py~
example_configs/*
*.swp
doc/*/generated
doc/_*
12 changes: 12 additions & 0 deletions bips/service/base.py
Expand Up @@ -11,6 +11,7 @@
import numpy as np

from ..workflows import get_workflows, get_workflow
from scripts.form_scripts import get_form

MEDIA_DIR = os.path.join(os.path.dirname(__file__), 'scripts')
FILE_DIR = os.path.join(os.getcwd(), 'files')
Expand Down Expand Up @@ -72,6 +73,17 @@ def workflows(self, tags=None):
msg = fp.readlines()
return msg

@expose
def edit_config(self,uuid='7757e3168af611e1b9d5001e4fb1404c'):
conf = get_workflow(uuid).config_ui()
with open(os.path.join(MEDIA_DIR, 'edit_config.html')) as fp:
m = fp.readlines()
form = get_form(conf)

msg = '\n'.join(m).replace('**TEMPLATE**',form)
return msg


@expose
def queryworkflows(self, tags=None):
print tags
Expand Down
95 changes: 95 additions & 0 deletions bips/service/scripts/edit_config.html
@@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<!--
/*
* jQuery File Upload Plugin Demo 6.9
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>BIPS</title>
<meta name="description" content="BIPS is a Python framework for brain imaging to host reusable, queriable and uniquely identifiable workflows. This demo allows users to upload a structural and a resting state functional image and get back a quality assessment report and a view of their statistics relative to other datasets.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap CSS Toolkit styles -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-responsive.css">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<link href="css/docs.css" rel="stylesheet">
<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
<link rel="stylesheet" href="css/jquery.fileupload-ui.css">
<!-- Shim to make HTML5 elements usable in older Internet Explorer versions -->
<!--[if lt IE 9]><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<style type='text/css'>
pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }

</style>
</head>

<body data-spy="scroll" data-target=".subnav" data-offset="50">

<!-- Navbar
================================================== -->
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button"class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="./">BIPS</a>
<div class="nav-collapse">
<ul class="nav">
<li class=""><a href="./index">Overview</a></li>
<li class="active"><a href="./workflows">Workflows</a></li>
<li class=""><a href="./database">Database</a></li>
<li class=""><a href="./publications">Publications</a></li>
<li class=""><a href="./neuroview">Neuroview</a></li>
<li class=""><a href="./links">Links</a></li>
<li class="divider-vertical"></li>
<li class=""><a href="./demo">Demo</a></li>
<li class=""><a href="./status">Status</a></li>
</ul>
</div>
</div>
</div>
</div>

<div class="container">

<div class="row">
**TEMPLATE**
</div>

<!-- Footer
================================================== -->
<footer class="footer">
<p class="pull-right"><a href="#">Back to top</a></p>
<p>Brewed at <a href="http://gablab.mit.edu" target="_blank">Gablab@MIT</a> and TankThink Labs LLC. Supported by <a href="http://incf.org>" target="_blank">INCF</a>.</p>
<p>Code licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License v2.0</a>. Documentation licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
<p>Icons from <a href="http://glyphicons.com">Glyphicons Free</a>, licensed under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
</footer>

</div><!-- /container -->

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/bootstrap-typeahead.js"></script>
<script src="js/bootstrap-modal.js"></script>
<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE8+ -->
<!--[if gte IE 8]><script src="js/cors/jquery.xdr-transport.js"></script><![endif]-->
</body>
</html>
67 changes: 67 additions & 0 deletions bips/service/scripts/form_scripts.py
@@ -0,0 +1,67 @@
import colander
from colander import Schema
from deform import Form
import deform
import traits.api as traits

class Schema(colander.MappingSchema):
pass

def getNode(_type,tr,config):
if _type == type(traits.Int()):
col_type = colander.SchemaNode(colander.Int(),
name=tr,description=config.trait(tr).desc)
elif _type == type(traits.Float()):
col_type = colander.SchemaNode(colander.Decimal(),name=tr)

elif _type == type(traits.String()) or _type==type(traits.Str()):
col_type = colander.SchemaNode(colander.String(),name=tr)

elif _type == type(traits.Enum('')):
values=config.trait(tr).trait_type.values
the_values = []
for v in values:
the_values.append((v,v))
col_type = colander.SchemaNode(
deform.Set(),
widget=deform.widget.SelectWidget(values=the_values),
name=tr)
elif _type == type(traits.Bool()):
col_type = colander.SchemaNode(colander.Boolean(),widget=deform.widget.CheckboxWidget(),name=tr)
elif _type == type(traits.Code()):
col_type = colander.SchemaNode(colander.String(),name=tr,widget=deform.widget.TextAreaWidget(cols=100,rows=20))
#elif _type == type(traits.Instance())
elif _type == type(traits.List()):
col_type =get_list(_type,tr,config)
else:
print "type: ", _type, "not found!"
col_type = colander.SchemaNode(colander.String(),name=tr)
return col_type

def get_form(config):
schema = colander.Schema()
all_traits = config.trait_names()
all_traits.remove('trait_added')
all_traits.remove('trait_modified')

for tr in all_traits:
_type = type(config.trait(tr).trait_type)

col_type = getNode(_type,tr,config)

schema.add(col_type)

form = Form(schema,buttons = ('submit',),action='')

return form.render(appstruct=config.get())

def validator(form,value):
pass

def get_list(thetype,tr,config):
col_type = colander.SchemaNode(colander.String(),
name=tr,
description=config.trait(tr).desc,
widget=deform.widget.TextInputCSVWidget(cols=100,rows=1))
return col_type

2 changes: 1 addition & 1 deletion bips/service/scripts/workflows.html
Expand Up @@ -138,7 +138,7 @@ <h4>Workflow options</h4>
for(var i=0;i<data.length;i++){
var btninfo = "<a id=\"to_modal"+i+"\" href=\"./info?uuid="+data[i].uuid+"\"><i class=\"icon-info-sign\"></i></a>";
//btninfo = "<a data-toggle=\"modal\" href=\"#myModal\"><i class=\"icon-info-sign\"></i></a>"
var tdata = "<tr><td>"+btninfo+"</td><td>"+data[i].uuid+"</td><td>"+data[i].desc+"</td></tr>";
var tdata = "<tr><td>"+btninfo+"</td><td><a href=\"./edit_config?uuid="+data[i].uuid+"\">"+data[i].uuid+"</a></td><td>"+data[i].desc+"</td></tr>";
$("#wftable").append(tdata);
$("#to_modal"+i).click(function(e) {
e.preventDefault();
Expand Down
2 changes: 2 additions & 0 deletions bips/workflows/base.py
Expand Up @@ -82,6 +82,8 @@ class MetaWorkflow(HasStrictTraits):
config_ui = traits.Function
# config view
config_view = traits.Function
#html_config view
html_view = traits.Function
# purl to describe workflow
url = traits.Str()
# keyword tags for the workflow
Expand Down
Expand Up @@ -13,11 +13,12 @@ def fsl_getmask(name):
inputspec = pe.Node(niu.IdentityInterface(fields=['functional','structural']),name='inputspec')
bet = pe.Node(fsl.BET(mask=True,remove_eyes=True),name='bet')
flirt = pe.Node(fsl.FLIRT(dof=6),name='flirt')
flirt_inv = flirt.clone('func2struct')
applyxfm_mask = pe.Node(fsl.ApplyXfm(interp='nearestneighbour',apply_xfm=True),name='applyxfm_mask')
applyxfm_seg = pe.MapNode(fsl.ApplyXfm(interp='nearestneighbour',apply_xfm=True),name='applyxfm_seg',iterfield=['in_file'])
dilate = pe.Node(fsl.DilateImage(operation='mean'),name='dilate')
fast = pe.Node(fsl.FAST(),name='fast')
outputspec= pe.Node(niu.IdentityInterface(fields=['mask','reg_file','segments','warped_struct']),name='outputspec')
outputspec= pe.Node(niu.IdentityInterface(fields=['mask','reg_file','segments','warped_struct','bet_struct','inverse_reg']),name='outputspec')

#create brain mask
wf.connect(inputspec,"structural",bet,"in_file")
Expand All @@ -28,6 +29,12 @@ def fsl_getmask(name):
wf.connect(flirt,'out_matrix_file',outputspec,'reg_file')
wf.connect(flirt,'out_file',outputspec,'warped_struct')

# Calculate inverse

wf.connect(inputspec,"functional",flirt_inv,"in_file")
wf.connect(inputspec,"structural",flirt_inv,"reference")
wf.connect(flirt_inv,"out_matrix_file",outputspec,"inverse_reg")

#dilate brain mask
wf.connect(bet,"mask_file",dilate,"in_file")

Expand All @@ -39,6 +46,7 @@ def fsl_getmask(name):

#segment with FAST
wf.connect(bet,"out_file", fast,"in_files")
wf.connect(bet,"out_file", outputspec,"bet_struct")

#transform segments
wf.connect(fast,"tissue_class_map",applyxfm_seg,"in_file")
Expand Down
4 changes: 4 additions & 0 deletions bips/workflows/workflow31.py
Expand Up @@ -296,6 +296,10 @@ def prep_workflow(c=create_config()):
sinkd, 'preproc.flirtreg')
modelflow.connect(preproc, 'mask_segment_register.outputspec.warped_struct',
sinkd, 'preproc.flirtreg.@flirtstruct')
modelflow.connect(preproc, 'mask_segment_register.outputspec.bet_struct',
sinkd, 'bet')
modelflow.connect(preproc, 'mask_segment_register.outputspec.inverse_reg',
sinkd, 'flirtreg.func2struct')
modelflow.connect(preproc, 'outputspec.highpassed_files',
sinkd, 'preproc.highpass')
modelflow.connect(preproc, 'outputspec.tsnr_file',
Expand Down

0 comments on commit e92fe9e

Please sign in to comment.