Skip to content

Commit 931abc9

Browse files
mayofaulknerk1o0oliche
authored
Atlas maps (#391)
* update beryl and add new atlas mapping * add test * add test for retina * ONE documentation * docstring to trigger CI * merge conflict Co-authored-by: Miles Wells <[email protected]> Co-authored-by: olivier <[email protected]>
1 parent 8a33b2d commit 931abc9

File tree

7 files changed

+155
-53
lines changed

7 files changed

+155
-53
lines changed

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
include ibllib/atlas/allen_structure_tree.csv
22
include ibllib/atlas/beryl.npy
3+
include ibllib/atlas/cosmos.npy
34
include ibllib/io/extractors/extractor_types.json
45
include brainbox/tests/wheel_test.p
56
recursive-include brainbox/tests/fixtures *

brainbox/io/one.py

Lines changed: 141 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Functions for loading IBL ephys and trial data using the Open Neurophysiology Environment."""
12
import logging
23
import os
34

@@ -111,19 +112,43 @@ def _channels_alf2bunch(channels, brain_regions=None):
111112
def _load_spike_sorting(eid, one=None, collection=None, revision=None, return_channels=True, dataset_types=None,
112113
brain_regions=None):
113114
"""
114-
Generic function to load spike sortin according to one searchwords
115+
Generic function to load spike sorting according data using ONE.
116+
115117
Will try to load one spike sorting for any probe present for the eid matching the collection
116118
For each probe it will load a spike sorting:
117119
- if there is one version: loads this one
118120
- if there are several versions: loads pykilosort, if not found the shortest collection (alf/probeXX)
119121
120-
:param eid: experiment ID
121-
:param one: one instance
122-
:param collection: collection filter word - accepts wildcard - can be a combination of spike sorter and probe
123-
:param revision: revision to load
124-
:param return_channels: True
125-
:param brain_regions: ibllib.atlas.regions.BrainRegions object - will label acronyms if provided
126-
:return:
122+
Parameters
123+
----------
124+
eid : [str, UUID, Path, dict]
125+
Experiment session identifier; may be a UUID, URL, experiment reference string
126+
details dict or Path
127+
one : one.api.OneAlyx
128+
An instance of ONE (may be in 'local' mode)
129+
collection : str
130+
collection filter word - accepts wildcards - can be a combination of spike sorter and
131+
probe. See `ALF documentation`_ for details.
132+
revision : str
133+
A particular revision return (defaults to latest revision). See `ALF documentation`_ for
134+
details.
135+
return_channels : bool
136+
Defaults to False otherwise loads channels from disk (takes longer)
137+
138+
.. _ALF documentation: https://one.internationalbrainlab.org/alf_intro.html#optional-components
139+
140+
Returns
141+
-------
142+
spikes : dict of one.alf.io.AlfBunch
143+
A dict with probe labels as keys, contains bunch(es) of spike data for the provided
144+
session and spike sorter, with keys ('clusters', 'times')
145+
clusters : dict of one.alf.io.AlfBunch
146+
A dict with probe labels as keys, contains bunch(es) of cluster data, with keys
147+
('channels', 'depths', 'metrics')
148+
channels : dict of one.alf.io.AlfBunch
149+
A dict with probe labels as keys, contains channel locations with keys ('acronym',
150+
'atlas_id', 'x', 'y', 'z'). Only returned when return_channels is True. Atlas IDs
151+
non-lateralized.
127152
"""
128153
one = one or ONE()
129154
# enumerate probes and load according to the name
@@ -141,11 +166,9 @@ def _load_spike_sorting(eid, one=None, collection=None, revision=None, return_ch
141166
attribute=spike_attributes)
142167
clusters[pname] = one.load_object(eid, collection=probe_collection, obj='clusters',
143168
attribute=cluster_attributes)
144-
145-
channels = _load_channels_locations_from_disk(eid, collection=collection, one=one, revision=revision,
146-
brain_regions=brain_regions)
147-
148169
if return_channels:
170+
channels = _load_channels_locations_from_disk(
171+
eid, collection=collection, one=one, revision=revision, brain_regions=brain_regions)
149172
return spikes, clusters, channels
150173
else:
151174
return spikes, clusters
@@ -296,13 +319,27 @@ def _load_channel_locations_traj(eid, probe=None, one=None, revision=None, align
296319

297320
def load_channel_locations(eid, probe=None, one=None, aligned=False, brain_atlas=None):
298321
"""
299-
TODO
300-
:param eid:
301-
:param probe:
302-
:param one:
303-
:param aligned:
304-
:param brain_regions:
305-
:return:
322+
Load the brain locations of each channel for a given session/probe
323+
324+
Parameters
325+
----------
326+
eid : [str, UUID, Path, dict]
327+
Experiment session identifier; may be a UUID, URL, experiment reference string
328+
details dict or Path
329+
probe : [str, list of str]
330+
The probe label(s), e.g. 'probe01'
331+
one : one.api.OneAlyx
332+
An instance of ONE (shouldn't be in 'local' mode)
333+
aligned : bool
334+
Whether to get the latest user aligned channel when not resolved or use histology track
335+
brain_atlas : ibllib.atlas.BrainAtlas
336+
Brain atlas object (default: Allen atlas)
337+
338+
Returns
339+
-------
340+
dict of one.alf.io.AlfBunch
341+
A dict with probe labels as keys, contains channel locations with keys ('acronym',
342+
'atlas_id', 'x', 'y', 'z'). Atlas IDs non-lateralized.
306343
"""
307344
one = one or ONE()
308345
brain_atlas = brain_atlas or AllenAtlas()
@@ -391,15 +428,37 @@ def load_spike_sorting_with_channel(eid, one=None, probe=None, aligned=False, da
391428
"""
392429
For a given eid, get spikes, clusters and channels information, and merges clusters
393430
and channels information before returning all three variables.
394-
:param eid:
395-
:param one:
396-
:param aligned: whether to get the latest user aligned channel when not resolved or use
397-
histology track
398-
:param dataset_types: additional spikes/clusters objects to add to the standard default list
399-
:param spike_sorter: name of the spike sorting you want to load (None for default which is
400-
pykilosort if it's available otherwise the default matlab kilosort)
401-
:param brain_atlas: allen atlas object
402-
:return: spikes, clusters, channels (dict of bunch, 1 bunch per probe)
431+
432+
Parameters
433+
----------
434+
eid : [str, UUID, Path, dict]
435+
Experiment session identifier; may be a UUID, URL, experiment reference string
436+
details dict or Path
437+
one : one.api.OneAlyx
438+
An instance of ONE (shouldn't be in 'local' mode)
439+
probe : [str, list of str]
440+
The probe label(s), e.g. 'probe01'
441+
aligned : bool
442+
Whether to get the latest user aligned channel when not resolved or use histology track
443+
dataset_types : list of str
444+
Optional additional spikes/clusters objects to add to the standard default list
445+
spike_sorter : str
446+
Name of the spike sorting you want to load (None for default which is pykilosort if it's
447+
available otherwise the default MATLAB kilosort)
448+
brain_atlas : ibllib.atlas.BrainAtlas
449+
Brain atlas object (default: Allen atlas)
450+
451+
Returns
452+
-------
453+
spikes : dict of one.alf.io.AlfBunch
454+
A dict with probe labels as keys, contains bunch(es) of spike data for the provided
455+
session and spike sorter, with keys ('clusters', 'times')
456+
clusters : dict of one.alf.io.AlfBunch
457+
A dict with probe labels as keys, contains bunch(es) of cluster data, with keys
458+
('channels', 'depths', 'metrics')
459+
channels : dict of one.alf.io.AlfBunch
460+
A dict with probe labels as keys, contains channel locations with keys ('acronym',
461+
'atlas_id', 'x', 'y', 'z'). Atlas IDs non-lateralized.
403462
"""
404463
# --- Get spikes and clusters data
405464
one = one or ONE()
@@ -424,15 +483,29 @@ def load_ephys_session(eid, one=None):
424483
'spikes.clusters',
425484
'spikes.times',
426485
'probes.description'
427-
:param eid: experiment UUID or pathlib.Path of the local session
428-
:param one: one instance
429-
:return: spikes, clusters, trials (dict of bunch, 1 bunch per probe)
486+
487+
Parameters
488+
----------
489+
eid : [str, UUID, Path, dict]
490+
Experiment session identifier; may be a UUID, URL, experiment reference string
491+
details dict or Path
492+
one : oneibl.one.OneAlyx, optional
493+
ONE object to use for loading. Will generate internal one if not used, by default None
494+
495+
Returns
496+
-------
497+
spikes : dict of one.alf.io.AlfBunch
498+
A dict with probe labels as keys, contains bunch(es) of spike data for the provided
499+
session and spike sorter, with keys ('clusters', 'times')
500+
clusters : dict of one.alf.io.AlfBunch
501+
A dict with probe labels as keys, contains bunch(es) of cluster data, with keys
502+
('channels', 'depths', 'metrics')
503+
trials : one.alf.io.AlfBunch of numpy.ndarray
504+
The session trials data
430505
"""
431506
assert one
432-
433507
spikes, clusters = load_spike_sorting(eid, one=one)
434508
trials = one.load_object(eid, 'trials')
435-
436509
return spikes, clusters, trials
437510

438511

@@ -452,11 +525,20 @@ def merge_clusters_channels(dic_clus, channels, keys_to_add_extra=None):
452525
"""
453526
Takes (default and any extra) values in given keys from channels and assign them to clusters.
454527
If channels does not contain any data, the new keys are added to clusters but left empty.
455-
:param dic_clus: dict of bunch, 1 bunch per probe, containing cluster information
456-
:param channels: dict of bunch, 1 bunch per probe, containing channels information
457-
:param keys_to_add_extra: Any extra keys contained in channels (will be added to default
458-
['acronym', 'atlas_id'])
459-
:return: clusters (dict of bunch, 1 bunch per probe), with new keys values.
528+
529+
Parameters
530+
----------
531+
dic_clus : dict of one.alf.io.AlfBunch
532+
1 bunch per probe, containing cluster information
533+
channels : dict of one.alf.io.AlfBunch
534+
1 bunch per probe, containing channels bunch with keys ('acronym', 'atlas_id')
535+
keys_to_add_extra : list of str
536+
Any extra keys to load into channels bunches
537+
538+
Returns
539+
-------
540+
dict of one.alf.io.AlfBunch
541+
clusters (1 bunch per probe) with new keys values.
460542
"""
461543
probe_labels = list(channels.keys()) # Convert dict_keys into list
462544
keys_to_add_default = ['acronym', 'atlas_id', 'x', 'y', 'z']
@@ -494,9 +576,19 @@ def merge_clusters_channels(dic_clus, channels, keys_to_add_extra=None):
494576
def load_passive_rfmap(eid, one=None):
495577
"""
496578
For a given eid load in the passive receptive field mapping protocol data
497-
:param eid: eid or pathlib.Path of the local session
498-
:param one:
499-
:return: rf_map
579+
580+
Parameters
581+
----------
582+
eid : [str, UUID, Path, dict]
583+
Experiment session identifier; may be a UUID, URL, experiment reference string
584+
details dict or Path
585+
one : oneibl.one.OneAlyx, optional
586+
An instance of ONE (may be in 'local' - offline - mode)
587+
588+
Returns
589+
-------
590+
one.alf.io.AlfBunch
591+
Passive receptive field mapping data
500592
"""
501593
one = one or ONE()
502594

@@ -524,10 +616,11 @@ def load_wheel_reaction_times(eid, one=None):
524616
525617
Parameters
526618
----------
527-
eid : str
528-
Session UUID
529-
one : oneibl.ONE
530-
An instance of ONE for loading data. If None a new one is instantiated using the defaults.
619+
eid : [str, UUID, Path, dict]
620+
Experiment session identifier; may be a UUID, URL, experiment reference string
621+
details dict or Path
622+
one : oneibl.one.OneAlyx, optional
623+
one object to use for loading. Will generate internal one if not used, by default None
531624
532625
Returns
533626
----------
@@ -566,8 +659,9 @@ def load_trials_df(eid, one=None, maxlen=None, t_before=0., t_after=0., ret_whee
566659
567660
Parameters
568661
----------
569-
eid : str
570-
Session UUID string to pass to ONE
662+
eid : [str, UUID, Path, dict]
663+
Experiment session identifier; may be a UUID, URL, experiment reference string
664+
details dict or Path
571665
one : oneibl.one.OneAlyx, optional
572666
one object to use for loading. Will generate internal one if not used, by default None
573667
maxlen : float, optional

ibllib/atlas/beryl.npy

-28 Bytes
Binary file not shown.

ibllib/atlas/cosmos.npy

160 Bytes
Binary file not shown.

ibllib/atlas/regions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
_logger = logging.getLogger('ibllib')
1111
# 'Beryl' is the name given to an atlas containing a subset of the most relevant allen annotations
1212
FILE_BERYL = str(Path(__file__).parent.joinpath('beryl.npy'))
13+
FILE_COSMOS = str(Path(__file__).parent.joinpath('cosmos.npy'))
1314
FILE_REGIONS = str(Path(__file__).parent.joinpath('allen_structure_tree.csv'))
1415

1516

@@ -33,6 +34,7 @@ class BrainRegions(_BrainRegions):
3334
def __init__(self):
3435
df_regions = pd.read_csv(FILE_REGIONS)
3536
beryl = np.load(FILE_BERYL)
37+
cosmos = np.load(FILE_COSMOS)
3638
# lateralize
3739
df_regions_left = df_regions.iloc[np.array(df_regions.id > 0), :].copy()
3840
df_regions_left['id'] = - df_regions_left['id']
@@ -57,6 +59,8 @@ def __init__(self):
5759
'Allen-lr': np.arange(self.id.size),
5860
'Beryl': self._mapping_from_regions_list(beryl, lateralize=False),
5961
'Beryl-lr': self._mapping_from_regions_list(beryl, lateralize=True),
62+
'Cosmos': self._mapping_from_regions_list(cosmos, lateralize=False),
63+
'Cosmos-lr': self._mapping_from_regions_list(cosmos, lateralize=True),
6064
}
6165

6266
def get(self, ids) -> Bunch:

ibllib/dsp/cadzow.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ def denoise(WAV, x, y, r, imax=None, niter=1):
5151
"""
5252
Applies cadzow denoising by de-ranking spatial matrices in frequency domain
5353
:param WAV: np array nc / ns in frequency domain
54-
:param x:
55-
:param y:
56-
:param r:
57-
:param imax:
58-
:param niter:
59-
:return:
54+
:param x: trace spatial coordinate (np.array)
55+
:param y: trace spatial coordinate (np.array)
56+
:param r: rank
57+
:param imax: index of the maximum frequency to keep, all frequencies are de-ranked if None (None)
58+
:param niter: number of iterations (1)
59+
:return: WAV_: np array nc / ns in frequency domain
6060
"""
6161
WAV_ = np.copy(WAV)
6262
imax = np.minimum(WAV.shape[-1], imax) if imax else WAV.shape[-1]

ibllib/tests/test_atlas.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ def test_lookups(self):
7676
# unlike the retina, root stays root whatever the mapping
7777
assert self.ba.get_labels([0, 0, 0]) == 0 # void !
7878
assert self.ba.get_labels([0, 0, 0], mapping='Beryl') == 0 # root
79+
# Check the cosmos mapping too
80+
assert self.ba.get_labels([0, 0, self.ba.bc.i2z(103)], mapping='Cosmos') == 997
81+
assert self.ba.get_labels([0, 0, 0], mapping='Cosmos') == 0
7982

8083
def test_slice(self):
8184
ba = self.ba

0 commit comments

Comments
 (0)