Exemplo n.º 1
0
def probe_trajectory_coronal(
        eid, probe_label, one, ax=None):
    """
    Generates plots of coronal sections with the channel locations

    Args:
        eid (str): session uuid (eid) for one query
        probe_label (str): probe label, e.g. probe00
        one (ONE instance): ONE instance, pre instantiated ONE instance
        ax (matplotlib.axes.Axes object, optional): Defaults to None

    Returns:
        ax (matplotlib.axes.Axes object): Axes with coronal section plotted
    """

    one.path_from_eid(eid)
    traj = one.alyx.rest(
        'trajectories', 'list', session=eid,
         provenance='Ephys Aligned Histology Track', probe=probe_label)[0]
    channels = bbone.load_channel_locations(eid=eid, one=one, probe=probe_label)

    picks = one.alyx.rest('insertions', 'read', id=traj['probe_insertion'])['json']
    picks = np.array(picks['xyz_picks']) / 1e6
    ins = atlas.Insertion.from_dict(traj)

    if ax is None:
        fig, ax = plt.subplots(1, 1, dpi=100, frameon=False)

    ax = ba_allen.plot_tilted_slice(xyz=picks, axis=1, volume='image', ax=ax)
    ax.plot(picks[:, 0] * 1e6, picks[:, 2] * 1e6)
    ax.plot(channels[probe_label].x * 1e6, channels[probe_label].z * 1e6, 'g*')

    return ax
Exemplo n.º 2
0
# Test with eid that does not have any probe planned/histology values in Alyx
# eid = 'da188f2c-553c-4e04-879b-c9ea2d1b9a93'

# ----- RECOMMENDED: Option 1 (default) ------
# 1. Get spikes, cluster (with brain regions assigned to clusters) and channels
spikes, clusters, channels = bbone.load_spike_sorting_with_channel(eid,
                                                                   one=one)
del spikes, clusters, channels  # Delete for the purpose of the example

# ---------------------------------------------
# 2. Get only spikes and clusters (without brain regions assigned to clusters)
#    data separately from channels
#    Use merger function to get channels information into clusters
#    Adding feature x, y from default
spikes, clusters = bbone.load_spike_sorting(eid, one=one)
channels = bbone.load_channel_locations(eid, one=one)
keys = ['x', 'y']
clusters_brain = bbone.merge_clusters_channels(clusters,
                                               channels,
                                               keys_to_add_extra=keys)
del spikes, clusters, clusters_brain, channels  # Delete for the purpose of the example

# ---------------------------------------------
# 3. I don't want to connect to ONE and I already know my session path
session_path = one.path_from_eid(eid)  # replace by your local path
spikes, clusters = bbone.load_spike_sorting(session_path, one=one)
# TODO offline loading of channel locations ? Probably by caching the queries.

# ---------------- WIP ---------------------

