Skip to content

Commit

Permalink
added curvature properties to view_props so they can be set w/javascr…
Browse files Browse the repository at this point in the history
…ipt handle (#308)

Can now set curvature parameters (brightness, contrast, smoothness), by calling e.g.:
handle = cortex.webgl.show(volume)
handle._set_view(**{'surface.{subject}.curvature.brightness':0.3})
  • Loading branch information
ctseng12 authored and marklescroart committed Jan 10, 2019
1 parent 3b03bfe commit 12d0565
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions cortex/webgl/view.py
Expand Up @@ -45,7 +45,7 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"
html_embed=True, overlays_visible=('rois', 'sulci'), labels_visible=('rois', ), html_embed=True, overlays_visible=('rois', 'sulci'), labels_visible=('rois', ),
overlay_file=None, copy_ctmfiles=True, title='Brain', **kwargs): overlay_file=None, copy_ctmfiles=True, title='Brain', **kwargs):
""" """
Creates a static webGL MRI viewer in your filesystem so that it can easily Creates a static webGL MRI viewer in your filesystem so that it can easily
be posted publically for sharing or just saved for later viewing. be posted publically for sharing or just saved for later viewing.
Parameters Parameters
Expand All @@ -68,7 +68,7 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"
Overlays availble in the viewer. If None, then all overlay layers of the Overlays availble in the viewer. If None, then all overlay layers of the
svg file will be potentially available in the viewer (whether initially svg file will be potentially available in the viewer (whether initially
visible or not). This provides the option to include, e.g., only a subset visible or not). This provides the option to include, e.g., only a subset
of layers for a given static viewer. of layers for a given static viewer.
overlays_visible : tuple, optional overlays_visible : tuple, optional
The listed overlay layers will be set visible by default. Layers not listed The listed overlay layers will be set visible by default. Layers not listed
here will be hidden by default (but can be enabled in the viewer GUI). here will be hidden by default (but can be enabled in the viewer GUI).
Expand Down Expand Up @@ -108,7 +108,7 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"
You will need a real web server to view this, since `file://` paths You will need a real web server to view this, since `file://` paths
don't handle xsrf correctly don't handle xsrf correctly
""" """

outpath = os.path.abspath(os.path.expanduser(outpath)) # To handle ~ expansion outpath = os.path.abspath(os.path.expanduser(outpath)) # To handle ~ expansion
if not os.path.exists(outpath): if not os.path.exists(outpath):
os.makedirs(outpath) os.makedirs(outpath)
Expand All @@ -126,7 +126,7 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"
package = Package(data) package = Package(data)
subjects = list(package.subjects) subjects = list(package.subjects)


ctmargs = dict(method='mg2', level=9, recache=recache, external_svg=overlay_file, ctmargs = dict(method='mg2', level=9, recache=recache, external_svg=overlay_file,
overlays_available=overlays_available) overlays_available=overlays_available)
ctms = dict((subj, utils.get_ctmpack(subj, types, **ctmargs)) ctms = dict((subj, utils.get_ctmpack(subj, types, **ctmargs))
for subj in subjects) for subj in subjects)
Expand Down Expand Up @@ -210,7 +210,7 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"
my_viewopts['brightness'] = options.config.get('curvature', 'brightness') my_viewopts['brightness'] = options.config.get('curvature', 'brightness')
my_viewopts['smoothness'] = options.config.get('curvature', 'webgl_smooth') my_viewopts['smoothness'] = options.config.get('curvature', 'webgl_smooth')
my_viewopts['contrast'] = options.config.get('curvature', 'contrast') my_viewopts['contrast'] = options.config.get('curvature', 'contrast')

for sec in options.config.sections(): for sec in options.config.sections():
if 'paths' in sec or 'labels' in sec: if 'paths' in sec or 'labels' in sec:
my_viewopts[sec] = dict(options.config.items(sec)) my_viewopts[sec] = dict(options.config.items(sec))
Expand All @@ -235,8 +235,8 @@ def make_static(outpath, data, types=("inflated",), recache=False, cmap="RdBu_r"


def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None, def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None,
autoclose=True, open_browser=True, port=None, pickerfun=None, autoclose=True, open_browser=True, port=None, pickerfun=None,
template="mixer.html", overlays_available=None, template="mixer.html", overlays_available=None,
overlays_visible=('rois', 'sulci'), labels_visible=('rois', ), overlays_visible=('rois', 'sulci'), labels_visible=('rois', ),
overlay_file=None, title='Brain', **kwargs): overlay_file=None, title='Brain', **kwargs):
""" """
Creates a webGL MRI viewer that is dynamically served by a tornado server Creates a webGL MRI viewer that is dynamically served by a tornado server
Expand All @@ -250,7 +250,7 @@ def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None,
dictionary of Volume, Vertex. etc. objects. dictionary of Volume, Vertex. etc. objects.
autoclose : bool, optional autoclose : bool, optional
If True, the tornado server will automatically be destroyed when the last If True, the tornado server will automatically be destroyed when the last
web client has disconnected. If False, the server will stay open, web client has disconnected. If False, the server will stay open,
allowing more connections. Default True allowing more connections. Default True
open_browser : bool, optional open_browser : bool, optional
If True, uses the webbrowser library to open the viewer in the default If True, uses the webbrowser library to open the viewer in the default
Expand All @@ -260,7 +260,7 @@ def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None,
selected from the range 1024-65536. Default None selected from the range 1024-65536. Default None
pickerfun : funcion or None, optional pickerfun : funcion or None, optional
Should be a function that takes two arguments, a voxel index and a vertex Should be a function that takes two arguments, a voxel index and a vertex
index. Is called whenever a location on the surface is clicked in the index. Is called whenever a location on the surface is clicked in the
viewer. This can be used to print information about individual voxels or viewer. This can be used to print information about individual voxels or
vertices, plot receptive fields, or many other uses. Default None vertices, plot receptive fields, or many other uses. Default None
recache : bool, optional recache : bool, optional
Expand Down Expand Up @@ -296,7 +296,7 @@ def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None,
The layout of the viewer subwindows for showing multiple subjects. The layout of the viewer subwindows for showing multiple subjects.
Default None, which selects the layout based on the number of subjects. Default None, which selects the layout based on the number of subjects.
""" """

