Commit fc98f7a0 authored by Martin Schorb's avatar Martin Schorb
Browse files

Merge branch 'zoombox' into main

parents b06364bb 31ac6b9c
Pipeline #29628 passed with stage
in 19 seconds
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 18 14:52:17 2021
@author: schorb
"""
import dash
# import dash_core_components as dcc
# import dash_html_components as html
from dash.dependencies import Input, Output, State, MATCH, ALL
from dash.exceptions import PreventUpdate
from app import app
# import params
from utils import helper_functions as hf
for dim in ['X','Y','Z']:
@app.callback([Output({'component': 'start'+dim,'module' : MATCH},'value'),
Output({'component': 'start'+dim,'module' : MATCH},'min'),
Output({'component': 'end'+dim,'module' : MATCH},'value'),
Output({'component': 'end'+dim,'module' : MATCH},'max')],
Input({'component': 'store_stackparams', 'module': MATCH}, 'data')
)
def paramstoouterlimits(thisstore):
if not dash.callback_context.triggered:
raise PreventUpdate
oc = hf.output_components()
dim = oc[0][0][-1]
stackparams = thisstore['stackparams']
minval = stackparams['stats']['stackBounds']['min'+dim]
maxval = stackparams['stats']['stackBounds']['max'+dim]
return minval,minval,maxval,maxval
@app.callback([Output({'component': 'start'+dim,'module' : MATCH},'max'),
Output({'component':'end'+dim,'module' : MATCH},'min')],
[Input({'component': 'start'+dim,'module' : MATCH}, 'value'),
Input({'component':'end'+dim,'module' : MATCH},'value')]
)
def innerlimits(minval,maxval):
return maxval, minval
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 18 14:52:17 2021
@author: schorb
"""
import dash
# import dash_core_components as dcc
# import dash_html_components as html
from dash.dependencies import Input, Output, State, MATCH, ALL
from dash.exceptions import PreventUpdate
from app import app
# import params
from utils import helper_functions as hf
outs = list()
for dim in ['X','Y','Z']:
@app.callback([Output({'component': 'start' + dim, 'module': MATCH}, 'max'),
Output({'component': 'end' + dim, 'module': MATCH}, 'min')],
[Input({'component': 'start' + dim, 'module': MATCH}, 'value'),
Input({'component': 'end' + dim, 'module': MATCH}, 'value')]
)
def innerlimits(minval, maxval):
return maxval, minval
outs.extend([Output({'component': 'start'+dim,'module' : MATCH},'value'),
Output({'component': 'start'+dim,'module' : MATCH},'min'),
Output({'component': 'end'+dim,'module' : MATCH},'value'),
Output({'component': 'end'+dim,'module' : MATCH},'max')])
outs.append(Output({'component': 'sliceim_bboxparams_0', 'module': MATCH}, 'data'))
@app.callback(outs,
[Input({'component': 'sliceim_rectsel_0', 'module': MATCH}, "data")],
State({'component': 'sliceim_params_0', 'module': MATCH}, 'data')
)
def paramstoouterlimits(annotations,imparams):
if not dash.callback_context.triggered:
raise PreventUpdate
out = list()
outdims = dict()
for dim in ['X', 'Y']:
minval = annotations[dim][0]
maxval = annotations[dim][1]
outdims[dim] = [minval,maxval]
out.extend([minval,minval,maxval,maxval])
outdims['Z'] = [imparams['minZ'],imparams['maxZ']]
out.extend([imparams['minZ'],imparams['minZ'],imparams['maxZ'],imparams['maxZ']])
out.append(outdims)
return out
......@@ -15,6 +15,9 @@ from dash.exceptions import PreventUpdate
import requests
import os
import json
import plotly.express as px
from skimage import io
import re
from app import app
......@@ -272,7 +275,7 @@ for idx in range(params.max_tileviews):
out_scale = '%0.2f' %scale
imurl = url +'/jpeg-image?scale=' + out_scale
imurl = url +'/jpeg-image?scale=' + out_scale
if runstore is None or not 'mt_params' in runstore.keys():
scale1 = params.default_tile_scale
......@@ -309,56 +312,181 @@ for idx in range(params.max_tileviews):
raise PreventUpdate
imurl += '&minIntensity=' + str(c_limits[0]) + '&maxIntensity=' + str(c_limits[1])
return imurl
# init slice image display
@app.callback(Output({'component': 'sliceim_image'+idx_str, 'module': MATCH},'src'),
[Input({'component':'sliceim_section_in'+idx_str,'module': MATCH},'value'),
Input({'component': 'store_render_launch', 'module': MATCH},'data'),
Input({'component': 'sliceim_contrastslider'+idx_str, 'module': MATCH},'value')],
@app.callback([Output({'component': 'sliceim_image'+idx_str, 'module': MATCH},'figure'),
Output({'component': 'sliceim_image' + idx_str, 'module': MATCH}, 'config'),
Output({'component': 'sliceim_params' + idx_str, 'module': MATCH}, 'data'),
Output({'component': 'sliceim_image' + idx_str, 'module': MATCH}, "relayoutData")],
[Input({'component': 'sliceim_section_in'+idx_str,'module': MATCH},'value'),
Input({'component': 'slice_zoom', 'module': MATCH},'n_clicks'),
Input({'component': 'slice_reset', 'module': MATCH}, 'n_clicks'),
Input({'component': 'sliceim_contrastslider'+idx_str, 'module': MATCH},'value'),
Input({'component': 'store_stackparams', 'module': MATCH}, 'data')],
[State({'component': 'owner_dd','module': MATCH},'value'),
State({'component': 'project_dd','module': MATCH},'value'),
State({'component': 'stack_dd','module': MATCH},'value'),
State({'component': 'sliceim_params' + idx_str, 'module': MATCH}, 'data'),
State({'component': 'sliceim_bboxparams' + idx_str, 'module': MATCH}, 'data'),
State({'component': 'sliceim_rectsel' + idx_str, 'module': MATCH}, 'data'),
State('url', 'pathname')
],prevent_initial_call=True)
def slice_view(section,runstore,c_limits,owner,project,stack,thispage):
def slice_view(section,zoomclick,resetclick,c_limits,thisstore,owner,project,stack,imparams,bboxparams,rectsel,thispage):
if not dash.callback_context.triggered:
raise PreventUpdate
thispage = thispage.lstrip('/')
if not hf.trigger(key='module') == thispage:
trigger = hf.trigger()
thispage = thispage.lstrip('/')
if thispage == '' or not thispage in hf.trigger(key='module'):
raise PreventUpdate
if None in (section,runstore,owner,project,stack):
if None in (section,owner,project,stack):
raise PreventUpdate
if 'None' in (owner,project,stack):
raise PreventUpdate
if bboxparams == {}:
bboxparams.update(imparams)
scale = imparams['scale']
url = params.render_base_url + params.render_version + 'owner/' + owner + '/project/' + project + '/stack/' + stack
url += '/z/'+ str(section)
url1 = url + '/bounds'
bounds = requests.get(url1).json()
imwidth = bounds['maxX'] - bounds['minX']
scale = float(params.im_width) / float(imwidth)
out_scale = '%0.2f' %scale
imurl = url +'/jpeg-image?scale=' + out_scale
url += '/z/' + str(section)
if 'zoom' in trigger:
if rectsel == {}:
raise PreventUpdate
xmin = rectsel['X'][0]
ymin = rectsel['Y'][0]
width = int(rectsel['X'][1]-rectsel['X'][0])
height = int(rectsel['Y'][1]-rectsel['Y'][0])
bounds=dict()
bounds['minX'] = xmin
bounds['minY'] = ymin
bounds['maxX'] = rectsel['X'][1]
bounds['maxY'] = rectsel['Y'][1]
imparams.update(bounds)
scale = float(params.im_width) / float(width)
scale = round(scale, 4)
out_scale = '%0.4f' % scale
url = url + '/box/' + ','.join(map(str,[xmin,ymin,width,height,scale]))
imurl = url + '/jpeg-image?scale=' + out_scale
elif 'contrast' in trigger:
imurl = imparams['imurl']
elif 'section' in trigger:
imurl = re.sub('/z/[0-9]*','/z/'+str(section),imparams['imurl'])
else:
# bounds = thisstore['stackparams']['stats']['stackBounds']
url1 = url + '/bounds'
bounds = requests.get(url1).json()
imwidth = bounds['maxX'] - bounds['minX']
scale = float(params.im_width) / float(imwidth)
imparams.update(bounds)
imparams['fullbounds']=bounds
scale = round(scale,4)
out_scale = '%0.4f' % scale
imurl = url +'/jpeg-image?scale=' + out_scale
imparams['scale'] = scale
imparams['imurl'] = imurl
imurl += '&minIntensity=' + str(c_limits[0]) + '&maxIntensity=' + str(c_limits[1])
return imurl
try:
img = io.imread(imurl)
except:
fig = px.line()
fig.update_xaxes(showticklabels=False,showgrid=False)
fig.update_yaxes(showticklabels=False,showgrid=False)
fig.add_annotation(x=2, y=2,
text="Stack or slice cannot be found...")
return fig,{},imparams, None
fig = px.imshow(img,binary_string=True)
fig.update_layout(dragmode="drawrect")
fig.update_layout(coloraxis_showscale=False)
fig.update_layout(newshape = dict(opacity=0.3, fillcolor='#EB9',line=dict(color='#053')))
fig.update_layout(height=params.im_width,margin=dict(l=0, r=0, b=0, t=0))
fig.update_xaxes(showticklabels=False,showgrid=False)
fig.update_yaxes(showticklabels=False,showgrid=False)
config = {'responsive':False,
'displaylogo':False,
'modeBarButtons':[['drawrect','eraseshape']],
'showAxisDragHandles':False
}
return fig, config, imparams, None
@app.callback(Output({'component': 'sliceim_rectsel' + idx_str, 'module': MATCH}, 'data'),
Input({'component': 'sliceim_image' + idx_str, 'module': MATCH}, "relayoutData") ,
State({'component': 'sliceim_params' + idx_str, 'module': MATCH}, 'data'),
)
def paramstoouterlimits(annotations, imparams):
if not dash.callback_context.triggered:
raise PreventUpdate
if not 'minX' in imparams.keys():
raise PreventUpdate
outdims = dict()
scale = imparams['scale']
for dim in ['X', 'Y']:
minval = imparams['min' + dim]
maxval = imparams['max' + dim]
if annotations in ([], None):
outdims[dim] = [minval, maxval]
else:
if "shapes" in annotations:
if annotations["shapes"]==[]:
minv = 0
maxv = maxval - minval
scale = 1
else:
last_shape = annotations["shapes"][-1]
minv = int(last_shape[dim.lower() + '0'])
maxv = int(last_shape[dim.lower() + '1'])
elif any(["shapes" in key for key in annotations]):
minv = int([annotations[key] for key in annotations if dim.lower() + '0' in key][0])
maxv = int([annotations[key] for key in annotations if dim.lower() + '1' in key][0])
else:
minv = 0
maxv = maxval - minval
scale = 1
if minv > maxv:
minv, maxv = maxv, minv
offset = minval
minval, maxval = int(minv / scale + offset), int(maxv / scale + offset)
outdims[dim] = [minval, maxval].copy()
return (outdims)
@app.callback(Output({'component': 'lead_tile', 'module': MATCH},'data'),
Input({'component': 'lead_tile_0', 'module': MATCH},'data'))
......
......@@ -65,7 +65,7 @@ page.append(page1)
# ===============================================
slice_view = pages.section_view(module)
slice_view = pages.section_view(module,bbox=True)
page.append(slice_view)
......
......@@ -136,7 +136,7 @@ for dim in ['X','Y','Z']:
bbox0.append(Input({'component': 'end'+dim,'module' : parent},'value'))
stackinput = [Input({'component': 'stack_dd', 'module': parent},'value')]
stackinput = []#Input({'component': 'stack_dd', 'module': parent},'value')]
stackinput.extend(bbox0)
stackinput.append(Input({'component': "path_input", 'module': label},'n_blur'))
stackoutput = [Output({'component': 'path_ext', 'module': label},'data'),
......@@ -153,15 +153,15 @@ stackoutput.extend(compute_tablefields)
stackinput,
[State({'component': 'store_owner', 'module': parent}, 'data'),
State({'component': 'store_project', 'module': parent}, 'data'),
State({'component': 'store_stack', 'module': parent}, 'data'),
State({'component': 'stack_dd', 'module': parent}, 'value'),
State({'component': 'store_allstacks', 'module': parent}, 'data'),
State({'component': "path_input", 'module': label},'value'),
State('url','pathname')]
,prevent_initial_call=True)
def n5export_stacktodir(stack_sel,
def n5export_stacktodir(#stack_sel,
xmin,xmax,ymin,ymax,zmin,zmax,
browsetrig,
owner,project,stack,allstacks,
owner,project,stack_sel,allstacks,
browsedir,
thispage):
......@@ -192,6 +192,7 @@ def n5export_stacktodir(stack_sel,
out['numsections'] = zmax-zmin + 1
url = params.render_base_url + params.render_version + 'owner/' + owner + '/project/' + project + '/stack/' + stack + '/z/'+ str(out['zmin']) +'/render-parameters'
print(url)
tiles0 = requests.get(url).json()
tilefile0 = os.path.abspath(tiles0['tileSpecs'][0]['mipmapLevels']['0']['imageUrl'].strip('file:'))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment