Skip to content

Commit 7eafdca

Browse files
committed
simplified stuff
1 parent ef84f1d commit 7eafdca

2 files changed

Lines changed: 195 additions & 105 deletions

File tree

behavior_data_visualizer/main.py

Lines changed: 151 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@
1818
if not os.path.exists(STATIC_PATH):
1919
os.makedirs(STATIC_PATH)
2020

21-
def app_builder(project_name):
22-
mouse_data_dict = utils.get_mouse_data_dict(project_name)
23-
session_data_dict = {}
21+
def app_builder():
22+
23+
# get the list of the projects
24+
projects_list = utils.get_list_of_projects()
25+
26+
global mouse_data_dict
27+
mouse_data_dict = {} # utils.get_mouse_data_dict(project_name)
28+
# session_data_dict = {}
2429

2530
app = dash.Dash(__name__)
2631

@@ -58,81 +63,124 @@ def serve_video(filename):
5863
# Layout
5964
app.layout = dash.html.Div([
6065
dash.dcc.Store(id="video-start-time"), # Declare globally in layout
66+
dash.dcc.Store(id="mouse-data-loaded"),
6167

6268
dash.dcc.Tabs([
63-
dash.dcc.Tab(label='Compare mice', children=[
64-
dash.dcc.Checklist(
65-
id='mice-checklist',
66-
options=[{'label': key, 'value': key} for key in mouse_data_dict.keys()],
67-
value=[],
68-
labelStyle={'display': 'block'}
69-
),
70-
dash.dcc.Graph(id='graph')
71-
]),
69+
# dash.dcc.Tab(label='Compare mice', children=[
70+
# dash.dcc.Checklist(
71+
# id='mice-checklist',
72+
# options=[{'label': key, 'value': key} for key in mouse_data_dict.keys()],
73+
# value=[],
74+
# labelStyle={'display': 'block'}
75+
# ),
76+
# dash.dcc.Graph(id='graph')
77+
# ]),
7278

73-
dash.dcc.Tab(label='Single mouse reactive', children=[
79+
dash.dcc.Tab(label='Training Village Behavior Explorer', children=[
7480
dash.html.Div([
81+
dash.dcc.Dropdown(
82+
id='projects-dropdown',
83+
options=[{'label': project_name, 'value': project_name} for project_name in projects_list],
84+
value=None,
85+
multi=False,
86+
style={'width': '10%', 'min-width': '125px', 'flex-shrink': '0'}
87+
),
7588
dash.dcc.Dropdown(
7689
id='single-mouse-dropdown',
7790
options=[{'label': key, 'value': key} for key in mouse_data_dict.keys()],
7891
value=None,
7992
multi=False,
80-
style={'width': '10%'}
93+
style={'width': '10%', 'min-width': '125px', 'flex-shrink': '0'}
8194
),
82-
dash.dcc.Graph(id='reactive-calendar', style={'width': '55%'}),
83-
dash.html.Pre(id='single-mouse-text', style={'flex': '1', 'width': '35%'}),
95+
dash.dcc.Graph(id='reactive-calendar', style={'width': '55%', 'flex-shrink': '0'}),
96+
dash.html.Pre(id='single-mouse-text', style={'width': '25%', 'flex-shrink': '0'}),
8497
], style={'display': 'flex', 'flex-direction': 'row'}),
8598
dash.html.Div([
8699
dash.dcc.Graph(id='single-mouse-performance', style={'flex': '1', 'height': '15%', 'width': '35%'}),
87100
dash.dcc.Graph(id="single-mouse-psychometric", style={'flex': '1', 'height': '15%', 'width': '20%'}),
88101
dash.html.Pre(id='single-mouse-video', style={'display': 'flex', 'flex-direction': 'row', 'flex': '1', 'width': '45%'}),
89102
], style={'display': 'flex', 'flex-direction': 'row'}),
90103
]),
91-
dash.dcc.Tab(label='Reports', children=[
92-
dash.html.H3('Subject progress'),
93-
dash.dcc.Dropdown(
94-
id='reports-mice-dropdown',
95-
options=[{'label': key, 'value': key} for key in mouse_data_dict.keys()],
96-
value=None,
97-
multi=False,
98-
style={'width': '30%'}
99-
),
100-
dash.html.Img(id='subject-progress', src=''),
101-
dash.html.H3('Session summary'),
102-
dash.dcc.Dropdown(
103-
id='reports-session-dropdown',
104-
options=[{'label': key, 'value': session_data_dict[key]} for key in session_data_dict.keys()],
105-
value=None,
106-
multi=False,
107-
style={'width': '30%'}
108-
),
109-
dash.html.Img(id='session-summary', src=''),
110-
]),
104+
# dash.dcc.Tab(label='Reports', children=[
105+
# dash.html.H3('Subject progress'),
106+
# dash.dcc.Dropdown(
107+
# id='reports-mice-dropdown',
108+
# options=[{'label': key, 'value': key} for key in mouse_data_dict.keys()],
109+
# value=None,
110+
# multi=False,
111+
# style={'width': '30%'}
112+
# ),
113+
# dash.html.Img(id='subject-progress', src=''),
114+
# dash.html.H3('Session summary'),
115+
# dash.dcc.Dropdown(
116+
# id='reports-session-dropdown',
117+
# options=[{'label': key, 'value': session_data_dict[key]} for key in session_data_dict.keys()],
118+
# value=None,
119+
# multi=False,
120+
# style={'width': '30%'}
121+
# ),
122+
# dash.html.Img(id='session-summary', src=''),
123+
# ]),
111124
])
112125
])
113126

127+
# @app.callback(
128+
# dash.dependencies.Output('graph', 'figure'),
129+
# [dash.dependencies.Input('mice-checklist', 'value')],
130+
# )
131+
# def update_figure(selected_items):
132+
# if len(selected_items) == 0:
133+
# return {}
134+
# tdfs = []
135+
# for key in selected_items:
136+
# df = mouse_data_dict[key]
137+
# df["mouse_name"] = key
138+
# tdfs.append(dft.get_performance_through_trials(df, window=50))
139+
# tdf = pd.concat(tdfs)
140+
# fig = px.line(tdf, x='total_trial', y='performance_w', color='mouse_name')
141+
# return fig
142+
143+
# create a callback to get the list of the mice when a project is selected
114144
@app.callback(
115-
dash.dependencies.Output('graph', 'figure'),
116-
[dash.dependencies.Input('mice-checklist', 'value')],
145+
dash.dependencies.Output('single-mouse-dropdown', 'options'),
146+
[dash.dependencies.Input('projects-dropdown', 'value')],
117147
)
118-
def update_figure(selected_items):
119-
if len(selected_items) == 0:
120-
return {}
121-
tdfs = []
122-
for key in selected_items:
123-
df = mouse_data_dict[key]
124-
df["mouse_name"] = key
125-
tdfs.append(dft.get_performance_through_trials(df, window=50))
126-
tdf = pd.concat(tdfs)
127-
fig = px.line(tdf, x='total_trial', y='performance_w', color='mouse_name')
128-
return fig
148+
def update_mice_options(selected_project):
149+
# when the project is changed, refresh the mouse_data_dict
150+
mouse_data_dict = {}
151+
if selected_project is None:
152+
return []
153+
list_of_mice = utils.get_list_of_mice(selected_project)
154+
return [{'label': animal, 'value': animal} for animal in list_of_mice]
155+
156+
# create a callback to update the mouse_data_dict when a mouse is selected,
157+
@app.callback(
158+
dash.dependencies.Output('mouse-data-loaded', 'data'),
159+
[
160+
dash.dependencies.Input('projects-dropdown', 'value'),
161+
dash.dependencies.Input('single-mouse-dropdown', 'value'),
162+
],
163+
)
164+
def update_mouse_data_dict(selected_project, selected_mouse):
165+
print(mouse_data_dict.keys())
166+
if selected_project is None or selected_mouse is None:
167+
return False
168+
# check if the data is already loaded
169+
if selected_mouse in mouse_data_dict.keys():
170+
return True
171+
else:
172+
mouse_data_dict[selected_mouse] = utils.load_mouse_data(selected_project, selected_mouse)
173+
return True
129174

130175
@app.callback(
131176
dash.dependencies.Output('reactive-calendar', 'figure'),
132-
[dash.dependencies.Input('single-mouse-dropdown', 'value')],
177+
[
178+
dash.dependencies.Input('single-mouse-dropdown', 'value'),
179+
dash.dependencies.Input('mouse-data-loaded', 'data'),
180+
],
133181
)
134-
def update_calendar(mouse_name):
135-
if mouse_name is None:
182+
def update_calendar(mouse_name, mouse_data_loaded):
183+
if not mouse_data_loaded or mouse_name is None:
136184
return {}
137185
df = mouse_data_dict[mouse_name]
138186
dates_df = df.groupby(["year_month_day"]).count().reset_index()
@@ -147,22 +195,31 @@ def update_calendar(mouse_name):
147195
dash.dependencies.Output('single-mouse-text', 'children'),
148196
dash.dependencies.Output('single-mouse-performance', 'figure'),
149197
dash.dependencies.Output('single-mouse-psychometric', 'figure'),
150-
[dash.dependencies.Input('reactive-calendar', 'clickData'),
151-
dash.dependencies.Input('single-mouse-dropdown', 'value')],
198+
[
199+
dash.dependencies.Input('reactive-calendar', 'clickData'),
200+
dash.dependencies.Input('single-mouse-dropdown', 'value'),
201+
dash.dependencies.Input('mouse-data-loaded', 'data'),
202+
],
203+
prevent_initial_call=True
152204
)
153-
def update_single_mouse_reactive(clickData, mouse_name):
154-
text = utils.display_click_data(clickData, mouse_name)
155-
perf_fig = utils.update_performance_figure(clickData, mouse_name)
156-
psych_fig = utils.update_psychometric_figure(clickData, mouse_name)
205+
def update_single_mouse_reactive(clickData, mouse_name, mouse_data_loaded):
206+
if not mouse_data_loaded or mouse_name is None or clickData is None:
207+
return "", {}, {}
208+
text = utils.display_click_data(clickData, mouse_data_dict[mouse_name])
209+
perf_fig = utils.update_performance_figure(clickData, mouse_data_dict[mouse_name])
210+
psych_fig = utils.update_psychometric_figure(clickData, mouse_data_dict[mouse_name])
157211
return text, perf_fig, psych_fig
158212

159213
@app.callback(
160214
dash.dependencies.Output('single-mouse-video', 'children'),
161215
dash.dependencies.Output('video-start-time', 'data', allow_duplicate=True),
162-
[dash.dependencies.Input('single-mouse-performance', 'clickData')],
216+
[
217+
dash.dependencies.Input('single-mouse-performance', 'clickData'),
218+
dash.dependencies.Input('projects-dropdown', 'value'),
219+
],
163220
prevent_initial_call=True
164221
)
165-
def update_single_mouse_video(clickData):
222+
def update_single_mouse_video(clickData, project_name):
166223
if clickData is None:
167224
raise PreventUpdate
168225

@@ -196,43 +253,43 @@ def update_single_mouse_video(clickData):
196253

197254
return video_component, {"time": start_time}
198255

199-
@app.callback(
200-
dash.dependencies.Output('subject-progress', component_property='src'),
201-
[dash.dependencies.Input('reports-mice-dropdown', 'value')],
202-
)
203-
def update_subject_progress(selected_value):
204-
if selected_value is None:
205-
return ''
206-
df = mouse_data_dict[selected_value]
207-
fig = fm.subject_progress_figure(df)
208-
return utils.fig_to_uri(fig)
256+
# @app.callback(
257+
# dash.dependencies.Output('subject-progress', component_property='src'),
258+
# [dash.dependencies.Input('reports-mice-dropdown', 'value')],
259+
# )
260+
# def update_subject_progress(selected_value):
261+
# if selected_value is None:
262+
# return ''
263+
# df = mouse_data_dict[selected_value]
264+
# fig = fm.subject_progress_figure(df)
265+
# return utils.fig_to_uri(fig)
209266

210-
@app.callback(
211-
dash.dependencies.Output('reports-session-dropdown', 'options'),
212-
[dash.dependencies.Input('reports-mice-dropdown', 'value')],
213-
)
214-
def update_session_dropdown(selected_value):
215-
if selected_value is None:
216-
return []
217-
df = mouse_data_dict[selected_value]
218-
session_data_dict = utils.get_diccionary_of_dates(df)
219-
return [{'label': key, 'value': session_data_dict[key]} for key in session_data_dict.keys()]
267+
# @app.callback(
268+
# dash.dependencies.Output('reports-session-dropdown', 'options'),
269+
# [dash.dependencies.Input('reports-mice-dropdown', 'value')],
270+
# )
271+
# def update_session_dropdown(selected_value):
272+
# if selected_value is None:
273+
# return []
274+
# df = mouse_data_dict[selected_value]
275+
# session_data_dict = utils.get_diccionary_of_dates(df)
276+
# return [{'label': key, 'value': session_data_dict[key]} for key in session_data_dict.keys()]
220277

221-
@app.callback(
222-
dash.dependencies.Output('session-summary', component_property='src'),
223-
[dash.dependencies.Input('reports-mice-dropdown', 'value')],
224-
[dash.dependencies.Input('reports-session-dropdown', 'value')],
225-
)
226-
def update_session_summary(mouse, session):
227-
if mouse is None or session is None:
228-
return ''
229-
df = mouse_data_dict[mouse]
230-
sdf = df[df["year_month_day"] == session]
231-
fig = fm.session_summary_figure(sdf, mouse, perf_window=25)
232-
return utils.fig_to_uri(fig)
278+
# @app.callback(
279+
# dash.dependencies.Output('session-summary', component_property='src'),
280+
# [dash.dependencies.Input('reports-mice-dropdown', 'value')],
281+
# [dash.dependencies.Input('reports-session-dropdown', 'value')],
282+
# )
283+
# def update_session_summary(mouse, session):
284+
# if mouse is None or session is None:
285+
# return ''
286+
# df = mouse_data_dict[mouse]
287+
# sdf = df[df["year_month_day"] == session]
288+
# fig = fm.session_summary_figure(sdf, mouse, perf_window=25)
289+
# return utils.fig_to_uri(fig)
233290

234291
return app
235292

236293
if __name__ == '__main__':
237-
app = app_builder('visual_and_COT_data')
238-
app.run(debug=True, port=8050)
294+
app = app_builder()
295+
app.run(debug=True, port=4040)

0 commit comments

Comments
 (0)