def tha_build_callbacks(app): build_step_callback(app, id_tha_slider_steps_value, id_tha_slider_steps, 'Steps') build_init_callback(app, id_tha_modal, id_tha_modal_init_slider, 'Threshold Automata') @app.callback( dp.Output(model_tha['session-tracer'], 'data'), dp.Input(id_tha_dropdown, 'value')) def tracer_callback(value): return [model_tha['id'], value] @app.callback( dp.Output(model_tha['session-actions'], 'data'), dp.Input(id_tha_button_random, 'n_clicks'), dp.Input(id_tha_button_step, 'n_clicks'), dp.Input(id_tha_modal_generate, 'n_clicks'), dp.State(id_tha_modal_init_slider, 'value'), dp.State(id_tha_slider_steps, 'value')) def callback(n1, n2, n3, init, steps): ctx = dash.callback_context if not ctx.triggered: return [] source = ctx.triggered[0]['prop_id'].split('.')[0] args = {'steps': steps, 'init': init} ac = { id_tha_button_random: action_tha_random, id_tha_button_step: action_tha_step, id_tha_modal_generate: action_tha_init, } if source in ac: return [(model_tha['id'], ac[source], args)] print(f'THA callback: Could not find property with source: {source}') raise PreventUpdate()
def build_degroot_callbacks(app): build_step_callback(app, id_degroot_slider_steps_value, id_degroot_slider_steps, 'Steps') build_init_callback(app, id_degroot_modal, id_degroot_modal_init_slider, model_degroot['name']) @app.callback(dp.Output('session-tracer-degroot', 'data'), dp.Input(id_degroot_dropdown, 'value')) def tracer_callback(value): return [model_degroot['id'], value] @app.callback(dp.Output('session-actions-degroot', 'data'), dp.Input(id_degroot_button_random, 'n_clicks'), dp.Input(id_degroot_button_stochastic, 'n_clicks'), dp.Input(id_degroot_button_step, 'n_clicks'), dp.Input(id_degroot_modal_generate, 'n_clicks'), dp.State(id_degroot_modal_init_slider, 'value'), dp.State(id_degroot_slider_steps, 'value')) def callback(n1, n2, n3, n4, init, steps): ctx = dash.callback_context if not ctx.triggered: return [] source = ctx.triggered[0]['prop_id'].split('.')[0] args = {'steps': steps, 'init': init} ac = { id_degroot_button_random: action_degroot_random, id_degroot_button_stochastic: action_degroot_stochastic, id_degroot_button_step: action_degroot_step, id_degroot_modal_generate: action_degroot_init } if source in ac: return [(model_degroot['id'], ac[source], args)] print( f'DeGroot callback: Could not find property with source: {source}') raise PreventUpdate()
def register_app_callbacks(app: dash.Dash) -> None: @app.callback( ddp.Output("editor-euler-solution", "value"), [ddp.Input("select-solution-number", "value")], ) def populate_solution_code(name: str) -> str: if not name: return "" module = sys.modules[__name__] func: tp.Callable = getattr(module, name) code: str = inspect.getsource(func) seen: tp.List[str] = [] root: ast.Module = ast.parse(source=code) for node in ast.walk(node=root): if not isinstance(node, ast.Call): continue if not hasattr(node.func, 'value') or not hasattr( node.func, 'attr'): continue if node.func.attr in seen: continue else: seen.append(node.func.attr) helper_module = getattr(module, node.func.value.id) helper_func = getattr(helper_module, node.func.attr) code += "\n" code += inspect.getsource(helper_func) return code @app.callback( ddp.Output("store-solution-profile", "data"), [ddp.Input("button-solution-profile", "n_clicks")], [ddp.State("select-solution-number", "value")], ) def profile_solution(n_clicks: int, name: str) -> int: if not name: return {} module = sys.modules[__name__] func = getattr(module, name) print(inspect.getsource(func)) with pi.Profiler() as profiler: func() profile_str = profiler.output(renderer=pi.renderers.JSONRenderer( show_all=False)) profile_dict = json.loads(s=profile_str) return profile_dict @app.callback( ddp.Output("graph-solution-profile", "figure"), [ddp.Input("store-solution-profile", "data")], ) def visualize_profile(data: dict) -> int: if not data: return {} root_frame = data.pop("root_frame") return {}
def sir_build_callbacks(app): build_step_callback(app, id_sir_slider_steps_value, id_sir_slider_steps, 'Steps') build_prob_callback(app, id_sir_slider_prob_value, id_sir_slider_prob) build_infection_callback(app, id_sir_slider_itime_value, id_sir_slider_itime) build_init_callback(app, id_sir_modal, id_sir_modal_init_slider, model_sir['name']) @app.callback(dp.Output(model_sir['session-tracer'], 'data'), dp.Input(id_sir_dropdown, 'value')) def tracer_callback(value): return [model_sir['id'], value] @app.callback( dp.Output(model_sir['session-actions'], 'data'), dp.Input(id_sir_button_random, 'n_clicks'), dp.Input(id_sir_button_step, 'n_clicks'), dp.Input(id_sir_button_one, 'n_clicks'), dp.Input(id_sir_modal_generate, 'n_clicks'), dp.State(id_sir_modal_init_slider, 'value'), dp.State(id_sir_slider_steps, 'value'), dp.State(id_sir_slider_prob, 'value'), dp.State(id_sir_slider_itime, 'value'), ) def callback(n1, n2, n3, n4, init, steps, prob, itime): ctx = dash.callback_context if not ctx.triggered: return [] source = ctx.triggered[0]['prop_id'].split('.')[0] args = {'steps': steps, 'prob': prob, 'itime': itime, 'init': init} ac = { id_sir_button_random: action_sir_random, id_sir_button_step: action_sir_step, id_sir_button_one: action_sir_one, id_sir_modal_generate: action_sir_init } if source in ac: return [(model_sir['id'], ac[source], args)] print(f'SIR callback: Could not find property with source: {source}') raise PreventUpdate()
def build_init_callback(app, id_modal, slider_id, text): @app.callback(dp.Output(f'{slider_id}-value', 'children'), dp.Input(f'{slider_id}', 'value')) def slider_update(value): return f'{text} {value}' @app.callback(dp.Output(f'modal-{id_modal}', 'is_open'), dp.Input(f'modal-{id_modal}-open', 'n_clicks'), dp.Input(f'modal-{id_modal}-close', 'n_clicks'), dp.State(f'modal-{id_modal}', 'is_open')) def toggle_modal_init(n1, n2, is_open): if n1 or n2: return not is_open return is_open
def main(): usage = "usage: %prog [options] <sad_hdf5_path>" parser = OptionParser(usage) parser.add_option( "-c", dest="chrom_hdf5", default=False, action="store_true", help="HDF5 files split by chromosome [Default: %default]", ) (options, args) = parser.parse_args() if len(args) != 1: parser.error("Must provide SAD HDF5") else: sad_h5_path = args[0] ############################################# # precursors print("Preparing data...", end="", flush=True) sad5 = ChrSAD5(sad_h5_path, index_chr=True) print("DONE.", flush=True) ############################################# # layout app = dash.Dash() app.css.append_css( {"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) app.layout = html.Div([ html.Div( [ html.H1("Basenji SNP activity difference"), dcc.Markdown("Instructions..."), html.Div( [ html.Label("Datasets"), dcc.Dropdown( id="dataset", options=[ { "label": "CAGE", "value": "CAGE" }, { "label": "DNase", "value": "DNASE" }, { "label": "H3K4me3", "value": "CHIP:H3K4me3" }, { "label": "All", "value": "All" }, ], value="CAGE", ), ], style={ "width": "250", "display": "inline-block" }, ), html.Div( [ html.Label("Population"), dcc.Dropdown( id="population", options=[ { "label": "-", "value": "-" }, { "label": "1kG African", "value": "AFR" }, { "label": "1kG American", "value": "AMR" }, { "label": "1kG East Asian", "value": "EAS" }, { "label": "1kG European", "value": "EUR" }, { "label": "1kG South Asian", "value": "SAS" }, ], value="EUR", ), ], style={ "width": "250", "display": "inline-block" }, ), html.Div( [ html.Label("SNP ID"), dcc.Input(id="snp_id", value="rs6656401", type="text"), html.Button( id="snp_submit", n_clicks=0, children="Submit"), ], style={ "display": "inline-block", "float": "right" }, ), ], style={ "borderBottom": "thin lightgrey solid", "backgroundColor": "rgb(250, 250, 250)", "padding": "10px 5px", }, ), dcc.Graph(id="assoc_plot"), html.Div([ dt.DataTable( id="table", rows=[], columns=[ "SNP", "Association", "Score", "ScoreQ", "R", "Experiment", "Description", ], column_widths=[150, 125, 125, 125, 125, 200], editable=False, filterable=True, sortable=True, resizable=True, sortColumn="Association", row_selectable=True, selected_row_indices=[], max_rows_in_viewport=20, ) ]), ]) ############################################# # callback helpers @memoized def query_ld(population, snp_id): try: sad5.set_population(population) except ValueError: print("Population unavailable.", file=sys.stderr) return pd.DataFrame() chrm, snp_i = sad5.snp_chr_index(snp_id) pos = sad5.snp_pos(snp_i, chrm) if chrm is None: return pd.DataFrame() else: return sad5.emerald_vcf.query_ld(snp_id, chrm, pos, ld_threshold=0.8) @memoized def read_sad(chrm, snp_i, verbose=True): """Read SAD scores from HDF5 for the given SNP index.""" if verbose: print("Reading SAD!", file=sys.stderr) # read SAD snp_sad = sad5.chr_sad5[chrm][snp_i].astype("float64") # read percentiles snp_pct = sad5.chr_sad5[chrm].sad_pct(snp_sad) return snp_sad, snp_pct def snp_rows(snp_id, dataset, ld_r=1.0, verbose=True): """Construct table rows for the given SNP id and its LD set in the given dataset.""" rows = [] # search for SNP # chrom, snp_i = snp_indexes.get(snp_id, (None,None)) chrm, snp_i = sad5.snp_chr_index(snp_id) if chrm is not None: # SAD snp_sad, snp_pct = read_sad(chrm, snp_i) # round floats snp_sad = np.around(snp_sad, 4) snp_assoc = np.around(snp_sad * ld_r, 4) ld_r_round = np.around(ld_r, 4) # extract target scores and info for ti, tid in enumerate(sad5.target_ids): if dataset == "All" or sad5.target_labels[ti].startswith( dataset): rows.append({ "SNP": snp_id, "Association": snp_assoc[ti], "Score": snp_sad[ti], "ScoreQ": snp_pct[ti], "R": ld_r_round, "Experiment": tid, "Description": sad5.target_labels[ti], }) elif verbose: print("Cannot find %s in snp_indexes." % snp_id) return rows def make_data_mask(dataset): """Make a mask across targets for the given dataset.""" dataset_mask = [] for ti, tid in enumerate(sad5.target_ids): if dataset == "All": dataset_mask.append(True) else: dataset_mask.append(sad5.target_labels[ti].startswith(dataset)) return np.array(dataset_mask, dtype="bool") ############################################# # callbacks @app.callback( dd.Output("table", "rows"), [dd.Input("snp_submit", "n_clicks")], [ dd.State("snp_id", "value"), dd.State("dataset", "value"), dd.State("population", "value"), ], ) def update_table(n_clicks, snp_id, dataset, population, verbose=True): """Update the table with a new parameter set.""" if verbose: print("Tabling") # look up SNP index chrm, snp_i = sad5.snp_chr_index(snp_id) # look up position pos = sad5.snp_pos(snp_i, chrm) # set population try: sad5.set_population(population) except ValueError: print("Population unavailable.", file=sys.stderr) # retrieve scores and LD snp_ldscores, df_ld, snps_scores = sad5.retrieve_snp(snp_id, chrm, pos, ld_t=0.5) # construct rows rows = [] # for each SNP for i, v in tqdm(df_ld.iterrows()): # round floats snp_sad = np.around(snps_scores[i], 4) snp_assoc = np.around(snp_sad * v.r, 4) ld_r_round = np.around(v.r, 4) # read percentiles snp_pct = sad5.chr_sad5[chrm].sad_pct(snp_sad) # for each target for ti, tid in enumerate(sad5.target_ids): if dataset == "All" or sad5.target_labels[ti].startswith( dataset): rows.append({ "SNP": v.snp, "Association": snp_assoc[ti], "Score": snp_sad[ti], "ScoreQ": snp_pct[ti], "R": ld_r_round, "Experiment": tid, "Description": sad5.target_labels[ti], }) return rows @app.callback( dd.Output("assoc_plot", "figure"), [dd.Input("snp_submit", "n_clicks")], [ dd.State("snp_id", "value"), dd.State("dataset", "value"), dd.State("population", "value"), ], ) def update_plot(n_clicks, snp_id, dataset, population, verbose=True): if verbose: print("Plotting") target_mask = make_data_mask(dataset) # look up SNP index chrm, snp_i = sad5.snp_chr_index(snp_id) # look up position pos = sad5.snp_pos(snp_i, chrm) # set population try: sad5.set_population(population) except ValueError: print("Population unavailable.", file=sys.stderr) # retrieve scores and LD snp_ldscores, df_ld, snps_scores = sad5.retrieve_snp(snp_id, chrm, pos, ld_t=0.5) # mask snp_ldscores = snp_ldscores[target_mask] # sort sorted_indexes = np.argsort(snp_ldscores) # range ymax = np.abs(snp_ldscores).max() ymax *= 1.2 return { "data": [ go.Scatter( x=np.arange(len(snp_ldscores)), y=snp_ldscores[sorted_indexes], text=sad5.target_ids[target_mask][sorted_indexes], mode="markers", ) ], "layout": { "height": 400, "margin": { "l": 20, "b": 30, "r": 10, "t": 10 }, "yaxis": { "range": [-ymax, ymax] }, "xaxis": { "range": [-1, 1 + len(snp_ldscores)] }, }, } ############################################# # run app.scripts.config.serve_locally = True app.run_server(debug=False, port=8787)
# HTML images accept base64 encoded strings in the same format # that is supplied by the upload html.Img(src=imageToDisplay, id = filename), html.Hr(),], style={ 'width': '60%', 'textAlign': 'center', 'margin': 'auto' }) # callback to save the users image into the session as JSON @app.callback(dd.Output('user-session', 'data'), dd.Output('output-image-upload', 'children'), dd.Input('upload-image', 'contents'), dd.State('upload-image', 'filename')) def update_user_session(list_of_contents, list_of_names): # create an empty list to contin our dictonaries children = [] # loop through the uploaded images and save the image to the users session in a dcc.Store children = [] data = [] if list_of_contents is not None: for content,name in zip(list_of_contents, list_of_names): # save each of the uploaded images and their file names into a dictonary (JSON) data.append({'content':content, 'name':name}) children.append(parse_contents(content, name)) return data, children
import dash.dependencies as dd import numpy as np import dash_html_components as html from . import model as arcsmodel, exp import widget_utils as wu import convolution from .configuration_widget import chopper_freqs, chopper_freq_opts, create from .inelastic import get_data # use common util to create interface and callbacks conv_interface, conv_callback = convolution.create( 'arcs', instrument_params=[ dd.State(component_id='conv-arcs_Ei_input', component_property='value'), dd.State(component_id='conv-arcs_chopper_select', component_property='value'), dd.State(component_id='conv-arcs_chopper_freq', component_property='value'), ], res_function_calculator= get_data, # args for get_data method must match the sequence in instrument_params ) def build_interface(app): config_widget = create("conv-") return html.Div(children=[ config_widget, conv_interface(app),
app.css.append_css( {"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) #app.css.append_css({'external_url': 'https://cdn.rawgit.com/plotly/dash-app-stylesheets/2d266c578d2a6e8850ebce48fdb52759b2aef506/stylesheet-oil-and-gas.css'}) # noqa: E501 app.layout = html.Div(children=[ html.Div([html.Button(id='button', n_clicks=0, children='STARTING...')], style={'color': 'white'}), html.Div([dcc.Graph(id='graph_one', figure={})], style={'display': 'inline-block'}), dcc.Interval(id='live-update', interval=1000), ], style={'background-color': "#F0F0F0"}) @app.callback(dep.Output('graph_one', 'figure'), [], [dep.State('graph_one', 'figure')], [dep.Event('live-update', 'interval')]) def do_plot(figure): df = pd.read_csv('/tmp/mon.csv') plt_w = uj2w(df.time, df.cpu_uj) sys_w = uj2w(df.time, df.sys_uj) * 2 t = df.time - df.time[0] y_data = ( df.v0 / 1e6, df.v1 / 1e6, df.i0 / 1e6, df.i1 / 1e6, df.i0 * df.v0 / 1e12,
dd.Output('image_card', 'src'), dd.Output('solution_written', 'children'), dd.Output('solution', 'value'), dd.Output('image_result', 'src'), dd.Output('image_result', 'style'), dd.Output('rolling_score', 'children'), dd.Output('HIDDEN_DIV', 'children'), ], [ dd.Input('button', 'n_clicks'), dd.Input('solution', 'n_submit'), # soln input box on-click dd.Input('radio_type', 'value'), # problem-type radio button dd.Input('stack_store', 'data') ], # stack stored as dict() [ dd.State('solution', 'value'), # solution input box dd.State('problem_data', 'data'), dd.State('log', 'data'), dd.State('image_card', 'src'), dd.State('switch_gifs', 'on'), dd.State('dropdown_stack', 'value') ]) def mega_callback(n_clicks, n_submit, pType, stack, soln, prob, log, img_src, gifs, stack_dropdown): """ The mega callback function essentially takes any component the gives us an input/state in the app and uses runs the app from start to finsih: 1. Dummy Outputs (for when we bail out early) 2. Check if the problem card/posn needs updating - this could be from the reload buttion, a change in problem type or change of stack 3. Test if the input solution was correct (ignored if ENTER wasn't
def register_app_callbacks(app: dash.Dash) -> None: # Load default data on first tab visit. library, source, func = [(library, source, func) for library, sources in datasets.items() for source, funcs in sources.items() for func in funcs][0] @app.callback( ddp.Output(f"dmi-pivot-{library}-{source}-{func}", "n_clicks"), [ddp.Input("tabs-projects", "value")], [ddp.State(f"dmi-pivot-{library}-{source}-{func}", "n_clicks")], ) def click(tab: str, n_clicks: int) -> int: if tab != "pivot" or n_clicks > 0: raise dex.PreventUpdate return n_clicks + 1 @app.callback( [ ddp.Output("tabulator-pivot-raw", "data"), ddp.Output("tabulator-pivot-raw", "columns"), ], [ ddp.Input(f"dmi-pivot-{library}-{source}-{func}", "n_clicks") for library, sources in datasets.items() for source, funcs in sources.items() for func in funcs ], ) def load_raw_data(*n_clicks: tp.List[str]) -> tp.List[dict]: trigger = dash.callback_context.triggered[0] if not trigger["value"]: raise dex.PreventUpdate comp = trigger["prop_id"].rsplit(".", maxsplit=1)[0] *_, library, source, func = comp.split("-") if library == "plotly": data = getattr(ptd, func)() elif library == "sklearn": output = getattr(skd, func)() if isinstance(output, sku.Bunch): Xdat = output.data if len(Xdat.shape) == 1: Xdat = Xdat[:, np.newaxis] Xcol = output.get("feature_names", range(Xdat.shape[1])) X = dict(zip(Xcol, Xdat.T)) data = pd.DataFrame(X) else: data = pd.DataFrame() records = data.to_dict(orient="records") columns = [{ "title": col, "field": col, "hozAlign": "center", } for col in data.columns] return records, columns @app.callback( ddp.Output("div-pivot-agg", "children"), [ddp.Input("tabulator-pivot-raw", "data")], ) def load_agg_data(records: tp.List[dict]) -> dpv.PivotTable: n = sum(len(col) for col in records[0]) return dpv.PivotTable( id=str(pd.Timestamp.now()), data=records, unusedOrientationCutoff=n + 1, )
if tab == 'register-tab': return make_form('Register') elif tab == 'login-tab': return make_form('Login') # Make form content @app.callback( [ dep.Output('session', 'data'), dep.Output('auth-error', 'children'), dep.Output('hidden-div-for-auth-page-redirect-callback', 'children') ], [dep.Input('button', 'n_clicks')], [ dep.State('authentication-tabs', 'value'), dep.State('session', 'data'), dep.State('input-username', 'value'), dep.State('input-password', 'value'), ] ) def on_click(n_clicks, tab, session, username, password): if n_clicks is None: # prevent the None callbacks is important with the store component. # you don't want to update the store for nothing. raise PreventUpdate if tab == 'register-tab': endpoint = 'auth/register' elif tab == 'login-tab':
def register_app_callbacks(app: dash.Dash) -> None: @app.callback( ddp.Output("button-boids-reset", "n_clicks"), [ddp.Input("tabs-projects", "value")], [ddp.State("button-boids-reset", "n_clicks")], ) def click_reset(tab: str, n_clicks: int) -> int: if tab != "boids" or n_clicks > 0: raise dex.PreventUpdate return n_clicks + 1 @app.callback(ddp.Output("graph-boids-sim", "figure"), [ddp.Input("button-boids-reset", "n_clicks")], [ddp.State("graph-boids-sim", "figure")]) def reset_graph(n_clicks: int, figure: dict) -> dict: dt = 0.3 duration = 1000 * dt ranges = (figure["layout"][axis]["range"] for axis in ["xaxis", "yaxis"]) diameters = map(lambda range: range[-1] - range[0], ranges) radius = 0.5 * min(diameters) initial_boids = BoidSimulation.get_random_boids_state(num_boids=50, scale=0.5) initial_repulsors = BoidSimulation.get_circle_repulsor_state( num_repulsors=100, radius=radius) initial_state = pd.concat(ignore_index=True, objs=[ initial_boids, initial_repulsors, ]) states = BoidSimulation( state=initial_state, seperation=0.3, cohesion=0.6, alignment=0.01, visibility=3, ) figure["frames"] = [{ "name": n, "data": [{ "x": state["px"], "y": state["py"], "mode": "markers", "marker_symbol": np.where( state["vx"].abs().lt(1) & state["vy"].abs().lt(1), "circle", "x", ), }], } for n, state in enumerate(states)] figure["data"] = figure["frames"][0]["data"] button = figure["layout"]["updatemenus"][0]["buttons"][0] slider = figure["layout"]["sliders"][0] button["args"][-1]["frame"]["duration"] = duration slider["transition"]["duration"] = duration slider["step"] = [{ "label": frame["name"], "method": "animate", "args": [[frame["name"]], { "frame": { "duration": duration, "redraw": False }, "mode": "immediate", "transition": { "duration": duration } }], } for frame in figure["frames"]] return figure
go.Heatmap(z=[[matrix[i, j] for j in range(n)] for i in range(n)], colorscale=colorscale) ], 'layout': { 'width': '512', 'height': '512', 'yaxis': { 'autorange': 'reversed' } } } @app.callback(dd.Output('report-output-div', 'children'), [dd.Input('bent-function-filter', 'value')], [dd.State('database-filter', 'value')]) def select_bent_function(bentf_name, selected_database): try: conn = db.connect_to_database(selected_database) except IOError: return ['Cannot connect to database {}.'.format(selected_database)] if bentf_name is None: return [] bentf_c = db.cdb.select_classification_where_name(conn, bentf_name) bentf_path = os.path.join(output_dir, 'download') bentf_c.save_as_csv(bentf_path) with Capturing() as report: bentf_c.report() wc_matrix = bentf_c.weight_class_matrix wc_graph = dcc.Graph(figure=matrix_figure(wc_matrix), id='wc-graph')
if id_ == ID('category'): categories = val return test_table2(categories) @app.callback(dd.Output('app-url', 'search'), [dd.Input('app-url', 'href')]) def reset_url(pathname): 'clear query/search from url' log.debug('resetting path %s', pathname) return '' @app.callback(dd.Output(ID('modal-1'), 'style'), [ dd.Input(ID('modal-close'), 'n_clicks'), dd.Input(ID('modal-text'), 'n_clicks') ], [dd.State(ID('modal-1'), 'style')]) def toggle_modal(n_close, n_modal, style): 'modal close button was clicked, so hide the modal' n_close = 0 if n_close is None else n_close n_modal = 0 if n_modal is None else n_modal clicks = n_close + n_modal style = {'display': 'none'} if clicks > 0 else style return style log.debug('[%s] <- %s', n_close, style) style = {'display': 'none'} if n_close > 0 else style log.debug('[%s] -> %s', n_close, style) # return style if n_close is None: # in case n_clicks was not specified in _layout return style # - this is a no-op (initial callback on load) elif n_close == 0: # same case, but with initial n_clicks=0 in layout return style # - again a no-op
graph = Graph(id=INPID_GRAPH, config=dict(displayModeBar=False), figure=fig) return graph @deferred_callback( dd.Output("scatter-box", "children"), dd.Output("scatter-box", "hidden"), dd.Output(PLOT_ALERT, "children"), dd.Output(PLOT_ALERT, "color"), dd.Output(PLOT_ALERT_BOX, "hidden"), [dd.Input("input-matrix-button", "n_clicks")], [ dd.State(INPID_ZIPCODE, "value"), dd.State(INPID_MAX_DIST, "value"), dd.State(INPID_STATE, "value"), dd.State(INPID_STATE, "options"), SLIDER_STATES["price"], SLIDER_STATES["mileage"], dd.State( ToggleButtonGroup.selector( input=INPID_MMT_REFINE_TRIM, make=ALL, model=ALL), "active", ), dd.State( ToggleButtonGroup.selector( input=INPID_MMT_REFINE_TRIM, make=ALL, model=ALL), "id", ),
def main(): usage = "usage: %prog [options] <sad_hdf5_path>" parser = OptionParser(usage) parser.add_option( "-c", dest="chrom_hdf5", default=False, action="store_true", help="HDF5 files split by chromosome [Default: %default]", ) (options, args) = parser.parse_args() if len(args) != 1: parser.error("Must provide SAD HDF5") else: sad_hdf5_file = args[0] ############################################# # precursors print("Preparing data.", flush=True) chr_sad_h5_open = {} if not options.chrom_hdf5: # open HDF5 sad_h5_open = h5py.File(sad_hdf5_file, "r") # with one file, hash to a fake chromosome chr_sad_h5_open = {1: sad_h5_open} # hash SNP ids to indexes snps = np.array(sad_h5_open["snp"]) snp_indexes = {} for i, snp_id in enumerate(snps): snp_id = snp_id.decode("UTF-8") snp_indexes[snp_id] = (1, i) del snps else: snp_indexes = {} for ci in range(1, 6): # open HDF5 sad_h5_open = h5py.File("%s/chr%d/sad.h5" % (sad_hdf5_file, ci), "r") # with one file, hash to a fake chromosome chr_sad_h5_open[ci] = sad_h5_open # hash SNP ids to indexes snps = np.array(sad_h5_open["snp"]) for i, snp_id in enumerate(snps): snp_id = snp_id.decode("UTF-8") snp_indexes[snp_id] = (ci, i) del snps # open chr1 HDF5 for non-chr specific data sad_h5_open = chr_sad_h5_open[1] # easy access to target information target_ids = np.array( [tl.decode("UTF-8") for tl in sad_h5_open["target_ids"]]) target_labels = np.array( [tl.decode("UTF-8") for tl in sad_h5_open["target_labels"]]) # read SAD percentile indexes into memory sad_pct = np.array(sad_h5_open["SAD_pct"]) # read percentiles percentiles = np.around(sad_h5_open["percentiles"], 3) percentiles = np.append(percentiles, percentiles[-1]) # initialize BigQuery client # client = bigquery.Client('seqnn-170614') pop_emerald = { "EUR": "%s/popgen/1000G/phase3/eur/1000G.EUR.QC" % os.environ["HG19"] } pop_emerald = {} for pop in ["EUR"]: pop_vcf_stem = "%s/popgen/1000G/phase3/%s/1000G.%s.QC" % ( os.environ["HG19"], pop.lower(), pop, ) pop_emerald[pop] = EmeraldVCF(pop_vcf_stem) print("Done.", flush=True) ############################################# # layout app = dash.Dash() app.css.append_css( {"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) app.layout = html.Div([ html.Div( [ html.H1("Basenji SNP activity difference"), dcc.Markdown("Instructions..."), html.Div( [ html.Label("Datasets"), dcc.Dropdown( id="dataset", options=[ { "label": "CAGE", "value": "CAGE" }, { "label": "DNase", "value": "DNASE" }, { "label": "H3K4me3", "value": "CHIP:H3K4me3" }, { "label": "All", "value": "All" }, ], value="CAGE", ), ], style={ "width": "250", "display": "inline-block" }, ), html.Div( [ html.Label("Population"), dcc.Dropdown( id="population", options=[ { "label": "-", "value": "-" }, { "label": "1kG African", "value": "AFR" }, { "label": "1kG American", "value": "AMR" }, { "label": "1kG East Asian", "value": "EAS" }, { "label": "1kG European", "value": "EUR" }, { "label": "1kG South Asian", "value": "SAS" }, ], value="-", ), ], style={ "width": "250", "display": "inline-block" }, ), html.Div( [ html.Label("SNP ID"), dcc.Input(id="snp_id", value="rs2157719", type="text"), html.Button( id="snp_submit", n_clicks=0, children="Submit"), ], style={ "display": "inline-block", "float": "right" }, ), ], style={ "borderBottom": "thin lightgrey solid", "backgroundColor": "rgb(250, 250, 250)", "padding": "10px 5px", }, ), dcc.Graph(id="assoc_plot"), html.Div([ dt.DataTable( id="table", rows=[], columns=[ "SNP", "Association", "Score", "ScoreQ", "R2", "Experiment", "Description", ], column_widths=[150, 125, 125, 125, 125, 200], editable=False, filterable=True, sortable=True, resizable=True, sortColumn="Association", row_selectable=True, selected_row_indices=[], max_rows_in_viewport=20, ) ]), ]) ############################################# # callback helpers @memoized def query_ld_bq(snp_id, population): """Query Google Genomics 1000 Genomes LD table for the given SNP.""" bq_path = "genomics-public-data.linkage_disequilibrium_1000G_phase_3" # construct query query = "SELECT tname, corr" query += " FROM `%s.super_pop_%s`" % (bq_path, population) query += ' WHERE qname = "%s"' % snp_id # run query print("Running a BigQuery!", file=sys.stderr) query_results = client.query(query) return query_results @memoized def query_ld(population, snp_id): if population not in pop_emerald: print("Population unavailable.", file=sys.stderr) return pd.DataFrame() else: chrm, snp_i = snp_indexes.get(snp_id, (None, None)) pos = sad_h5_open["pos"][snp_i] if chrm is None: return pd.DataFrame() else: return pop_emerald[population].query_ld(snp_id, chrm, pos, ld_threshold=0.333) @memoized def read_pos(chrom, snp_i): return chr_sad_h5_open[chrom]["pos"][snp_i] @memoized def read_sad(chrom, snp_i, verbose=True): """Read SAD scores from HDF5 for the given SNP index.""" if verbose: print("Reading SAD!", file=sys.stderr) # read SAD snp_sad = chr_sad_h5_open[chrom]["SAD"][snp_i, :].astype("float64") # compute percentile indexes snp_sadq = [] for ti in range(len(snp_sad)): snp_sadq.append(int(np.searchsorted(sad_pct[ti], snp_sad[ti]))) return snp_sad, snp_sadq def snp_rows(snp_id, dataset, ld_r2=1.0, verbose=True): """Construct table rows for the given SNP id and its LD set in the given dataset.""" rows = [] # search for SNP chrom, snp_i = snp_indexes.get(snp_id, (None, None)) if chrom is not None: # SAD snp_sad, snp_sadq = read_sad(chrom, snp_i) # round floats snp_sad = np.around(snp_sad, 4) snp_assoc = np.around(snp_sad * ld_r2, 4) ld_r2_round = np.around(ld_r2, 4) # extract target scores and info for ti, tid in enumerate(target_ids): if dataset == "All" or target_labels[ti].startswith(dataset): rows.append({ "SNP": snp_id, "Association": snp_assoc[ti], "Score": snp_sad[ti], "ScoreQ": percentiles[snp_sadq[ti]], "R2": ld_r2_round, "Experiment": tid, "Description": target_labels[ti], }) elif verbose: print("Cannot find %s in snp_indexes." % snp_id) return rows def make_data_mask(dataset): """Make a mask across targets for the given dataset.""" dataset_mask = [] for ti, tid in enumerate(target_ids): if dataset == "All": dataset_mask.append(True) else: dataset_mask.append(target_labels[ti].startswith(dataset)) return np.array(dataset_mask, dtype="bool") def snp_scores(snp_id, dataset, ld_r2=1.0): """Compute an array of scores for this SNP in the specified dataset.""" dataset_mask = make_data_mask(dataset) scores = np.zeros(dataset_mask.sum(), dtype="float64") # search for SNP if snp_id in snp_indexes: chrom, snp_i = snp_indexes[snp_id] # read SAD snp_sad, _ = read_sad(chrom, snp_i) # filter datasets snp_sad = snp_sad[dataset_mask] # add scores += snp_sad * ld_r2 return scores ############################################# # callbacks @app.callback( dd.Output("table", "rows"), [dd.Input("snp_submit", "n_clicks")], [ dd.State("snp_id", "value"), dd.State("dataset", "value"), dd.State("population", "value"), ], ) def update_table(n_clicks, snp_id, dataset, population, verbose=True): """Update the table with a new parameter set.""" if verbose: print("Tabling") # add snp_id rows rows = snp_rows(snp_id, dataset) if population != "-": # query_results = query_ld(snp_id, population) # for ld_snp, ld_corr in query_results: # rows += snp_rows(ld_snp, dataset, ld_corr) df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): rows += snp_rows(v.snp, dataset, v.r) return rows @app.callback( dd.Output("assoc_plot", "figure"), [dd.Input("snp_submit", "n_clicks")], [ dd.State("snp_id", "value"), dd.State("dataset", "value"), dd.State("population", "value"), ], ) def update_plot(n_clicks, snp_id, dataset, population, verbose=True): if verbose: print("Plotting") target_mask = make_data_mask(dataset) # add snp_id rows query_scores = snp_scores(snp_id, dataset) if population != "-": # query_results = query_ld(snp_id, population) # for ld_snp, ld_corr in query_results: # query_scores += snp_scores(ld_snp, dataset, ld_corr) df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): query_scores += snp_scores(v.snp, dataset, v.r) # sort sorted_indexes = np.argsort(query_scores) # range ymax = np.abs(query_scores).max() ymax *= 1.2 return { "data": [ go.Scatter( x=np.arange(len(query_scores)), y=query_scores[sorted_indexes], text=target_ids[target_mask][sorted_indexes], mode="markers", ) ], "layout": { "height": 400, "margin": { "l": 20, "b": 30, "r": 10, "t": 10 }, "yaxis": { "range": [-ymax, ymax] }, "xaxis": { "range": [-1, 1 + len(query_scores)] }, }, } ############################################# # run app.scripts.config.serve_locally = True app.run_server(debug=False, port=8787)
INPID_OPTS_TRANS = "input-car-opts-transmission" INPID_OPTS_DRIVETRAIN = "input-car-opts-drivetrain" INPID_OPTS_FUEL = "input-car-opts-fuel-type" INPID_OPTS_BODY = "input-car-opts-body" ALERT_MM_PICKER = "alert-mm-picker" INPID_MM_PICKER = "input-mm-picker" SLIDER_INPUTS = { "year": dd.Input(INPID_YEAR, "value"), "mileage": dd.Input(INPID_MILEAGE, "value"), "price": dd.Input(INPID_PRICE, "value"), "mpg": dd.Input(INPID_MPG, "value"), } SLIDER_STATES = { "year": dd.State(INPID_YEAR, "value"), "mileage": dd.State(INPID_MILEAGE, "value"), "price": dd.State(INPID_PRICE, "value"), "mpg": dd.State(INPID_MPG, "value"), } CAR_OPTS = "car-opts" TOGGLE_BUTTON = "toggle-btn" TOGGLE_BUTTON_DUMMY = "toggle-btn-dummy" TOGGLE_BUTTON_STATE = "toggle-btn-state" TOGGLE_BUTTON_DEFAULT_STATE = "toggle-btn-default-state" TOGGLE_BUTTON_STATE_IX = "toggle-btn-state-ix" TOGGLE_BUTTON_BOX = "toggle-button-box" PLOT_BUTTON = "input-matrix-button" PLOT_ALERT_BOX = "plot-alert-box"
def register_app_callbacks(app:dash.Dash) -> None: @app.callback( ddp.Output("button-geometry-spiral-plot", "n_clicks"), [ddp.Input("tabs-projects", "value")], [ddp.State("button-geometry-spiral-plot", "n_clicks")], ) def click_plot(tab:str, n_clicks:int) -> int: if tab!="geometry" or n_clicks>0: raise dex.PreventUpdate return n_clicks+1 @app.callback( [ ddp.Output("input-geometry-spiral-snum", "value"), ddp.Output("input-geometry-spiral-tmin", "value"), ddp.Output("input-geometry-spiral-tmax", "value"), ddp.Output("input-geometry-spiral-tnum", "value"), ddp.Output("checkbox-geometry-spiral-mode", "value"), ], [ddp.Input("button-geometry-spiral-reset", "n_clicks"),], ) def click_reset(n_clicks:int) -> int: return ( 300, "(1+5**0.5)/2", "1", 50, True, ) @app.callback( ddp.Output("graph-geometry-spiral", "figure"), [ddp.Input("button-geometry-spiral-plot", "n_clicks")], [ ddp.State("graph-geometry-spiral", "figure"), ddp.State("input-geometry-spiral-snum", "value"), ddp.State("input-geometry-spiral-tmin", "value"), ddp.State("input-geometry-spiral-tmax", "value"), ddp.State("input-geometry-spiral-tnum", "value"), ddp.State("checkbox-geometry-spiral-mode", "value"), ], ) def plot_spiral(n_clicks:int, figure:dict, snum:int, tmin:float, tmax:float, tnum:int, lines:bool) -> dict: tmin = eval(tmin, {}, {}) tmax = eval(tmax, {}, {}) tnum = int(tnum) snum = int(snum) mode = "markers+lines" if lines else "markers" rgb = gu.hex_to_rgb(constants.NAVBAR_COLOR) figure["frames"] = [] for t in np.linspace(start=tmin, stop=tmax, num=tnum): mesh = t*2*math.pi*np.linspace(start=1, stop=snum, num=snum) spiral = Spiral(center=Point.origin(), radius=1/snum/t) points = spiral.get_points(mesh) sizes = [5+int(10*i/snum) for i, _ in enumerate(points, 1)] x, y = zip(*points) frame = { "name":f"{t:0.3f}", "data":[{ "x":x, "y":y, "mode":mode, "marker":{"color":"rgba({},{},{},1)".format(*rgb), "size":sizes}, "line":{"color":"rgba({},{},{},0.2)".format(*rgb)}, }], } figure["frames"].append(frame) figure["data"] = figure["frames"][0]["data"] figure["layout"]["sliders"][0]["steps"] = [ { "method":"animate", "label":frame["name"], "args": [ [frame["name"]], { "mode":"immediate", "transition":{"duration":0}, "frame":{"duration":0, "redraw":False}, } ], } for frame in figure["frames"] ] return figure @app.callback( ddp.Output("graph-geometry-polygon", "figure"), [ ddp.Input("button-geometry-polygon-clear", "n_clicks"), ddp.Input("button-geometry-polygon-add", "n_clicks"), ], [ ddp.State("input-geometry-polygon-sides", "value"), ddp.State("graph-geometry-polygon", "figure"), ], ) def add_polygon(clear_clicks:int, add_clicks:int, sides:int, figure:dict) -> dict: trigger = dash.callback_context.triggered[0] if trigger['prop_id'].endswith('clear.n_clicks'): figure['data'].clear() return figure sides = int(sides) polygon = RegularPolygon(sides=sides) trace = polygon.get_trace() figure['data'].append(trace) return figure
def build_callbacks(app): @app.callback( [ dd.Output(component_id='arcs-res_vs_E', component_property='figure'), dd.Output(component_id='arcs-status', component_property='children'), dd.Output('arcs-download-link', 'href'), dd.Output('arcs-summary', 'children'), dd.Output('arcs-pychop-polyfit-python-formula', 'children'), dd.Output('arcs-pychop-polyfit-matlab-formula', 'children'), # convolution widgets dd.Output(conv_widget_factory.excitation_input_id, 'placeholder'), dd.Output(conv_widget_factory.excitation_input_status_id, 'children'), dd.Output(conv_widget_factory.conv_example_plots_id, component_property='children'), dd.Output(conv_widget_factory.plot_widget_id, component_property='children'), dd.Output(conv_widget_factory.IQE_plot_widget_Id, component_property='children'), ], [ dd.Input('arcs-calculate-button', 'n_clicks'), dd.Input('arcs-inel-tabs', 'value'), # convolution widgets dd.Input(conv_widget_factory.tabs_id, 'value'), dd.Input(conv_widget_factory.upload_widget_id, 'contents'), dd.Input(conv_widget_factory.apply_excitations_button_id, 'n_clicks'), dd.Input(conv_widget_factory.phonopy_upload_widget_id, 'contents'), ], # convolution widgets [ dd.State(conv_widget_factory.upload_widget_id, 'filename'), dd.State(conv_widget_factory.upload_widget_id, 'last_modified'), dd.State(conv_widget_factory.phonopy_upload_widget_id, 'filename'), dd.State(conv_widget_factory.phonopy_upload_widget_id, 'last_modified'), dd.State(conv_widget_factory.excitation_input_id, 'value'), dd.State(conv_widget_factory.qgrid_dim_input_id, 'value'), dd.State(conv_widget_factory.Nqsamples, 'value'), dd.State(conv_widget_factory.temperature, 'value'), # instrument configuration dd.State(component_id='arcs_chopper_select', component_property='value'), dd.State(component_id='arcs_chopper_freq', component_property='value'), dd.State(component_id='arcs_Ei_input', component_property='value'), ]) def update_output_div( #inputs calc_btn, output_tab, conv_tab, uploaded_contents, apply_excitation_btn, phonopy_uploaded_contents, # states uploaded_filename, uploaded_last_modified, phonopy_uploaded_filename, phonopy_uploaded_last_modified, excitation_input_text, qgrid_dim, Nqsamples, temperature, chopper_select, chopper_freq, Ei): failed = False status = "" curve = {} downloadlink = '' summary = '' python_formula = '' matlab_formula = '' example_panel_excitation_placeholder = '' excitation_input_status = '' example_panel_plots = '' convplot = '' iqeplot = '' # it is necessary to use try-except clause. otherwise the production website # may cease to work after an exception try: if output_tab in ['summary', 'plot']: # summary and plot summary, python_formula, matlab_formula, curve, downloadlink = update_summary_and_plot( Ei, chopper_select, chopper_freq) else: # convolution if conv_tab == 'I(E)': example_panel_excitation_placeholder, excitation_input_status, example_panel_plots \ = conv_widget_factory.updateExamplePanel( excitation_input_text, Ei, chopper_select, chopper_freq) convplot = conv_widget_factory.createPlotForUploadedData( uploaded_contents, uploaded_filename, uploaded_last_modified, Ei, chopper_select, chopper_freq, ) elif conv_tab == 'I(Q,E)': iqeplot = conv_widget_factory.updateSQEConvolution( phonopy_uploaded_contents, phonopy_uploaded_filename, qgrid_dim, Nqsamples, temperature, Ei, chopper_select, chopper_freq, ) except Exception as e: failed = True status = str(e) ret = ( curve, status, downloadlink, summary, python_formula, matlab_formula, # convolution related example_panel_excitation_placeholder, excitation_input_status, example_panel_plots, convplot, iqeplot) return ret @app.server.route('/download/arcs') def download_csv(): d = {} keys = ['chopper_select', 'chopper_freq', 'Ei'] for k in keys: value = flask.request.args.get(k) try: value = float(value) except: pass d[k] = value E, res = get_data(**d) filename = "arcs_res_{chopper_select}_{chopper_freq}_Ei_{Ei}.csv".format( **d) return wu.send_file(np.array([E, res]).T, filename) return
# Prevent starting a serial connection when something is already active, # including another threaded instance of this function. raise de.PreventUpdate adc.loop_running = True logging.info("Starting acq loop") adc.acquisition_loop() adc.decode_loop() adc.loop_running = False return (f'accumulated status: {adc.accumulated_status}') @app.callback(dd.Output('time-domain-graph', 'figure'), [ dd.Input('accumulated-status', 'children'), dd.Input('show-windowed-button', 'n_clicks'), dd.Input('window-functions', 'value') ], [dd.State('time-domain-graph', 'relayoutData')]) def time_domain_update(status, show_windowed_clicks, window, relayoutData): '''Process the acquired data and display in time domain.''' global sample_index, rms_mag try: magnitude = adc.decoded_data_queue[0] rms_mag = np.sqrt(np.mean((magnitude - np.mean(magnitude))**2)) magnitude -= np.mean(magnitude) # print('magnitude: {}'.format(magnitude)) sample_index = 1 / adc.sample_rate * np.linspace( 0, adc.number_of_samples, num=adc.number_of_samples, endpoint=False) except IndexError: # no data in queue, exit the function without doing anythin
plot_bgcolor="#D0D0D0", paper_bgcolor="#F0F0F0", ))) ], ), dcc.Interval( id='live-update', interval=1000, ), html.Div(id='clear_fig', children=True, style=dict(display='none')) ], style={"background-color": "#F0F0F0"}) @app.callback( dep.Output('graph_one', 'figure'), [], [dep.State('graph_one', 'figure'), dep.State('option_value', 'value')], [dep.Event('live-update', 'interval')]) def update_fig(figure, option_value): data = figure["data"] data[0]['x'].append(time.time()) data[0]['y'].append(sysvar(option_value)) return figure @app.callback(dep.Output('button', 'children'), [dep.Input('live-update', 'interval')]) def update_button_text(interval): if interval == UPDATE_INTERVAL_MSEC: return 'STOP' else:
def register_app_callbacks(app:dash.Dash) -> None: @app.callback( ddp.Output("rubik-button-reset", "n_clicks"), [ddp.Input("tabs-projects", "value")], [ddp.State("rubik-button-reset", "n_clicks")], ) def click_reset(tab:str, n_clicks:int) -> int: if tab != "rubik" or n_clicks > 0: raise dex.PreventUpdate return n_clicks + 1 @app.callback( [ ddp.Output("rubik-select-layer", "options"), ddp.Output("rubik-select-layer", "value"), ddp.Output("rubik-store-state", "data"), ddp.Output("rubik-table-history", "data"), ], [ ddp.Input("rubik-button-clear", "n_clicks"), ddp.Input("rubik-button-reset", "n_clicks"), ddp.Input("rubik-button-scramble", "n_clicks"), ddp.Input("rubik-button-solve", "n_clicks"), ddp.Input("rubik-graph-state", "clickData"), ddp.Input("rubik-table-history", "rowClicked"), ddp.Input("rubik-select-dim", "value"), ], [ ddp.State("rubik-select-layer", "value"), ddp.State("rubik-select-scramble", "value"), ddp.State("rubik-store-state", "data"), ddp.State("rubik-table-history", "data"), ], ) def set_cube_state(*args:list) -> tp.Tuple[object, ...]: trigger = dash.callback_context.triggered[0] if not trigger["value"] or trigger["prop_id"].endswith("clear.n_clicks"): # Clear cube. return constants.EMPTY_OPTIONS, "", [], [], # Unpack arguments and enforce data types. *_, dim, layer, scramble, state, history = args dim = int(dim) layer = int(layer) if layer else 1 scramble = int(scramble) options = [ {"label":f"Rotate {hu.ordinal(layer)} layer", "value":layer} for layer in range(1, 1+dim) ] layer = min(layer, dim) if trigger["prop_id"].endswith("reset.n_clicks") or trigger["prop_id"].endswith("dim.value"): # Load new cube. cube = RubiksCube(dim=dim, state=None) return options, layer, cube.get_state(), [] if trigger["prop_id"].endswith("history.rowClicked"): # Revert cube. i = trigger["value"]["i"] history = [move for move in history if move["i"]<i] cube = RubiksCube(dim=dim, state=None) rotations = [move["move"] for move in history] cube.rotate(rotations=rotations) return options, layer, cube.get_state(), history cube = RubiksCube(dim=dim, state=state) if trigger["prop_id"].endswith("scramble.n_clicks"): # Scramble cube. rotations = cube.scramble(n=scramble) if trigger["prop_id"].endswith("solve.n_clicks"): # Solve cube. rotations = cube.solve() if trigger["prop_id"].endswith("state.clickData"): # Rotate face of cube. faces, axes = zip(*RubiksCube._face_axes.items()) point = trigger["value"]["points"][0] coord = {axis:point[axis] for axis in ["x", "y", "z"]} axis = max(coord.keys(), key=lambda axis:abs(coord[axis])) axis += "+" if coord[axis]>0 else "-" face = list(faces)[list(axes).index(axis)] rotations = f"{layer}{face}" rotations = cube.rotate(rotations=rotations) n = len(history) history.extend({"move":rotation, "i":n+i} for i, rotation in enumerate(rotations)) return options, layer, cube.get_state(), history @app.callback( ddp.Output("rubik-graph-state", "figure"), [ddp.Input("rubik-store-state", "data")], [ddp.State("rubik-select-dim", "value")], ) def graph_cube_state(state:list, dim:str) -> dict: if not state: return empty_cube_figure dim = int(dim) cube = RubiksCube(dim=dim, state=state) figure = cube.get_figure() for trace in figure["data"]: # Disable hover information. trace.update({ "hoverinfo":"none" if trace["type"]=="mesh3d" else "skip", "hovertemplate":"", "name":None, }) figure["layout"].update({ **empty_cube_figure["layout"], # Remove center annotation. "annotations":empty_cube_figure["layout"]["annotations"][1:], }) return figure @app.callback( [ ddp.Output("rubik-button-scramble", "disabled"), ddp.Output("rubik-button-solve", "disabled"), ], [ddp.Input("rubik-store-state", "data")], [ddp.State("rubik-select-dim", "value")], ) def disable_buttons(state:tp.List[str], dim:str) -> tp.Tuple[bool, bool]: if not state or not dim: return True, True if int(dim) not in RubiksCube._solvable_dims: return False, True return False, False
dcc.Input( id={ 'type': 'modal-gen-input', 'index': idx }, type='number', placeholder='{}'.format(values[2]) ) ]) for idx, values in enumerate(zip(data['args'], data['argtypes'], data['argvals'])) ] @app.callback( dp.Output('modal', 'is_open'), [dp.Input('modal-gen-open', 'n_clicks'), dp.Input('modal-gen-close', 'n_clicks')], [dp.State('modal', 'is_open')]) def toggle_modal(n1, n2, is_open): if n1 or n2: return not is_open return is_open @app.callback( dp.Output('modal-info', 'is_open'), [dp.Input('modal-info-open', 'n_clicks'), dp.Input('modal-info-close', 'n_clicks')], [dp.State('modal-info', 'is_open')]) def toggle_modal_info(n1, n2, is_open): if n1 or n2: return not is_open return is_open
def main(): usage = 'usage: %prog [options] <sad_hdf5_path>' parser = OptionParser(usage) parser.add_option( '-c', dest='chrom_hdf5', default=False, action='store_true', help='HDF5 files split by chromosome [Default: %default]') (options, args) = parser.parse_args() if len(args) != 1: parser.error('Must provide SAD HDF5') else: sad_h5_path = args[0] ############################################# # precursors print('Preparing data...', end='', flush=True) sad5 = ChrSAD5(sad_h5_path, index_chr=True) print('DONE.', flush=True) ############################################# # layout column_widths = [('SNP', 150), ('Association', 125), ('Score', 125), ('ScoreQ', 125), ('R', 125), ('Experiment', 125), ('Description', 200)] scc = [{ 'if': { 'column_id': cw[0] }, 'width': cw[1] } for cw in column_widths] app = dash.Dash(__name__) app.css.append_css( {"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) app.layout = html.Div([ html.Div( [ html.H1('Basenji SNP activity difference'), dcc.Markdown('Instructions...'), html.Div([ html.Label('Datasets'), dcc.Dropdown(id='dataset', options=[{ 'label': 'CAGE', 'value': 'CAGE' }, { 'label': 'DNase', 'value': 'DNASE' }, { 'label': 'H3K4me3', 'value': 'CHIP:H3K4me3' }, { 'label': 'All', 'value': 'All' }], value='CAGE') ], style={ 'width': '250', 'display': 'inline-block' }), html.Div([ html.Label('Population'), dcc.Dropdown(id='population', options=[{ 'label': '-', 'value': '-' }, { 'label': '1kG African', 'value': 'AFR' }, { 'label': '1kG American', 'value': 'AMR' }, { 'label': '1kG East Asian', 'value': 'EAS' }, { 'label': '1kG European', 'value': 'EUR' }, { 'label': '1kG South Asian', 'value': 'SAS' }], value='-') ], style={ 'width': '250', 'display': 'inline-block' }), html.Div([ html.Label('SNP ID'), dcc.Input(id='snp_id', value='rs6656401', type='text'), html.Button(id='snp_submit', n_clicks=0, children='Submit') ], style={ 'display': 'inline-block', 'float': 'right' }) ], style={ 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '10px 5px' }), dcc.Graph(id='assoc_plot'), html.Div([ dt.DataTable(id='table', data=[], columns=[{ 'id': cw[0], 'name': cw[0] } for cw in column_widths], style_cell_conditional=scc, editable=False, filtering=True, sorting=True, n_fixed_rows=20) ]) ]) # html.Div([ # dt.DataTable( # id='table', # data=[], # columns=[cw[0] for cw in column_widths], # style_cell_conditional=scc, # editable=False, # filtering=True, # sorting=True, # n_fixed_rows=20 # ) ############################################# # callback helpers @memoized def query_ld(population, snp_id): try: sad5.set_population(population) except ValueError: print('Population unavailable.', file=sys.stderr) return pd.DataFrame() chrm, snp_i = sad5.snp_chr_index(snp_id) pos = sad5.snp_pos(snp_i, chrm) if chrm is None: return pd.DataFrame() else: return sad5.emerald_vcf.query_ld(snp_id, chrm, pos, ld_threshold=0.8) @memoized def read_sad(chrm, snp_i, verbose=True): """Read SAD scores from HDF5 for the given SNP index.""" if verbose: print('Reading SAD!', file=sys.stderr) # read SAD snp_sad = sad5.chr_sad5[chrm][snp_i].astype('float64') # read percentiles snp_pct = sad5.chr_sad5[chrm].sad_pct(snp_sad) return snp_sad, snp_pct def snp_rows(snp_id, dataset, ld_r2=1., verbose=True): """Construct table rows for the given SNP id and its LD set in the given dataset.""" rows = [] # search for SNP # chrom, snp_i = snp_indexes.get(snp_id, (None,None)) chrm, snp_i = sad5.snp_chr_index(snp_id) if chrm is not None: # SAD snp_sad, snp_pct = read_sad(chrm, snp_i) # round floats snp_sad = np.around(snp_sad, 4) snp_assoc = np.around(snp_sad * ld_r2, 4) ld_r2_round = np.around(ld_r2, 4) # extract target scores and info for ti, tid in enumerate(sad5.target_ids): if dataset == 'All' or sad5.target_labels[ti].startswith( dataset): rows.append({ 'SNP': snp_id, 'Association': snp_assoc[ti], 'Score': snp_sad[ti], 'ScoreQ': snp_pct[ti], 'R': ld_r2_round, 'Experiment': tid, 'Description': sad5.target_labels[ti] }) elif verbose: print('Cannot find %s in snp_indexes.' % snp_id) return rows def make_data_mask(dataset): """Make a mask across targets for the given dataset.""" dataset_mask = [] for ti, tid in enumerate(sad5.target_ids): if dataset == 'All': dataset_mask.append(True) else: dataset_mask.append(sad5.target_labels[ti].startswith(dataset)) return np.array(dataset_mask, dtype='bool') def snp_scores(snp_id, dataset, ld_r2=1.): """Compute an array of scores for this SNP in the specified dataset.""" dataset_mask = make_data_mask(dataset) scores = np.zeros(dataset_mask.sum(), dtype='float64') # search for SNP chrm, snp_i = sad5.snp_chr_index(snp_id) if snp_i is not None: # read SAD snp_sad, _ = read_sad(chrm, snp_i) # filter datasets snp_sad = snp_sad[dataset_mask] # add scores += snp_sad * ld_r2 return scores ############################################# # callbacks @app.callback(dd.Output('table', 'data'), [dd.Input('snp_submit', 'n_clicks')], [ dd.State('snp_id', 'value'), dd.State('dataset', 'value'), dd.State('population', 'value') ]) def update_table(n_clicks, snp_id, dataset, population, verbose=True): """Update the table with a new parameter set.""" if verbose: print('Tabling') # add snp_id rows rows = snp_rows(snp_id, dataset) if population != '-': df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): rows += snp_rows(v.snp, dataset, v.r) return rows @app.callback(dd.Output('assoc_plot', 'figure'), [dd.Input('snp_submit', 'n_clicks')], [ dd.State('snp_id', 'value'), dd.State('dataset', 'value'), dd.State('population', 'value') ]) def update_plot(n_clicks, snp_id, dataset, population, verbose=True): if verbose: print('Plotting') target_mask = make_data_mask(dataset) # add snp_id rows query_scores = snp_scores(snp_id, dataset) if population != '-': df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): query_scores += snp_scores(v.snp, dataset, v.r) # sort sorted_indexes = np.argsort(query_scores) # range ymax = np.abs(query_scores).max() ymax *= 1.2 return { 'data': [ go.Scatter(x=np.arange(len(query_scores)), y=query_scores[sorted_indexes], text=sad5.target_ids[target_mask][sorted_indexes], mode='markers') ], 'layout': { 'height': 400, 'margin': { 'l': 20, 'b': 30, 'r': 10, 't': 10 }, 'yaxis': { 'range': [-ymax, ymax] }, 'xaxis': { 'range': [-1, 1 + len(query_scores)] } } } ############################################# # run app.scripts.config.serve_locally = True app.run_server(debug=False, port=8787)
[], [], [dep.Event('live-update', 'interval')] ) def update_text(): return 'BAT1: {}, {:.2f}V, {:.2f}A, {}%'.format( read('/sys/class/power_supply/BAT1/status'), read('/sys/class/power_supply/BAT1/voltage_now')/1e6, read('/sys/class/power_supply/BAT1/current_now')/1e6, read('/sys/class/power_supply/BAT1/capacity'), ) @app.callback( dep.Output('graph', 'figure'), [], [dep.State('graph', 'figure'), dep.State('time0', 'children')], [dep.Event('live-update', 'interval')]) def update_plot(fig,time0): y_data = [] t0 = time.time() sys0 = read('/sys/class/powercap/intel-rapl:1/energy_uj')/1e6 t0_0 = time.time() pkg0 = read('/sys/class/powercap/intel-rapl:0/energy_uj')/1e6 t0_1 = time.time() core0 = read('/sys/class/powercap/intel-rapl:0:0/energy_uj')/1e6
def main(): usage = 'usage: %prog [options] <sad_hdf5_path>' parser = OptionParser(usage) parser.add_option( '-c', dest='chrom_hdf5', default=False, action='store_true', help='HDF5 files split by chromosome [Default: %default]') (options, args) = parser.parse_args() if len(args) != 1: parser.error('Must provide SAD HDF5') else: sad_hdf5_file = args[0] ############################################# # precursors print('Preparing data.', flush=True) chr_sad_h5_open = {} if not options.chrom_hdf5: # open HDF5 sad_h5_open = h5py.File(sad_hdf5_file, 'r') # with one file, hash to a fake chromosome chr_sad_h5_open = {1: sad_h5_open} # hash SNP ids to indexes snps = np.array(sad_h5_open['snp']) snp_indexes = {} for i, snp_id in enumerate(snps): snp_id = snp_id.decode('UTF-8') snp_indexes[snp_id] = (1, i) del snps else: snp_indexes = {} for ci in range(1, 6): # open HDF5 sad_h5_open = h5py.File('%s/chr%d/sad.h5' % (sad_hdf5_file, ci), 'r') # with one file, hash to a fake chromosome chr_sad_h5_open[ci] = sad_h5_open # hash SNP ids to indexes snps = np.array(sad_h5_open['snp']) for i, snp_id in enumerate(snps): snp_id = snp_id.decode('UTF-8') snp_indexes[snp_id] = (ci, i) del snps # open chr1 HDF5 for non-chr specific data sad_h5_open = chr_sad_h5_open[1] # easy access to target information target_ids = np.array( [tl.decode('UTF-8') for tl in sad_h5_open['target_ids']]) target_labels = np.array( [tl.decode('UTF-8') for tl in sad_h5_open['target_labels']]) # read SAD percentile indexes into memory sad_pct = np.array(sad_h5_open['SAD_pct']) # read percentiles percentiles = np.around(sad_h5_open['percentiles'], 3) percentiles = np.append(percentiles, percentiles[-1]) # initialize BigQuery client # client = bigquery.Client('seqnn-170614') pop_emerald = { 'EUR': '%s/popgen/1000G/phase3/eur/1000G.EUR.QC' % os.environ['HG19'] } pop_emerald = {} for pop in ['EUR']: pop_vcf_stem = '%s/popgen/1000G/phase3/%s/1000G.%s.QC' % ( os.environ['HG19'], pop.lower(), pop) pop_emerald[pop] = EmeraldVCF(pop_vcf_stem) print('Done.', flush=True) ############################################# # layout app = dash.Dash() app.css.append_css( {"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) app.layout = html.Div([ html.Div( [ html.H1('Basenji SNP activity difference'), dcc.Markdown('Instructions...'), html.Div([ html.Label('Datasets'), dcc.Dropdown(id='dataset', options=[{ 'label': 'CAGE', 'value': 'CAGE' }, { 'label': 'DNase', 'value': 'DNASE' }, { 'label': 'H3K4me3', 'value': 'CHIP:H3K4me3' }, { 'label': 'All', 'value': 'All' }], value='CAGE') ], style={ 'width': '250', 'display': 'inline-block' }), html.Div([ html.Label('Population'), dcc.Dropdown(id='population', options=[{ 'label': '-', 'value': '-' }, { 'label': '1kG African', 'value': 'AFR' }, { 'label': '1kG American', 'value': 'AMR' }, { 'label': '1kG East Asian', 'value': 'EAS' }, { 'label': '1kG European', 'value': 'EUR' }, { 'label': '1kG South Asian', 'value': 'SAS' }], value='-') ], style={ 'width': '250', 'display': 'inline-block' }), html.Div([ html.Label('SNP ID'), dcc.Input(id='snp_id', value='rs2157719', type='text'), html.Button(id='snp_submit', n_clicks=0, children='Submit') ], style={ 'display': 'inline-block', 'float': 'right' }) ], style={ 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '10px 5px' }), dcc.Graph(id='assoc_plot'), html.Div([ dt.DataTable(id='table', rows=[], columns=[ 'SNP', 'Association', 'Score', 'ScoreQ', 'R2', 'Experiment', 'Description' ], column_widths=[150, 125, 125, 125, 125, 200], editable=False, filterable=True, sortable=True, resizable=True, sortColumn='Association', row_selectable=True, selected_row_indices=[], max_rows_in_viewport=20) ]) ]) ############################################# # callback helpers @memoized def query_ld_bq(snp_id, population): """Query Google Genomics 1000 Genomes LD table for the given SNP.""" bq_path = 'genomics-public-data.linkage_disequilibrium_1000G_phase_3' # construct query query = 'SELECT tname, corr' query += ' FROM `%s.super_pop_%s`' % (bq_path, population) query += ' WHERE qname = "%s"' % snp_id # run query print('Running a BigQuery!', file=sys.stderr) query_results = client.query(query) return query_results @memoized def query_ld(population, snp_id): if population not in pop_emerald: print('Population unavailable.', file=sys.stderr) return pd.DataFrame() else: chrm, snp_i = snp_indexes.get(snp_id, (None, None)) pos = sad_h5_open['pos'][snp_i] if chrm is None: return pd.DataFrame() else: return pop_emerald[population].query_ld(snp_id, chrm, pos, ld_threshold=0.333) @memoized def read_pos(chrom, snp_i): return chr_sad_h5_open[chrom]['pos'][snp_i] @memoized def read_sad(chrom, snp_i, verbose=True): """Read SAD scores from HDF5 for the given SNP index.""" if verbose: print('Reading SAD!', file=sys.stderr) # read SAD snp_sad = chr_sad_h5_open[chrom]['SAD'][snp_i, :].astype('float64') # compute percentile indexes snp_sadq = [] for ti in range(len(snp_sad)): snp_sadq.append(int(np.searchsorted(sad_pct[ti], snp_sad[ti]))) return snp_sad, snp_sadq def snp_rows(snp_id, dataset, ld_r2=1., verbose=True): """Construct table rows for the given SNP id and its LD set in the given dataset.""" rows = [] # search for SNP chrom, snp_i = snp_indexes.get(snp_id, (None, None)) if chrom is not None: # SAD snp_sad, snp_sadq = read_sad(chrom, snp_i) # round floats snp_sad = np.around(snp_sad, 4) snp_assoc = np.around(snp_sad * ld_r2, 4) ld_r2_round = np.around(ld_r2, 4) # extract target scores and info for ti, tid in enumerate(target_ids): if dataset == 'All' or target_labels[ti].startswith(dataset): rows.append({ 'SNP': snp_id, 'Association': snp_assoc[ti], 'Score': snp_sad[ti], 'ScoreQ': percentiles[snp_sadq[ti]], 'R2': ld_r2_round, 'Experiment': tid, 'Description': target_labels[ti] }) elif verbose: print('Cannot find %s in snp_indexes.' % snp_id) return rows def make_data_mask(dataset): """Make a mask across targets for the given dataset.""" dataset_mask = [] for ti, tid in enumerate(target_ids): if dataset == 'All': dataset_mask.append(True) else: dataset_mask.append(target_labels[ti].startswith(dataset)) return np.array(dataset_mask, dtype='bool') def snp_scores(snp_id, dataset, ld_r2=1.): """Compute an array of scores for this SNP in the specified dataset.""" dataset_mask = make_data_mask(dataset) scores = np.zeros(dataset_mask.sum(), dtype='float64') # search for SNP if snp_id in snp_indexes: chrom, snp_i = snp_indexes[snp_id] # read SAD snp_sad, _ = read_sad(chrom, snp_i) # filter datasets snp_sad = snp_sad[dataset_mask] # add scores += snp_sad * ld_r2 return scores ############################################# # callbacks @app.callback(dd.Output('table', 'rows'), [dd.Input('snp_submit', 'n_clicks')], [ dd.State('snp_id', 'value'), dd.State('dataset', 'value'), dd.State('population', 'value') ]) def update_table(n_clicks, snp_id, dataset, population, verbose=True): """Update the table with a new parameter set.""" if verbose: print('Tabling') # add snp_id rows rows = snp_rows(snp_id, dataset) if population != '-': # query_results = query_ld(snp_id, population) # for ld_snp, ld_corr in query_results: # rows += snp_rows(ld_snp, dataset, ld_corr) df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): rows += snp_rows(v.snp, dataset, v.r) return rows @app.callback(dd.Output('assoc_plot', 'figure'), [dd.Input('snp_submit', 'n_clicks')], [ dd.State('snp_id', 'value'), dd.State('dataset', 'value'), dd.State('population', 'value') ]) def update_plot(n_clicks, snp_id, dataset, population, verbose=True): if verbose: print('Plotting') target_mask = make_data_mask(dataset) # add snp_id rows query_scores = snp_scores(snp_id, dataset) if population != '-': # query_results = query_ld(snp_id, population) # for ld_snp, ld_corr in query_results: # query_scores += snp_scores(ld_snp, dataset, ld_corr) df_ld = query_ld(population, snp_id) for i, v in df_ld.iterrows(): query_scores += snp_scores(v.snp, dataset, v.r) # sort sorted_indexes = np.argsort(query_scores) # range ymax = np.abs(query_scores).max() ymax *= 1.2 return { 'data': [ go.Scatter(x=np.arange(len(query_scores)), y=query_scores[sorted_indexes], text=target_ids[target_mask][sorted_indexes], mode='markers') ], 'layout': { 'height': 400, 'margin': { 'l': 20, 'b': 30, 'r': 10, 't': 10 }, 'yaxis': { 'range': [-ymax, ymax] }, 'xaxis': { 'range': [-1, 1 + len(query_scores)] } } } ############################################# # run app.scripts.config.serve_locally = True app.run_server(debug=False, port=8787)
) ) ] ), dcc.Interval( id='live-update', interval=1000, ) ] ) @app.callback( dep.Output('graph-1', 'figure'), [], [dep.State('path-1', 'value'), dep.State('graph-1', 'figure'), dep.State('button-1', 'n_clicks')], [dep.Event('live-update', 'interval')] ) def update_fig(path, fig, n_clicks): data = fig["data"] if n_clicks%2: data[0]['x'].append(time.time()-time0) data[0]['y'].append(sysvar(path)) else: data[0]['x']=[] data[0]['y']=[] return fig @app.callback(
dash_core.Interval( id="interval-component", interval=1 * 500, # in milliseconds n_intervals=0, ), ])) @app.callback( # type: ignore [ dash_deps.Output("hit-rate-history-graph", "extendData"), dash_deps.Output("virtual-powder-pattern-heatmap", "figure"), ], [dash_deps.Input("interval-component", "n_intervals")], [ dash_deps.State("hit-rate-history-graph", "figure"), dash_deps.State("new_x0", "children"), dash_deps.State("new_x1", "children"), dash_deps.State("new_y0", "children"), dash_deps.State("new_y1", "children"), ], ) def update_hit_plots( _, # type: Any current_hit_rate_plot_figure, # type: Any new_x0, # type: int new_x1, # type: int new_y0, # type: int new_y1, # type: int ): # type: (...) -> Tuple[Any, Any]
]) @app.callback( dependencies.Output('curve', 'figure'), dependencies.Input('slider', 'value'), ) def update_figure(value): global curve, fig fig.update_traces(dict(y=x**float(value)), selector=0) fig.update_layout(title=f'{value:3.1f}') return fig @app.callback( dependencies.Output('save-msg', 'children'), dependencies.Input('save-button', 'n_clicks'), dependencies.State('slider', 'value'), ) def update_database(n_clicks, value): if n_clicks == 0: return '' with open('./data.txt', 'w') as f: f.write(f'>> {value:3.2f}\n') return 'Input has been saved to "./data.txt".' if __name__ == '__main__': app.run_server( host='127.0.0.1', port=9595, debug=True, dev_tools_ui=False, dev_tools_props_check=False,