Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog
=========

UNRELEASED
------
* added: Neuropixel coordinate registration tool for NP2.4

8.30.0
------
* added: Online Plots are stored as PNG and added to Alyx as a Session Note
Expand Down
50 changes: 43 additions & 7 deletions iblrig/ephys.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import argparse
import string

import numpy as np

from iblatlas import atlas
from ibllib.ephys.spikes import create_insertion
from iblrig.base_tasks import EmptySession
from iblrig.transfer_experiments import EphysCopier
from iblutil.util import setup_logger
from one.webclient import no_cache as no_cache_context


def prepare_ephys_session_cmd():
Expand Down Expand Up @@ -37,7 +38,7 @@ def prepare_ephys_session(subject_name: str, nprobes: int = 2):
copier.initialize_experiment(nprobes=nprobes)


def neuropixel24_micromanipulator_coordinates(ref_shank, pname, ba=None, shank_spacings_um=(0, 200, 400, 600)):
def neuropixel24_micromanipulator_coordinates(ref_shank, pname, ba=None, shank_spacings_um=(0, 200, 400, 600), pivot_shank='a'):
"""
Provide the micro-manipulator coordinates of the first shank.

Expand All @@ -50,13 +51,22 @@ def neuropixel24_micromanipulator_coordinates(ref_shank, pname, ba=None, shank_s
:param shank_spacings_um: list of shank spacings in micrometers
:return:
"""
# this only works if the roll is 0, ie. the probe is facing upwards
assert ref_shank['roll'] == 0
ref_shank['roll'] = 0 # this is a constant and has no nmeaning for 4 shanks probes
if pivot_shank == 'd':
shank_letters = 'dcba'
spacing_sign = -1
elif pivot_shank == 'a':
shank_letters = 'abcd'
spacing_sign = 1
else:
raise ValueError("reference_shank parameter should be either 'a' or 'd'")

ba = atlas.NeedlesAtlas() if ba is None else ba
trajectories = {}
for i, d in enumerate(shank_spacings_um):
x = ref_shank['x'] + np.sin(ref_shank['phi'] / 180 * np.pi) * d
y = ref_shank['y'] - np.cos(ref_shank['phi'] / 180 * np.pi) * d
spacing_multiplier = d * spacing_sign # flip the direction if reference_shank is 'd'
x = ref_shank['x'] + np.sin(ref_shank['phi'] / 180 * np.pi) * spacing_multiplier
y = ref_shank['y'] - np.cos(ref_shank['phi'] / 180 * np.pi) * spacing_multiplier
shank = {
'x': x,
'y': y,
Expand All @@ -72,5 +82,31 @@ def neuropixel24_micromanipulator_coordinates(ref_shank, pname, ba=None, shank_s
xyz_ref = xyz_entry
shank['z'] = xyz_entry[2] * 1e6
shank['depth'] = ref_shank['depth'] + (xyz_entry[2] - xyz_ref[2]) * 1e6
trajectories[f'{pname}{string.ascii_lowercase[i]}'] = shank
trajectories[f'{pname}{shank_letters[i]}'] = shank
return trajectories


def register_micromanipulator_coordinates(alyx=None, trajectories=None, eid=None, metadata=None):
assert alyx is not None, 'An alyx client is required to register/create micromanipulator coordinates'
assert eid is not None, 'An session ID is required to register/create micromanipulator coordinates'
# if we do not have access to the fileName or any of the metadata, it will be patched later
metadata = {'neuropixelVersion': 'NP2.4', 'fileName': None, 'serial': -1} if metadata is None else metadata
rest_trajectories = {}
rest_insertions = {}
with no_cache_context(alyx):
traj_extra = {}
for pname, traj in trajectories.items():
_, rest_insertions[pname] = create_insertion(alyx, metadata, pname, eid=eid)
pid = rest_insertions[pname]['id']
traj_extra['probe_insertion'] = pid
traj_extra['chronic_insertion'] = None
traj_extra['provenance'] = 'Micro-manipulator'
traj_extra['coordinate_system'] = 'Needles-Allen'
rest_trajectory = alyx.rest('trajectories', 'list', probe_insertion=pid, provenance='Micro-manipulator')
if len(rest_trajectory) == 0:
rest_trajectories[pname] = alyx.rest('trajectories', 'create', data=traj | traj_extra)
else:
rest_trajectories[pname] = alyx.rest(
'trajectories', 'update', id=rest_trajectory[0]['id'], data=traj | traj_extra
)
return rest_insertions, rest_trajectories
99 changes: 0 additions & 99 deletions iblrig/gui/micromanipulator.py

This file was deleted.

Loading
Loading