From 445ae5587fd50d61df8c56b0dbe35468b1516d5a Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Thu, 2 Nov 2023 18:17:10 +0000 Subject: [PATCH 1/8] some work on online plots --- iblrig/misc.py | 10 ++++++---- iblrig/online_plots.py | 28 ++++++++++++++++++---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/iblrig/misc.py b/iblrig/misc.py index 0a2493379..51c30f194 100644 --- a/iblrig/misc.py +++ b/iblrig/misc.py @@ -159,7 +159,7 @@ def truncated_exponential(scale: float = 0.35, min_value: float = 0.2, max_value if min_value <= x <= max_value: return x else: - return truncated_exponential(scale=scale, min_value=min_value, max_value=max_value) + return truncated_exponential(scale, min_value, max_value) def get_biased_probs(n: int, idx: int = -1, p_idx: float = 0.5) -> list[float]: @@ -186,13 +186,15 @@ def get_biased_probs(n: int, idx: int = -1, p_idx: float = 0.5) -> list[float]: Raises ------ + IndexError + If `idx` is out of range ValueError - If `idx` is outside the valid range [-1, n), or if `p_idx` is 0. + If `p_idx` is 0. """ - if idx < -1 or idx >= n: - raise ValueError("Invalid index. Index should be in the range [-1, n).") if n == 1: return [1.0] + if idx not in range(-n, n): + raise IndexError("`idx` is out of range.") if p_idx == 0: raise ValueError("Probability must be larger than 0.") z = n - 1 + p_idx diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 511d8247b..0709ec93b 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -2,9 +2,11 @@ import datetime import time +import matplotlib import pandas as pd import numpy as np import matplotlib.pyplot as plt +import matplotlib.style as mplstyle import seaborn as sns from pandas.api.types import CategoricalDtype @@ -23,6 +25,8 @@ ENGAGED_CRITIERION = {'secs': 45 * 60, 'trial_count': 400} sns.set_style('white') +mplstyle.use(['ggplot', 'fast']) +matplotlib.use('Qt5Agg') class DataModel(object): """ @@ -92,7 +96,7 @@ def __init__(self, task_file): # we keep only a single column as buffer self.trials_table = trials_table[['response_time']] # for the trials plots this is the background image showing green if correct, red if incorrect - self.rgb_background = np.zeros((NTRIALS_PLOT, 1, 3), dtype=np.uint8) + self.rgb_background = np.ones((NTRIALS_PLOT, 1, 3), dtype=np.uint8) * 229 self.rgb_background[self.last_trials.correct == False, 0, 0] = 255 # noqa self.rgb_background[self.last_trials.correct == True, 0, 1] = 255 # noqa # keep the last contrasts as a 20 by 2 array @@ -194,20 +198,20 @@ def __init__(self, task_file=None): h.ax_performance = h.fig.add_subplot(h.gs[0, nc - 1]) h.ax_reaction = h.fig.add_subplot(h.gs[1, hc:nc - 1]) h.ax_water = h.fig.add_subplot(h.gs[1, nc - 1]) - h.ax_psych.set(title='psychometric curve', xlim=[-1.01, 1.01], ylim=[0, 1.01]) - h.ax_reaction.set(title='reaction times', xlim=[-1.01, 1.01], ylim=[0, 4], xlabel='signed contrast') + h.ax_psych.set(title='psychometric curve', xlim=[-1, 1], ylim=[0, 1]) + h.ax_reaction.set(title='reaction times', xlim=[-1, 1], ylim=[0, 4], xlabel='signed contrast') h.ax_trials.set(yticks=[], title='trials timeline', xlim=[-5, 30], xlabel='time (s)') - h.ax_performance.set(xticks=[], xlim=[-1.01, 1.01], title='# trials') - h.ax_water.set(xticks=[], xlim=[-1.01, 1.01], ylim=[0, 1000], title='water (uL)') + h.ax_performance.set(xticks=[], xlim=[-0.6, 0.6], title='# trials') + h.ax_water.set(xticks=[], xlim=[-0.6, 0.6], ylim=[0, 1000], title='reward') # create psych curves h.curve_psych = {} h.curve_reaction = {} for i, p in enumerate(PROBABILITY_SET): h.curve_psych[p] = h.ax_psych.plot( - self.data.psychometrics.loc[p].index, self.data.psychometrics.loc[p]['choice'], '.-') + self.data.psychometrics.loc[p].index, self.data.psychometrics.loc[p]['choice'], 'k.-', zorder=10, clip_on=False) h.curve_reaction[p] = h.ax_reaction.plot( - self.data.psychometrics.loc[p].index, self.data.psychometrics.loc[p]['response_time'], '.-') + self.data.psychometrics.loc[p].index, self.data.psychometrics.loc[p]['response_time'], 'k.-') # create the two bars on the right side h.bar_correct = h.ax_performance.bar(0, self.data.ntrials_correct, label='correct', color='g') @@ -215,8 +219,12 @@ def __init__(self, task_file=None): 0, self.data.ntrials - self.data.ntrials_correct, label='error', color='r', bottom=self.data.ntrials_correct) h.bar_water = h.ax_water.bar(0, self.data.water_delivered, label='water delivered', color='b') + # h.label_correct = h.ax_performance.bar_label(h.bar_correct, label_type='center') + # h.label_error = h.ax_performance.bar_label(h.bar_error, label_type='center') + # h.label_water = h.ax_water.bar_label(h.bar_water) + # create the trials timeline view in a single axis - xpos = np.tile([[-4, -1.5]], (NTRIALS_PLOT, 1)).T.flatten() + xpos = np.tile([[-3.75, -1.25]], (NTRIALS_PLOT, 1)).T.flatten() ypos = np.tile(np.arange(NTRIALS_PLOT), 2) h.im_trials = h.ax_trials.imshow( self.data.rgb_background, alpha=.2, extent=[-10, 50, -.5, NTRIALS_PLOT - .5], aspect='auto', origin='lower') @@ -241,7 +249,7 @@ def __init__(self, task_file=None): def update_titles(self): self.h.fig_title.set_text( f"{self._session_string} time elapsed: {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}") - self.h.ax_water.title.set_text(f"water \n {self.data.water_delivered:.2f} (uL)") + self.h.ax_water.title.set_text(f"reward \n {self.data.water_delivered:.1f} μL") self.h.ax_performance.title.set_text(f" correct/tot \n {self.data.ntrials_correct} / {self.data.ntrials}") def update_trial(self, trial_data, bpod_data): @@ -276,7 +284,7 @@ def update_graphics(self, pupdate: float | None = None): self.h.bar_correct[0].set(height=self.data.ntrials_correct) self.h.bar_error[0].set(height=self.data.ntrials - self.data.ntrials_correct, y=self.data.ntrials_correct) self.h.bar_water[0].set(height=self.data.water_delivered) - h.ax_performance.set(ylim=[0, (self.data.ntrials // 50 + 1) * 50]) + h.ax_performance.set(ylim=[0, self.data.ntrials]) @property def _session_string(self) -> str: From 65cbf324c0976704084644b4a448ee5a9c252f78 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Thu, 2 Nov 2023 18:24:19 +0000 Subject: [PATCH 2/8] Update online_plots.py --- iblrig/online_plots.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 0709ec93b..3ec1fcc9d 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -23,9 +23,8 @@ PROBABILITY_SET = np.array([.2, .5, .8]) # if the mouse does less than 400 trials in the first 45mins it's disengaged ENGAGED_CRITIERION = {'secs': 45 * 60, 'trial_count': 400} -sns.set_style('white') +sns.set_style("darkgrid") -mplstyle.use(['ggplot', 'fast']) matplotlib.use('Qt5Agg') class DataModel(object): From bbcc8d78d70a3e0da40ce285e1fcc34c52576191 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 10:12:50 +0000 Subject: [PATCH 3/8] Update online_plots.py --- iblrig/online_plots.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 3ec1fcc9d..0a4762375 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -197,9 +197,17 @@ def __init__(self, task_file=None): h.ax_performance = h.fig.add_subplot(h.gs[0, nc - 1]) h.ax_reaction = h.fig.add_subplot(h.gs[1, hc:nc - 1]) h.ax_water = h.fig.add_subplot(h.gs[1, nc - 1]) + h.ax_psych.set(title='psychometric curve', xlim=[-1, 1], ylim=[0, 1]) h.ax_reaction.set(title='reaction times', xlim=[-1, 1], ylim=[0, 4], xlabel='signed contrast') + xticks = np.arange(-1, 1.1, .25) + xticklabels = np.array([f'{x:g}' for x in xticks]) + xticklabels[1::2] = '' + h.ax_psych.set_xticks(xticks, xticklabels) + h.ax_reaction.set_xticks(xticks, xticklabels) + h.ax_trials.set(yticks=[], title='trials timeline', xlim=[-5, 30], xlabel='time (s)') + h.ax_trials.set_xticklabels(np.hstack(([''], h.ax_trials.get_xticklabels()[1::]))) h.ax_performance.set(xticks=[], xlim=[-0.6, 0.6], title='# trials') h.ax_water.set(xticks=[], xlim=[-0.6, 0.6], ylim=[0, 1000], title='reward') @@ -218,10 +226,6 @@ def __init__(self, task_file=None): 0, self.data.ntrials - self.data.ntrials_correct, label='error', color='r', bottom=self.data.ntrials_correct) h.bar_water = h.ax_water.bar(0, self.data.water_delivered, label='water delivered', color='b') - # h.label_correct = h.ax_performance.bar_label(h.bar_correct, label_type='center') - # h.label_error = h.ax_performance.bar_label(h.bar_error, label_type='center') - # h.label_water = h.ax_water.bar_label(h.bar_water) - # create the trials timeline view in a single axis xpos = np.tile([[-3.75, -1.25]], (NTRIALS_PLOT, 1)).T.flatten() ypos = np.tile(np.arange(NTRIALS_PLOT), 2) @@ -240,6 +244,11 @@ def __init__(self, task_file=None): } h.scatter_contrast = h.ax_trials.scatter(xpos, ypos, s=250, c=self.data.last_contrasts.T.flatten(), alpha=1, marker='o', vmin=0.0, vmax=1, cmap='Greys') + xticks = np.arange(-1, 1.1, .25) + xticklabels = np.array([f'{x:g}' for x in xticks]) + xticklabels[1::2] = '' + h.ax_psych.set_xticks(xticks, xticklabels) + self.h = h self.update_titles() plt.show(block=False) From 604269a62fd59481361390478b57a8dedf0c7c92 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 17:44:57 +0000 Subject: [PATCH 4/8] Update online_plots.py --- iblrig/online_plots.py | 44 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 0a4762375..17d8aa622 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -1,3 +1,4 @@ +import json from pathlib import Path import datetime import time @@ -6,12 +7,12 @@ import pandas as pd import numpy as np import matplotlib.pyplot as plt -import matplotlib.style as mplstyle import seaborn as sns from pandas.api.types import CategoricalDtype import one.alf.io +from iblrig.choiceworld import get_subject_training_info from iblrig.misc import online_std from iblrig.raw_data_loaders import load_task_jsonable from iblutil.util import Bunch @@ -27,6 +28,7 @@ matplotlib.use('Qt5Agg') + class DataModel(object): """ The data model is a pure numpy / pandas container for the choice world task. @@ -36,6 +38,8 @@ class DataModel(object): - a last trials dataframe that contains 20 trials worth of data for the timeline view - various counters such as ntrials and water delivered """ + task_settings = None + def __init__(self, task_file): """ Can be instantiated empty or from an existing jsonable file from any rig version @@ -45,6 +49,7 @@ def __init__(self, task_file): self.last_trials = pd.DataFrame( columns=['correct', 'signed_contrast', 'stim_on', 'play_tone', 'reward_time', 'error_time', 'response_time'], index=np.arange(NTRIALS_PLOT)) + if task_file is None or not Path(task_file).exists(): self.psychometrics = pd.DataFrame( columns=['count', 'response_time', 'choice', 'response_time_std', 'choice_std'], @@ -58,6 +63,7 @@ def __init__(self, task_file): self.time_elapsed = 0 self.ntrials_engaged = 0 # those are the trials happening within the first 400s else: + self.get_task_settings(Path(task_file).parent) trials_table, bpod_data = load_task_jsonable(task_file) # here we take the end time of the first trial as reference to avoid factoring in the delay self.time_elapsed = bpod_data[-1]['Trial end timestamp'] - bpod_data[0]['Trial end timestamp'] @@ -105,6 +111,11 @@ def __init__(self, task_file): self.last_contrasts[ileft, 0] = np.abs(self.last_trials.signed_contrast[ileft]) self.last_contrasts[iright, 1] = np.abs(self.last_trials.signed_contrast[iright]) + def get_task_settings(self, session_directory: str | Path) -> None: + task_settings_file = Path(session_directory).joinpath('_iblrig_taskSettings.raw.json') + with open(task_settings_file, 'r') as fid: + self.task_settings = json.load(fid) + def update_trial(self, trial_data, bpod_data) -> None: # update counters self.time_elapsed = bpod_data['Trial end timestamp'] - bpod_data['Bpod start timestamp'] @@ -183,12 +194,15 @@ class OnlinePlots(object): Use ctrl + Z to interrupt >>> OnlinePlots().run(task_file) """ + def __init__(self, task_file=None): self.data = DataModel(task_file=task_file) + # create figure and axes h = Bunch({}) h.fig = plt.figure(constrained_layout=True, figsize=(10, 8)) - h.fig_title = h.fig.suptitle(f"{self._session_string}", fontweight='bold') + self._set_session_string() + h.fig_title = h.fig.suptitle(f"{self._session_string}") nc = 9 hc = nc // 2 h.gs = h.fig.add_gridspec(2, nc) @@ -207,7 +221,7 @@ def __init__(self, task_file=None): h.ax_reaction.set_xticks(xticks, xticklabels) h.ax_trials.set(yticks=[], title='trials timeline', xlim=[-5, 30], xlabel='time (s)') - h.ax_trials.set_xticklabels(np.hstack(([''], h.ax_trials.get_xticklabels()[1::]))) + # h.ax_trials.set_xticklabels(np.hstack(([''], h.ax_trials.get_xticklabels()[1::]))) h.ax_performance.set(xticks=[], xlim=[-0.6, 0.6], title='# trials') h.ax_water.set(xticks=[], xlim=[-0.6, 0.6], ylim=[0, 1000], title='reward') @@ -256,7 +270,7 @@ def __init__(self, task_file=None): def update_titles(self): self.h.fig_title.set_text( - f"{self._session_string} time elapsed: {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}") + self._session_string + f"time elapsed: {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}") self.h.ax_water.title.set_text(f"reward \n {self.data.water_delivered:.1f} μL") self.h.ax_performance.title.set_text(f" correct/tot \n {self.data.ntrials_correct} / {self.data.ntrials}") @@ -294,9 +308,20 @@ def update_graphics(self, pupdate: float | None = None): self.h.bar_water[0].set(height=self.data.water_delivered) h.ax_performance.set(ylim=[0, self.data.ntrials]) - @property - def _session_string(self) -> str: - return ' - '.join(self.data.session_path.parts[-3:]) if self.data.session_path != "" else "" + def _set_session_string(self) -> None: + if isinstance(self.data.task_settings, dict): + training_info, _ = get_subject_training_info(subject_name=self.data.task_settings["SUBJECT_NAME"], + task_name=self.data.task_settings["PYBPOD_PROTOCOL"], + lab=self.data.task_settings["ALYX_LAB"]) + protocol = r'$\mathbf{' + self.data.task_settings["PYBPOD_PROTOCOL"].replace('_', '\_') + r'}$' + self._session_string = f'{protocol}\n' \ + f'subject: {self.data.task_settings["SUBJECT_NAME"]} · ' \ + f'weight: {self.data.task_settings["SUBJECT_WEIGHT"]}g · ' \ + f'training phase: {training_info["training_phase"]} · ' \ + f'stimulus gain: {self.data.task_settings["STIM_GAIN"]} · ' \ + f'reward amount: {self.data.task_settings["REWARD_AMOUNT_UL"]}µl · ' + else: + self._session_string = '' def run(self, task_file: Path | str) -> None: """ @@ -304,9 +329,12 @@ def run(self, task_file: Path | str) -> None: :param task_file: :return: """ + task_file = Path(task_file) + self.data.get_task_settings(task_file.parent) + self._set_session_string() + self.update_titles() self.h.fig.canvas.flush_events() self.real_time = Bunch({'fseek': 0, 'time_last_check': 0}) - task_file = Path(task_file) flag_file = task_file.parent.joinpath('new_trial.flag') while True: From 3276e7659e1eea991bae3291b5cab5a88e4edd54 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 18:35:33 +0000 Subject: [PATCH 5/8] ready for 8.12.4 --- CHANGELOG.md | 4 ++++ iblrig/__init__.py | 2 +- iblrig/online_plots.py | 35 +++++++++++++++++++---------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b4f4674..792c8570b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Changelog --------- +8.12.4 +------ +* updated online-plots + 8.12.3 ------ * bugfix: getting training status of subject not present on local server diff --git a/iblrig/__init__.py b/iblrig/__init__.py index 4cc3048e9..dda045230 100644 --- a/iblrig/__init__.py +++ b/iblrig/__init__.py @@ -4,7 +4,7 @@ # 3) Check CI and eventually wet lab test # 4) Pull request to iblrigv8 # 5) git tag the release in accordance to the version number below (after merge!) -__version__ = '8.12.3' +__version__ = '8.12.4' # The following method call will try to get post-release information (i.e. the number of commits since the last tagged # release corresponding to the one above), plus information about the state of the local repository (dirty/broken) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 17d8aa622..1423a5151 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -59,6 +59,9 @@ def __init__(self, task_file): self.trials_table = pd.DataFrame(columns=['response_time'], index=np.arange(NTRIALS_INIT)) self.ntrials = 0 self.ntrials_correct = 0 + self.ntrials_nan = np.nan + self.percent_correct = np.nan + self.percent_error = np.nan self.water_delivered = 0 self.time_elapsed = 0 self.ntrials_engaged = 0 # those are the trials happening within the first 400s @@ -83,6 +86,8 @@ def __init__(self, task_file): ) self.ntrials = trials_table.shape[0] self.ntrials_correct = np.sum(trials_table.trial_correct) + self.ntrials_nan = self.ntrials if self.ntrials > 0 else np.nan + self.percent_correct = self.ntrials_correct / self.ntrials_nan * 100 # agg.water_delivered = trials_table.water_delivered.iloc[-1] self.water_delivered = trials_table.reward_amount.sum() # init the last trials table @@ -161,6 +166,8 @@ def update_trial(self, trial_data, bpod_data) -> None: self.last_contrasts[-1, :] = 0 self.last_contrasts[-1, int(self.last_trials.signed_contrast.iloc[-1] > 0)] = abs( self.last_trials.signed_contrast.iloc[-1]) + self.ntrials_nan = self.ntrials if self.ntrials > 0 else np.nan + self.percent_correct = self.ntrials_correct / self.ntrials_nan * 100 def compute_end_session_criteria(self): """ @@ -221,8 +228,8 @@ def __init__(self, task_file=None): h.ax_reaction.set_xticks(xticks, xticklabels) h.ax_trials.set(yticks=[], title='trials timeline', xlim=[-5, 30], xlabel='time (s)') - # h.ax_trials.set_xticklabels(np.hstack(([''], h.ax_trials.get_xticklabels()[1::]))) - h.ax_performance.set(xticks=[], xlim=[-0.6, 0.6], title='# trials') + h.ax_trials.set_xticks(h.ax_trials.get_xticks(), [''] + h.ax_trials.get_xticklabels()[1::]) + h.ax_performance.set(xticks=[], xlim=[-0.6, 0.6], ylim=[0, 100], title='performance') h.ax_water.set(xticks=[], xlim=[-0.6, 0.6], ylim=[0, 1000], title='reward') # create psych curves @@ -235,9 +242,7 @@ def __init__(self, task_file=None): self.data.psychometrics.loc[p].index, self.data.psychometrics.loc[p]['response_time'], 'k.-') # create the two bars on the right side - h.bar_correct = h.ax_performance.bar(0, self.data.ntrials_correct, label='correct', color='g') - h.bar_error = h.ax_performance.bar( - 0, self.data.ntrials - self.data.ntrials_correct, label='error', color='r', bottom=self.data.ntrials_correct) + h.bar_correct = h.ax_performance.bar(0, self.data.percent_correct, label='correct', color='k') h.bar_water = h.ax_water.bar(0, self.data.water_delivered, label='water delivered', color='b') # create the trials timeline view in a single axis @@ -269,10 +274,12 @@ def __init__(self, task_file=None): plt.draw() def update_titles(self): - self.h.fig_title.set_text( - self._session_string + f"time elapsed: {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}") - self.h.ax_water.title.set_text(f"reward \n {self.data.water_delivered:.1f} μL") - self.h.ax_performance.title.set_text(f" correct/tot \n {self.data.ntrials_correct} / {self.data.ntrials}") + protocol = (self.data.task_settings["PYBPOD_PROTOCOL"] if self.data.task_settings else '').replace('_', '\_') + spacer = '\ \ ·\ \ ' + main_title = r'$\mathbf{' + protocol + f'{spacer}{self.data.ntrials}\ trials{spacer}time\ elapsed:\ {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}' + r'}$' + self.h.fig_title.set_text(main_title + '\n' + self._session_string) + self.h.ax_water.title.set_text(f"total reward\n{self.data.water_delivered:.1f}μL") + self.h.ax_performance.title.set_text(f"performance\n{self.data.percent_correct:.0f}%") def update_trial(self, trial_data, bpod_data): """ @@ -303,23 +310,19 @@ def update_graphics(self, pupdate: float | None = None): h.lines_trials[k][0].set(xdata=self.data.last_trials[k]) self.h.scatter_contrast.set_array(self.data.last_contrasts.T.flatten()) # update barplots - self.h.bar_correct[0].set(height=self.data.ntrials_correct) - self.h.bar_error[0].set(height=self.data.ntrials - self.data.ntrials_correct, y=self.data.ntrials_correct) + self.h.bar_correct[0].set(height=self.data.percent_correct) self.h.bar_water[0].set(height=self.data.water_delivered) - h.ax_performance.set(ylim=[0, self.data.ntrials]) def _set_session_string(self) -> None: if isinstance(self.data.task_settings, dict): training_info, _ = get_subject_training_info(subject_name=self.data.task_settings["SUBJECT_NAME"], task_name=self.data.task_settings["PYBPOD_PROTOCOL"], lab=self.data.task_settings["ALYX_LAB"]) - protocol = r'$\mathbf{' + self.data.task_settings["PYBPOD_PROTOCOL"].replace('_', '\_') + r'}$' - self._session_string = f'{protocol}\n' \ - f'subject: {self.data.task_settings["SUBJECT_NAME"]} · ' \ + self._session_string = f'subject: {self.data.task_settings["SUBJECT_NAME"]} · ' \ f'weight: {self.data.task_settings["SUBJECT_WEIGHT"]}g · ' \ f'training phase: {training_info["training_phase"]} · ' \ f'stimulus gain: {self.data.task_settings["STIM_GAIN"]} · ' \ - f'reward amount: {self.data.task_settings["REWARD_AMOUNT_UL"]}µl · ' + f'reward amount: {self.data.task_settings["REWARD_AMOUNT_UL"]}µl' else: self._session_string = '' From 2027091a6619eeaebc30eeb8a2811088f8f1a92e Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 18:38:40 +0000 Subject: [PATCH 6/8] flake8 --- iblrig/online_plots.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 1423a5151..bcc32c6b1 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -274,9 +274,10 @@ def __init__(self, task_file=None): plt.draw() def update_titles(self): - protocol = (self.data.task_settings["PYBPOD_PROTOCOL"] if self.data.task_settings else '').replace('_', '\_') - spacer = '\ \ ·\ \ ' - main_title = r'$\mathbf{' + protocol + f'{spacer}{self.data.ntrials}\ trials{spacer}time\ elapsed:\ {str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}' + r'}$' + protocol = (self.data.task_settings["PYBPOD_PROTOCOL"] if self.data.task_settings else '').replace('_', r'\_') + spacer = r'\ \ ·\ \ ' + main_title = r'$\mathbf{' + protocol + fr'{spacer}{self.data.ntrials}\ trials{spacer}time\ elapsed:\ ' \ + fr'{str(datetime.timedelta(seconds=int(self.data.time_elapsed)))}' + r'}$' self.h.fig_title.set_text(main_title + '\n' + self._session_string) self.h.ax_water.title.set_text(f"total reward\n{self.data.water_delivered:.1f}μL") self.h.ax_performance.title.set_text(f"performance\n{self.data.percent_correct:.0f}%") From c83a6484629236c5723794963970fb0c8e78349c Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 18:45:59 +0000 Subject: [PATCH 7/8] fix CI --- iblrig/online_plots.py | 2 ++ iblrig/test/test_misc.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index bcc32c6b1..0d66c6b70 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -118,6 +118,8 @@ def __init__(self, task_file): def get_task_settings(self, session_directory: str | Path) -> None: task_settings_file = Path(session_directory).joinpath('_iblrig_taskSettings.raw.json') + if not task_settings_file.exists(): + return with open(task_settings_file, 'r') as fid: self.task_settings = json.load(fid) diff --git a/iblrig/test/test_misc.py b/iblrig/test/test_misc.py index 926cebfd3..927a9b29f 100644 --- a/iblrig/test/test_misc.py +++ b/iblrig/test/test_misc.py @@ -9,7 +9,7 @@ class TestMisc(unittest.TestCase): def test_draw_contrast(self): - n_draws = 1000 + n_draws = 5000 n_contrasts = 10 contrast_set = np.linspace(0, 1, n_contrasts) @@ -30,7 +30,7 @@ def assert_distribution(values: list[int], f_exp: list[float] | None = None) -> assert_distribution(contrasts, expected) self.assertRaises(ValueError, misc.draw_contrast, [], "incorrect_type") # assert exception for incorrect type - self.assertRaises(ValueError, misc.draw_contrast, [0, 1], "biased", 2) # assert exception for out-of-range index + self.assertRaises(IndexError, misc.draw_contrast, [0, 1], "biased", 2) # assert exception for out-of-range index def test_online_std(self): n = 41 From 685289b4757477bd4b2178ba7bd68ff06d37bc3c Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Fri, 3 Nov 2023 20:01:29 +0000 Subject: [PATCH 8/8] Update online_plots.py --- iblrig/online_plots.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/iblrig/online_plots.py b/iblrig/online_plots.py index 0d66c6b70..a38779e8c 100644 --- a/iblrig/online_plots.py +++ b/iblrig/online_plots.py @@ -3,7 +3,6 @@ import datetime import time -import matplotlib import pandas as pd import numpy as np import matplotlib.pyplot as plt @@ -26,8 +25,6 @@ ENGAGED_CRITIERION = {'secs': 45 * 60, 'trial_count': 400} sns.set_style("darkgrid") -matplotlib.use('Qt5Agg') - class DataModel(object): """