Skip to content

Commit

Permalink
Merge branch 'release/2.10.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
juhuntenburg committed Feb 22, 2022
2 parents 15696d8 + 4a780e0 commit 2e1f91c
Show file tree
Hide file tree
Showing 27 changed files with 2,508 additions and 273 deletions.
15 changes: 8 additions & 7 deletions brainbox/behavior/dlc.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,12 @@ def plot_wheel_position(wheel_position, wheel_time, trials_df):

plt.axvline(x=0, linestyle='--', c='k', label='stimOn')
plt.axhline(y=-0.26, linestyle='--', c='g', label='reward')
plt.axhline(y=0.26, linestyle='--', c='g', label='reward')
plt.ylim([-0.27, 0.27])
plt.xlabel('time [sec]')
plt.ylabel('wheel position [rad]')
plt.ylabel('wheel position diff to first value [rad]')
plt.legend(loc='center right')
plt.title('Wheel position')
plt.title('Wheel position trial avg\n(and individual trials)')
plt.tight_layout()

return plt.gca()
Expand Down Expand Up @@ -406,7 +407,7 @@ def plot_lick_hist(lick_times, trials_df):
plt.plot(times, pd.DataFrame.from_dict(dict(zip(correct.index, incorrect.values))).mean(axis=1),
c='gray', label='incorrect trial')
plt.axvline(x=0, label='feedback', linestyle='--', c='purple')
plt.title('Lick events')
plt.title('Lick events trial avg')
plt.xlabel('time [sec]')
plt.ylabel('lick events [a.u.]')
plt.legend(loc='lower right')
Expand Down Expand Up @@ -479,7 +480,7 @@ def plot_motion_energy_hist(camera_dict, trials_df):
plt.xlabel('time [sec]')
plt.axvline(x=0, label='stimOn', linestyle='--', c='k')
plt.legend(loc='lower right')
plt.title('Motion Energy')
plt.title('Motion Energy trial avg\n(+/- std)')
if len(missing_data) > 0:
ax = plt.gca()
ax.text(.95, .35, f"Data incomplete for\n{' and '.join(missing_data)} camera", color='r', fontsize=10,
Expand Down Expand Up @@ -523,7 +524,7 @@ def plot_speed_hist(dlc_df, cam_times, trials_df, feature='paw_r', cam='left', l
plt.plot(times, pd.DataFrame.from_dict(dict(zip(incorrect.index, incorrect.values))).mean(axis=1),
c='gray', label='incorrect trial')
plt.axvline(x=0, label='stimOn', linestyle='--', c='r')
plt.title(f'{feature.split("_")[0].capitalize()} speed ({cam} cam)')
plt.title(f'{feature.capitalize()} speed trial avg\n({cam.upper()} cam)')
plt.xticks([-0.5, 0, 0.5, 1, 1.5])
plt.xlabel('time [sec]')
plt.ylabel('speed [px/sec]')
Expand Down Expand Up @@ -559,8 +560,8 @@ def plot_pupil_diameter_hist(pupil_diameter, cam_times, trials_df, cam='left'):
plt.plot(times, pupil_mean, label=align_to.split("_")[0], color=color)
plt.fill_between(times, pupil_mean + pupil_std, pupil_mean - pupil_std, color=color, alpha=0.5)
plt.axvline(x=0, linestyle='--', c='k')
plt.title(f'Pupil diameter ({cam} cam)')
plt.title(f'Pupil diameter trial avg\n({cam.upper()} cam)')
plt.xlabel('time [sec]')
plt.xticks([-0.5, 0, 0.5, 1, 1.5])
plt.ylabel('pupil diameter [px]')
plt.ylabel('z-scored smoothed pupil diameter [px]')
plt.legend(loc='lower right', title='aligned to')
27 changes: 27 additions & 0 deletions brainbox/ephys_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,30 @@ def histc(x, bins):
return data.convert2dict(), fig, ax

return data


def image_raw_data(raw, fs, chn_coords=None, cmap='bone', title=None, display=False, gain=-90, **kwargs):

def gain2level(gain):
return 10 ** (gain / 20) * 4 * np.array([-1, 1])

ylabel = 'Channel index' if chn_coords is None else 'Distance from probe tip (um)'
title = title or 'Raw data'

y = np.arange(raw.shape[1]) if chn_coords is None else chn_coords[:, 1]

x = np.array([0, raw.shape[0] - 1]) / fs * 1e3

data = ImagePlot(raw, y=y, cmap=cmap)
data.set_labels(title=title, xlabel='Time (ms)',
ylabel=ylabel, clabel='Power (uV)')
clim = gain2level(gain)
data.set_clim(clim=clim)
data.set_xlim(xlim=x)
data.set_ylim()

if display:
ax, fig = plot_image(data.convert2dict(), **kwargs)
return data.convert2dict(), fig, ax

return data
33 changes: 25 additions & 8 deletions brainbox/io/one.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import pandas as pd
from scipy.interpolate import interp1d

from one.api import ONE
from one.api import ONE, One
import one.alf.io as alfio
from one.alf import cache

from iblutil.util import Bunch

from ibllib.io import spikeglx
from ibllib.io.extractors.training_wheel import extract_wheel_moves, extract_first_movement_times
from ibllib.ephys.neuropixel import SITES_COORDINATES, TIP_SIZE_UM, trace_header
Expand Down Expand Up @@ -872,10 +872,15 @@ def load_channels_from_insertion(ins, depths=None, one=None, ba=None):
class SpikeSortingLoader:
"""
Object that will load spike sorting data for a given probe insertion.
This class can be instantiated in several manners
- With Alyx database probe id:
SpikeSortingLoader(pid=pid, one=one)
- With Alyx database eic and probe name:
SpikeSortingLoader(eid=eid, pname='probe00', one=one)
- From a local session and probe name:
SpikeSortingLoader(session_path=session_path, pname='probe00')
"""
one: ONE
one: ONE = None
atlas: None = None
pid: str = None
eid: str = ''
Expand All @@ -891,14 +896,26 @@ class SpikeSortingLoader:
spike_sorting_path: Path = None

def __post_init__(self):
# pid gets precedence
if self.pid is not None:
self.eid, self.pname = self.one.pid2eid(self.pid)
if self.atlas is None:
self.atlas = AllenAtlas()
self.session_path = self.one.eid2path(self.eid)
self.session_path = self.one.eid2path(self.eid)
# then eid / pname combination
elif self.session_path is None or self.session_path == '':
self.session_path = self.one.eid2path(self.eid)
# fully local providing a session path
else:
self.one = One(cache_dir=self.session_path.parents[2], mode='local')
df_sessions = cache._make_sessions_df(self.session_path)
self.one._cache['sessions'] = df_sessions.set_index('id')
self.one._cache['datasets'] = cache._make_datasets_df(self.session_path, hash_files=False)
self.eid = str(self.session_path.relative_to(self.session_path.parents[2]))
# populates default properties
self.collections = self.one.list_collections(
self.eid, filename='spikes*', collection=f"alf/{self.pname}*")
self.datasets = self.one.list_datasets(self.eid)
if self.atlas is None:
self.atlas = AllenAtlas()
self.files = {}

@staticmethod
Expand Down
16 changes: 10 additions & 6 deletions brainbox/io/spikeglx.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,13 @@ def stream(pid, t0, nsecs=1, one=None, cache_folder=None, remove_cached=False, t
:param one: An instance of ONE
:param cache_folder:
:param typ: 'ap' or 'lf'
:return: sr, dsets, t0
:return: sr, t0
"""
CHUNK_DURATION_SECS = 1 # the mtscomp chunk duration. Right now it's a constant
if nsecs > 10:
ValueError(f'Streamer works only with 10 or less seconds, set nsecs to lesss than {nsecs}')
ValueError(f'Streamer works only with 10 or less seconds, set nsecs to less than {nsecs}')
assert one
assert typ in ['lf', 'ap']
t0 = np.floor(t0 / CHUNK_DURATION_SECS) * CHUNK_DURATION_SECS

if cache_folder is None:
samples_folder = Path(one.alyx._par.CACHE_DIR).joinpath('cache', typ)

Expand All @@ -134,8 +133,13 @@ def stream(pid, t0, nsecs=1, one=None, cache_folder=None, remove_cached=False, t
ch_file = one._download_datasets(ch_rec)[0]
one._download_datasets(meta_rec)[0]

first_chunk = int(t0 / CHUNK_DURATION_SECS)
last_chunk = int((t0 + nsecs) / CHUNK_DURATION_SECS) - 1
import json
with open(ch_file) as fid:
chinfo = json.load(fid)
tbounds = np.array(chinfo['chunk_bounds']) / chinfo['sample_rate']
first_chunk = np.maximum(0, np.searchsorted(tbounds, t0 + 0.01) - 1)
last_chunk = np.maximum(0, np.searchsorted(tbounds, t0 + + 0.01 + nsecs) - 2)
t0 = tbounds[first_chunk]

samples_folder.mkdir(exist_ok=True, parents=True)
sr = spikeglx.download_raw_partial(
Expand Down
6 changes: 5 additions & 1 deletion brainbox/plot_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ def _get_scale(self, axis):
:param axis: 'x' or 'y'
:return:
"""
lim = self._set_lim(axis)
if axis == 'x':
lim = self.xlim
else:
lim = self.ylim
lim = self._set_lim(axis, lim=lim)
scale = (lim[1] - lim[0]) / self.data['c'].shape[axis_dict[axis]]
return scale

Expand Down
217 changes: 217 additions & 0 deletions examples/atlas/Working with ibllib atlas.ipynb

Large diffs are not rendered by default.

Loading

0 comments on commit 2e1f91c

Please sign in to comment.