# TODO one.load_object(): return dict of bunch
"""
# Author: Olivier Winter

import numpy as np
from one.api import ONE

import ibllib.atlas as atlas
import brainbox.io.one as bbone

# === Parameters section (edit) ===
eid = 'c7bd79c9-c47e-4ea5-aea3-74dda991b48e'
probe_label = 'probe01'
# === Code (do not edit) ===
ba = atlas.AllenAtlas(25)
one = ONE(base_url='https://openalyx.internationalbrainlab.org')
traj = one.alyx.rest('trajectories',
                     'list',
                     session=eid,
                     provenance='Ephys aligned histology track',
                     probe=probe_label)[0]
channels = bbone.load_channel_locations(eid=eid, one=one, probe=probe_label)

picks = one.alyx.rest('insertions', 'read', id=traj['probe_insertion'])['json']
picks = np.array(picks['xyz_picks']) / 1e6
ins = atlas.Insertion.from_dict(traj)

cax = ba.plot_tilted_slice(xyz=picks, axis=1, volume='image')
cax.plot(picks[:, 0] * 1e6, picks[:, 2] * 1e6)
cax.plot(channels[probe_label]['x'] * 1e6, channels[probe_label]['z'] * 1e6,
         'g*')
Exemplo n.º 4
0
from ibllib.pipes.ephys_alignment import EphysAlignment
from oneibl.one import ONE
from brainbox.io.one import load_channel_locations
import numpy as np
import matplotlib.pyplot as plt

one = ONE(base_url="https://alyx.internationalbrainlab.org")
# Load data from 'ZM_2407' '2019-12-06'
eid = '03d3cffc-755a-43db-a839-65d8359a7b93'
probe = 'probe_00'
channels = load_channel_locations(eid, one=one, probe=probe)
# xyz coords of channels
xyz_channels = np.c_[channels[probe].x, channels[probe].y, channels[probe].z]
# depth along probe of channels
depths = channels[probe].axial_um
region, region_label, region_colour, region_id = EphysAlignment.get_histology_regions(xyz_channels, depths)

fig, ax1 = plt.subplots(figsize=(4,10))
for reg, col in zip(region, region_colour):
    height = np.abs(reg[1]- reg[0])
    bottom = reg[0]
    color = col/255
    ax1.bar(x=0.5, height=height, width=1, color=color, bottom=reg[0], edgecolor='w')

ax1.set_yticks(region_label[:, 0].astype(int))
ax1.set_yticklabels(region_label[:, 1])
ax1.hlines([0, 3840], *ax1.get_xlim(), linestyles='dashed', linewidth = 3, colors='k')
plt.show()

Exemplo n.º 5
0
def download_ch_disp_data(x,
                          y,
                          provenance='Planned',
                          project='ibl_neuropixel_brainwide_01'):
    """Download channels displacement data for all given probes at the planned 
    insertion coord [x,y] from Alyx
    
    Downloads the most up-to-date data from Alyx for all recordings at [x,y],
    including their channel positionss, and the orthogonal points of each 
    channel from the planned trajectory.
    
    Saves this data to a standard location in the file system.
    
    Also returns this data as a pandas DataFrame object with following:
    
    * subject, eid, probe - the subject, eid and probe IDs
    * chan_loc - xyz coords of all channels
    * planned_orth_proj - xyz coord of orthogonal line from chan_loc onto planned proj
    * dist - the euclidean distance between chan_loc xyz and planned_orth_proj xyz
    
    Parameters
    ----------
    x : int
        x planned insertion coord in µm.  Eg. repeated site is -2243
    y : int
        y planned insertion coord in µm. Eg. repeated site is -2000.
    provenance : str, optional
        Probe provenance to list trajectories from: Planned, Micro-manipulator, 
        Histology, E-phys aligned. The default is 'Planned'.
    project : str, optional
        Project to gather all trajectories from. The default is 
        'ibl_neuropixel_brainwide_01'.

    Returns
    -------
    data_frame : pandas DataFrame
        Dataframe containing: subject, eid, probe; ins_x, ins_y; chan_loc; 
        planned_orth_proj; dist.

    """

    from one.api import ONE
    from ibllib.atlas import Insertion
    import brainbox.io.one as bbone
    #from ibllib.io import params - deprecated!

    # for catching errors in collecting datasets
    from ibllib.exceptions import IblError
    from urllib.error import HTTPError

    import numpy as np
    import pandas as pd
    from pathlib import Path

    # in format -2000_-2243
    prefix = str(str(x) + "_" + str(y))

    # connect to ONE
    one = ONE()

    # get the planned trajectory for repeated site: x=2243, y=2000
    traj = one.alyx.rest('trajectories',
                         'list',
                         provenance=provenance,
                         x=x,
                         y=y,
                         project=project)

    # from this collect all eids, probes, subjects that use repeated site:
    eids = [sess['session']['id'] for sess in traj]
    probes = [sess['probe_name'] for sess in traj]
    subj = [sess['session']['subject'] for sess in traj]

    # new dict to store data from loop:
    # chan_loc - xyz coord of channels
    # planned_orth_proj - xyz coord of orthogonal line from chan_loc to planned
    #   proj
    # dist - the 3D distance between chan_loc xyz and planned_orth_proj xyz
    data = {
        'subject': [],
        'lab': [],
        'eid': [],
        'probe': [],
        'ins_x': [],
        'ins_y': [],
        'chan_loc_x': [],
        'chan_loc_y': [],
        'chan_loc_z': [],
        'planned_orth_proj_x': [],
        'planned_orth_proj_y': [],
        'planned_orth_proj_z': [],
        'dist': [],
    }

    # Fetch Repeated Site planned trajectory metadata:
    planned = one.alyx.rest('trajectories',
                            'list',
                            session=eids[0],
                            probe=probes[0],
                            provenance='planned')

    # create insertion object of probe from planned trajectory:
    ins = Insertion.from_dict(planned[0])

    # create a trajectory object of Planned Repeated Site from this insertion:
    traj = ins.trajectory

    subindex = 0

    # loop through each eid/probe:
    for eid, probe in zip(eids, probes):

        print(
            "=================================================================="
        )
        print(eids.index(eid))
        print(eid)
        print(probe)
        print(subj[subindex])
        subindex = subindex + 1

        # get the eid/probe as insertion
        insertion = one.alyx.rest('insertions',
                                  'list',
                                  session=eid,
                                  name=probe)

        if insertion:

            print("  insertion exists")

            # check if histology has been traced and loaded
            tracing = np.array(insertion[0]['json'])

            if tracing:

                print("  tracing exists")

                # For this insertion which has histology tracing, retrieve the
                # channels in xyz coords:

                # check the localCoordinates EXIST for this eid/probe
                # run in a try..except statement to continue over the eid/probe
                # if localCoordinates dataset does not exist
                try:
                    channel_coord = one.load_dataset(
                        eid,
                        'channels.localCoordinates.npy',
                        collection='alf/' + probe)
                except IblError:
                    print("ALFObjectNotFound")
                    print("")
                    continue
                except HTTPError:
                    print("HTTPError")
                    print("")
                    continue
                except:
                    print("ERROR - generic")
                    continue

                # only proceed if channel_coord is not None
                if channel_coord is None:
                    continue

                print("  channel_coords exist")

                if one.alyx.rest('trajectories',
                                 'list',
                                 session=eid,
                                 probe=probe,
                                 provenance='Histology track') == []:
                    print("ERROR - no Histology Track..")
                    continue

                chan_loc = bbone.load_channel_locations(eid,
                                                        one=one,
                                                        probe=probe)

                print("chan_loc")

                # only proceed if channel locations could be retrieved
                if not chan_loc:
                    continue

                # Next, create a representation of the planned trajectory as a
                # line:
                plannedTraj = one.alyx.rest('trajectories',
                                            'list',
                                            session=eid,
                                            probe=probe,
                                            provenance='planned')

                print("plannedTraj")

                # create insertion object from planned trajectory:
                #ins = Insertion.from_dict(planned[0])

                # create a trajectory object from this insertion:
                #traj = ins.trajectory

                # NEXT - compute the projected coord for each channel coord onto the
                # line defined by traj:
                for ch_ind in range(len(chan_loc[probe]['x'])):

                    cl_x = chan_loc[probe]['x'][ch_ind]
                    cl_y = chan_loc[probe]['y'][ch_ind]
                    cl_z = chan_loc[probe]['z'][ch_ind]

                    # create numpy array from chan_loc coords:
                    ch_loc = np.array([cl_x, cl_y, cl_z])

                    # project the current chan_loc to the PLANNED trajectory:
                    proj = traj.project(ch_loc)

                    # calculate the distance between proj and chan_loc:
                    dist = np.linalg.norm(ch_loc - proj)

                    data['subject'].append(
                        plannedTraj[0]['session']['subject'])
                    data['lab'].append(plannedTraj[0]['session']['lab'])
                    data['eid'].append(eid)
                    data['probe'].append(probe)
                    data['ins_x'].append(probe)
                    data['ins_y'].append(probe)
                    data['chan_loc_x'].append(cl_x)
                    data['chan_loc_y'].append(cl_y)
                    data['chan_loc_z'].append(cl_z)
                    data['planned_orth_proj_x'].append(proj[0])
                    data['planned_orth_proj_y'].append(proj[1])
                    data['planned_orth_proj_z'].append(proj[2])
                    data['dist'].append(dist)

    # convert data to a Pandas DataFrame:
    data_frame = pd.DataFrame.from_dict(data)

    save_ch_disp_data(data_frame, prefix)

    return data_frame
Exemplo n.º 6
0
from brainbox.io.one import load_spike_sorting, load_channel_locations
from oneibl.one import ONE

one = ONE(base_url="https://dev.alyx.internationalbrainlab.org")
eids = one.search(subject='ZM_2407', task_protocol='ephys')

channels = load_channel_locations(eids[0], one=one)
spikes, clusters = load_spike_sorting(eids[0], one=one)