def update_graph(tiff_mode, filename, graph_idx, curr_neuron): background = templates_tiff[graph_idx] if tiff_mode else templates[ graph_idx] if curr_neuron == -1: new_graph = int_func.format_fig(background, title=filename.partition(".")[0], zoom=False, is_tiff_mode=tiff_mode) else: if not tiff_mode: background = np.where( np.logical_and(footprints[graph_idx][curr_neuron] >= 0.01, background != 255), # to keep com dot cols[0], background) new_graph = int_func.format_fig( background, title=filename.partition(".")[0], zoom=True, zoom_ratio=zoom_ratio, center_coords_x=int(coms[graph_idx][curr_neuron][1]), center_coords_y=int(coms[graph_idx][curr_neuron][0]), is_tiff_mode=tiff_mode) return new_graph
def update_graphs(fn0, fn1, fn2, fn3, fn4, fn5, fn6, fn7, fn8, fn9, fn10, fn11, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8, cd9, cd10, cd11, click_save, suggestion_mode, tiff_mode, no_match_update, st0, st1, st2, st3, st4, st5, st6, st7, st8, st9, st10, st11, state_cells_left): fnames = [fn0, fn1, fn2, fn3, fn4, fn5, fn6, fn7, fn8, fn9, fn10, fn11] cdata = [cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8, cd9, cd10, cd11] states = [st0, st1, st2, st3, st4, st5, st6, st7, st8, st9, st10, st11] updates = [no_update] * num_plots_max new_sugg = False cells_left_message = state_cells_left ctx = dash.callback_context reset = no_update global cell_matching_df global templates global orig_templates if ctx.triggered: global current_selected trigger_action = ctx.triggered[0]['prop_id'].split('.')[1] trigger_firstarg = ctx.triggered[0]['prop_id'].split('.')[0] # 1. SAVE BUTTON CLICKED if trigger_action == "n_clicks" and trigger_firstarg == "save_button": print("***callback: SAVE") if not filenames[0]: # no files uploaded and/or nothing highlighted cells_left_message = "upload files first" else: # get index, update cells of matched neurons and recompute best options for other neurons col = cell_matching_df[fnames[0].partition(".")[0]] row_idx = cell_matching_df[col == current_selected[0]].index.values[0] cell_matching_df.at[row_idx, "confirmed"] = 1 for graph_idx, filename in enumerate(filenames): if filename: cell_matching_df.at[row_idx, filename] = current_selected[graph_idx] cell_matching_df.to_csv(UPLOAD_DIRECTORY + "\\" + filename_result_csv, index=False, header=True, sep=';') print("csv saved @ ", UPLOAD_DIRECTORY + "\\" + filename_result_csv) # output number of cells left to match num_cells_left = sum(cell_matching_df["confirmed"] == 0) cells_left_message = str(num_cells_left) + " cells left to confirm" # color neuron in graphs color = cell_matching_df.at[row_idx, "color"] for graph_idx, filename in enumerate(filenames): print(graph_idx) curr_neuron = current_selected[graph_idx] if not filename or curr_neuron == -1: continue print(curr_neuron, color) templates[graph_idx] = np.where( np.logical_and(footprints[graph_idx][curr_neuron] >= 0.01, templates[graph_idx] != 255), cols[color], templates[graph_idx]) updates[graph_idx] = update_graph(tiff_mode, filename, graph_idx, -1) print(cells_left_message) new_sugg = suggestion_mode reset = True # SUGGEST RANDOM NEURON MATCHING if (ctx.triggered[0]['prop_id'] == "suggestion_mode_button.active") or new_sugg: if ctx.triggered[0]['value'] or new_sugg: print("new neuron matching suggested") if isinstance(cell_matching_df, pd.DataFrame): col = cell_matching_df["confirmed"] row_idx = cell_matching_df[col == 0].index.values[0] for graph_idx, filename in enumerate(fnames): if not filename: continue print(filename, fnames) curr_neuron = cell_matching_df.iloc[row_idx][filename.partition(".")[0]] if graph_idx > 0: clf_input = cell_matching_df.iloc[row_idx][filename.partition(".")[0] + 'feature_vals'] if not isinstance(clf_input, list): clf_input = json.loads(clf_input) print('clf_input ', clf_input) curr_neuron = get_predicted_neuron(clf, clf_input[:3]) if isinstance(curr_neuron, list): print("list of tuples ", curr_neuron) curr_neuron = curr_neuron[0][1] print(curr_neuron); current_selected[graph_idx] = curr_neuron updates[graph_idx] = update_graph(tiff_mode, filename, graph_idx, curr_neuron) print(int(coms[graph_idx][curr_neuron][0]), int(coms[graph_idx][curr_neuron][1])) # IMAGE MODE CHANGED elif ctx.triggered[0]['prop_id'] == "tiff_mode_button.active": print("***callback: IMAGE MODE tiff CHANGED to: ", tiff_mode) for graph_idx, filename in enumerate(fnames): if not filename: continue print(filename, fnames, current_selected[graph_idx]) updates[graph_idx] = update_graph(tiff_mode, filename, graph_idx, current_selected[graph_idx]) # NO MATCH BUTTON UPDATED elif ctx.triggered[0]['prop_id'] == "no_match_update_graph.children": print("***callback: GRAPH UPDATED because of NO MATCH BUTTON click: ") for graph_idx, filename in enumerate(fnames): if not filename or not graph_idx: # not ref continue current_selected[graph_idx] = -1 if no_match[graph_idx - 1] else current_selected[graph_idx] updates[graph_idx] = update_graph(tiff_mode, filename, graph_idx, current_selected[graph_idx]) # 2 GRAPH CLICKED elif trigger_action == "clickData": trigger_graph_id = int(trigger_firstarg.rsplit('_', 1)[-1]) print("***callback: IMAGE CLICKED trigger_id: ", trigger_graph_id) click_data = cdata[trigger_graph_id] print(click_data) y = click_data['points'][0]['x'] x = click_data['points'][0]['y'] print("click on something", x, y, fnames[trigger_graph_id], np.amax(pixel_ownerships[trigger_graph_id])) neuron_id = pixel_ownerships[trigger_graph_id][x, y] print("clicked on neuron: ", neuron_id, "trigger graph: ", trigger_graph_id) if neuron_id != -1 and neuron_id != current_selected[trigger_graph_id]: current_selected[trigger_graph_id] = neuron_id # reselection of matching -> update highlighted neuron (of a non-reference graph) if trigger_graph_id != 0: if not no_match[trigger_graph_id-1]: # cannot update graph if 'no match' button is pressed! print("newly selected: ", current_selected[trigger_graph_id]) updates[trigger_graph_id] = update_graph(tiff_mode, fnames[trigger_graph_id], trigger_graph_id, current_selected[trigger_graph_id]) # new ref neuron clicked -> update highlighted neuron in ref and non-ref graphs if trigger_graph_id == 0 and not suggestion_mode: try: print(list(cell_matching_df.columns), fnames[trigger_graph_id].partition(".")[0]) except AttributeError: print("Compute or upload matchings before clicking neurons!") col = cell_matching_df[fnames[trigger_graph_id].partition(".")[0]] row_idx = cell_matching_df[col == neuron_id].index.values[0] print("row index is: ", row_idx) for graph_idx, filename in enumerate(fnames): if not filename: continue print(filename, fnames) curr_neuron = cell_matching_df.iloc[row_idx][filename.partition(".")[0]] if graph_idx > 0: clf_input = cell_matching_df.iloc[row_idx][filename.partition(".")[0] + 'feature_vals'] if not isinstance(clf_input, list): clf_input = json.loads(clf_input) print('clf_input ', clf_input) curr_neuron = get_predicted_neuron(clf, clf_input[:3]) print(curr_neuron) current_selected[graph_idx] = curr_neuron updates[graph_idx] = update_graph(tiff_mode, filename, graph_idx, curr_neuron) print(int(coms[graph_idx][curr_neuron][0]), int(coms[graph_idx][curr_neuron][1])) print("click on nothing?") # 3 UPLOAD BUTTON elif trigger_action == 'filename': print("***callback: LOAD FILE") print(ctx.triggered) trigger_graph_id = int(trigger_firstarg.rsplit('_', 1)[-1]) print("loading ", fnames[trigger_graph_id]) updates[trigger_graph_id] = int_func.format_fig( getdata_from_npyfile(fnames[trigger_graph_id], trigger_graph_id)[1], title=fnames[trigger_graph_id].partition(".")[0]) print("done loading file") for i in range(num_plots_max): if i != trigger_graph_id: updates[i] = no_update else: pass print(cells_left_message) return tuple(updates) + (cells_left_message,) + (reset,)
# initialization of global variables num_plots_max = 12 cell_matching_df = [] filenames = [''] * num_plots_max sessions_data = [None] * num_plots_max footprints = [None] * num_plots_max orig_templates = [None] * num_plots_max templates = [None] * num_plots_max templates_tiff = [None] * num_plots_max coms = [None] * num_plots_max current_selected = [-1] * num_plots_max no_match = [False] * (num_plots_max - 1) pixel_ownerships = [np.full((512, 512), -1)] * num_plots_max empty_template = [[0] * 512] * 512 figs = [int_func.format_fig(empty_template)] * num_plots_max clf = pickle.load(open(classifier_path, 'rb')) # ********************************************************************************************************************** # DASHBOARD # ********************************************************************************************************************** print("the app reset, all data must be reloaded!") app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP]) # ********************************************************************************************************************** # LAYOUT (see content_layout.py for more details) # ********************************************************************************************************************** app.layout = dbc.Container(
# initialization of global variables cell_matching_df = [] filenames = [''] * 6 sessions_data = [None] * 6 footprints = [None] * 6 orig_templates = [None] * 6 templates = [None] * 6 templates_tiff = [None] * 6 coms = [None] * 6 current_selected = [-1] * 6 no_match = [False] * 5 pixel_ownerships = [np.full((512, 512), -1)] * 6 empty_template = [[0] * 512] * 512 figs = [int_func.format_fig(empty_template)] * 6 clf = pickle.load(open(classifier_path, 'rb')) # ********************************************************************************************************************** # DASHBOARD # ********************************************************************************************************************** print("the app reset, all data must be reloaded!") app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP]) # ********************************************************************************************************************** # LAYOUT (see content_layout.py for more details) # ********************************************************************************************************************** app.layout = dbc.Container([ dbc.Row(dbc.Col(html.Div("CELL MATCHING ACROSS SESSIONS"), width=12),