data = dataset.normalize(data) data = dataset.normalize(data)
if not isinstance(data, dataset.Dataset): if not isinstance(data, dataset.Dataset):
data = dataset.Dataset(data=data) data = dataset.Dataset(data=data)
Expand All @@ -316,7 +316,7 @@ def show(data, types=("inflated", ), recache=False, cmap='RdBu_r', layout=None,
images = package.images images = package.images
subjects = list(package.subjects) subjects = list(package.subjects)


ctmargs = dict(method='mg2', level=9, recache=recache, ctmargs = dict(method='mg2', level=9, recache=recache,
external_svg=overlay_file, overlays_available=overlays_available) external_svg=overlay_file, overlays_available=overlays_available)
ctms = dict((subj, utils.get_ctmpack(subj, types, **ctmargs)) ctms = dict((subj, utils.get_ctmpack(subj, types, **ctmargs))
for subj in subjects) for subj in subjects)
Expand Down Expand Up @@ -457,13 +457,16 @@ def view_props(self):
_subject = list(self.ui.surface._folders.attrs.keys())[0] _subject = list(self.ui.surface._folders.attrs.keys())[0]
_surface = getattr(self.ui.surface, _subject) _surface = getattr(self.ui.surface, _subject)
_surface_props = ['surface.{subject}.%s'%k for k in _surface._controls.attrs.keys()] _surface_props = ['surface.{subject}.%s'%k for k in _surface._controls.attrs.keys()]
_curvature_props = ['surface.{subject}.curvature.brightness',
'surface.{subject}.curvature.contrast',
'surface.{subject}.curvature.smoothness']
#view_props = _camera_props + _surface_props #view_props = _camera_props + _surface_props
return _camera_props + _surface_props return _camera_props + _surface_props + _curvature_props
#['camera.altitude', 'camera.azimuth', 'camera.target', 'camera.radius', #['camera.altitude', 'camera.azimuth', 'camera.target', 'camera.radius',
#'surface.{subject}.unfold', 'surface.{subject}.pivot', 'surface.{subject}.depth', #'surface.{subject}.unfold', 'surface.{subject}.pivot', 'surface.{subject}.depth',
#'surface.{subject}.shift', 'surface.{subject}.left', 'surface.{subject}.right'] #'surface.{subject}.shift', 'surface.{subject}.left', 'surface.{subject}.right']
#'surface.{subject}.specularity', 'frame', 'bg_alpha' #'surface.{subject}.specularity', 'frame', 'bg_alpha'
#'visL', 'visR', 'alpha', 'rotationR', 'rotationL', 'projection', #'visL', 'visR', 'alpha', 'rotationR', 'rotationL', 'projection',
#'volume_vis', 'frame', 'slices'] #'volume_vis', 'frame', 'slices']


def _set_view(self, **kwargs): def _set_view(self, **kwargs):
Expand Down Expand Up @@ -516,7 +519,7 @@ def _capture_view(self, time=None):
try: try:
view[p] = self.ui.get(p.format(subject=subject) if '{subject}' in p else p)[0] view[p] = self.ui.get(p.format(subject=subject) if '{subject}' in p else p)[0]
except Exception as err: except Exception as err:
# TO DO: Fix this hack with an error class in serve.py & catch it here # TO DO: Fix this hack with an error class in serve.py & catch it here
print(err) #msg = "Cannot read property 'undefined'" print(err) #msg = "Cannot read property 'undefined'"
#if err.message[:len(msg)] != msg: #if err.message[:len(msg)] != msg:
# raise err # raise err
Expand Down Expand Up @@ -688,7 +691,7 @@ def _get_anim_seq(self, keyframes, fps=30, interpolation='linear'):
fr = 0 fr = 0
a = np.array a = np.array
func = mixes[interpolation] func = mixes[interpolation]
skip_props = ['surface.{subject}.right', 'surface.{subject}.left', ] #'projection', skip_props = ['surface.{subject}.right', 'surface.{subject}.left', ] #'projection',
# Get keyframes # Get keyframes
keyframes = sorted(keyframes, key=lambda x:x['time']) keyframes = sorted(keyframes, key=lambda x:x['time'])
# Normalize all time to frame rate # Normalize all time to frame rate
Expand Down

0 comments on commit 12d0565

Please sign in to comment.