From 9112e43310346582b170169fecb5eea177772cb2 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Thu, 15 May 2025 14:27:03 +0100 Subject: [PATCH 01/11] initial commit --- .gitignore | 1 - resources/generate_neuropixels_library.py | 21 +- src/probeinterface/neuropixels_tools.py | 672 ++---- .../resources/probe_features.json | 2086 +++++++++++++++++ tests/test_io/test_openephys.py | 13 - tests/test_io/test_spikeglx.py | 22 +- tests/test_neuropixels_backwards_compat.py | 532 +++++ 7 files changed, 2808 insertions(+), 539 deletions(-) create mode 100644 src/probeinterface/resources/probe_features.json create mode 100644 tests/test_neuropixels_backwards_compat.py diff --git a/.gitignore b/.gitignore index 5f8e41d0..d83456d9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ tests/*.prb tests/*.json tests/*/*.prb -*.json *.prb tests/*/*.json tests/*/*.tsv diff --git a/resources/generate_neuropixels_library.py b/resources/generate_neuropixels_library.py index 90ed1b79..6b8db46f 100644 --- a/resources/generate_neuropixels_library.py +++ b/resources/generate_neuropixels_library.py @@ -1,10 +1,12 @@ import shutil from pathlib import Path +import json + import numpy as np import matplotlib.pyplot as plt -from probeinterface.neuropixels_tools import npx_descriptions, probe_part_number_to_probe_type, _make_npx_probe_from_description +from probeinterface.neuropixels_tools import make_npx_description, _make_npx_probe_from_description from probeinterface.plotting import plot_probe from probeinterface import write_probeinterface @@ -18,24 +20,24 @@ def generate_all_npx(): # if not base_folder.exists(): base_folder.mkdir(exist_ok=True) + probe_features_filepath = Path(__file__).absolute().parent / Path("../src/probeinterface/resources/probe_features.json") + probe_features = json.load(open(probe_features_filepath, "r")) + probe_part_numbers = probe_features['neuropixels_probes'].keys() + - for probe_number, probe_type in probe_part_number_to_probe_type.items(): + for probe_number in probe_part_numbers: if probe_number is None: continue - if probe_number == "1110": + if probe_number == "NP1110": # the formula by the imrow table is wrong and more complicated continue probe_folder = base_folder / probe_number probe_folder.mkdir(exist_ok=True) - print(probe_number, probe_type) - - probe_description = npx_descriptions[probe_type] - - + probe_description = make_npx_description(probe_number) num_shank = probe_description["shank_number"] contact_per_shank = probe_description["ncols_per_shank"] * probe_description["nrows_per_shank"] @@ -99,8 +101,5 @@ def generate_all_npx(): - - - if __name__ == "__main__": generate_all_npx() diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index 58001741..a9c727f7 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -12,471 +12,13 @@ from typing import Union, Optional import warnings from packaging.version import parse +import json import numpy as np from .probe import Probe from .utils import import_safely - -# this dict define the contour for one shank (duplicated when several shanks so) -# note that a final "contour_shift" is applied -polygon_contour_description = { - # NP1 and NP2 (1 and 4 shanks) - "np70": [ - (0, 10000), - (0, 0), - (35, -175), - (70, 0), - (70, 10000), - ], - "nhp90": [ - (0, 10000), - (0, 0), - (45, -342), - (90, 0), - (90, 10000), - ], - "nhp125": [ - (0, 10000), - (0, 0), - (62.5, -342), - (125, 0), - (125, 10000), - ], -} - - -# IMPORTANT -# A map from probe type to geometry_parameters -# Here the key is "imDatPrb_type" in the metadata -# for a good understanding of this fields please read the _read_imro_string() function -# The main formula of the contact positions is this one -# y_idx, x_idx = np.divmod(elec_ids, probe_description["ncols_per_shank"]) -# stagger = np.mod(y_idx + 1, 2) * probe_description["stagger"] -# x_pos = x_idx * x_pitch + stagger -# y_pos = y_idx * y_pitch - -npx_descriptions = { - # Neuropixels 1.0 - # This probably should be None or something else because NOT ONLY the neuropixels 1.0 have that imDatPrb_type - "0": { - "model_name": "Neuropixels 1.0", - "x_pitch": 32, - "y_pitch": 20, - "contact_width": 12, - "stagger": 16, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 480, - "contour_description": "np70", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Neuropixels 2.0 - Single Shank - Prototype - "21": { - "model_name": "Neuropixels 2.0 - Single Shank - Prototype", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), - }, - # Neuropixels 2.0 - Four Shank - Prototype - "24": { - "model_name": "Neuropixels 2.0 - Four Shank - Prototype", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 250, - "shank_number": 4, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ( - "channel_ids", - "shank_id", - "banks", - "references", - "elec_ids", - ), - }, - # Neuropixels 2.0 - Single Shank - Commercial without metal cap - "2003": { - "model_name": "Neuropixels 2.0 - Single Shank", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), - }, - # Neuropixels 2.0 - Single Shank - Commercial with metal cap - "2004": { - "model_name": "Neuropixels 2.0 - Single Shank", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), - }, - # Neuropixels 2.0 - Four Shank - Commercial without metal cap - "2013": { - "model_name": "Neuropixels 2.0 - Four Shank", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 250, - "shank_number": 4, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ( - "channel_ids", - "shank_id", - "banks", - "references", - "elec_ids", - ), - }, - # Neuropixels 2.0 - Four Shank - Commercial with metal cap - "2014": { - "model_name": "Neuropixels 2.0 - Four Shank", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 250, - "shank_number": 4, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ( - "channel_ids", - "shank_id", - "banks", - "references", - "elec_ids", - ), - }, - # Neuropixels 2.0 Quad Base - "2020": { - "model_name": "Neuropixels 2.0 - Quad Base", - "x_pitch": 32, - "y_pitch": 15, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 250, - "shank_number": 4, - "ncols_per_shank": 2, - "nrows_per_shank": 640, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ( - "channel_ids", - "shank_id", - "banks", - "references", - "elec_ids", - ), - }, - # Experimental probes previous to 1.0 - "Phase3a": { - "model_name": "Phase3a", - "x_pitch": 32, - "y_pitch": 20, - "contact_width": 12, - "stagger": 16.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 480, - "contour_description": "np70", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - ), - }, - # Neuropixels 1.0-NHP Short (10mm) - "1015": { - "model_name": "Neuropixels 1.0-NHP - short", - "x_pitch": 32, - "y_pitch": 20, - "contact_width": 12, - "stagger": 0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 480, - "contour_description": "np70", - "contour_shift": [-27, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - ################# - # Neuropixels 1.0-NHP Medium (25mm) - "1020": { - "model_name": "Neuropixels 1.0-NHP - medium - staggered", - "x_pitch": 103 - 12, - "y_pitch": 20, - "contact_width": 12, - "stagger": 12.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 - "contour_description": "nhp125", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Neuropixels 1.0-NHP Medium (25mm) - "1021": { - "model_name": "Neuropixels 1.0-NHP - medium - staggered", - "x_pitch": 103 - 12, - "y_pitch": 20, - "contact_width": 12, - "stagger": 12.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 - "contour_description": "nhp125", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - ################# - # Neuropixels 1.0-NHP Medium (25mm) - "1022": { - "model_name": "Neuropixels 1.0-NHP - medium", - "x_pitch": 103, - "y_pitch": 20, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 - "contour_description": "nhp125", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Neuropixels 1.0-NHP 45mm SOI90 - NHP long 90um wide, staggered contacts - "1030": { - "model_name": "Neuropixels 1.0-NHP - long SOI90 staggered", - "x_pitch": 56, - "y_pitch": 20, - "stagger": 12, - "contact_width": 12, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 2208, - "contour_description": "nhp90", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Neuropixels 1.0-NHP 45mm SOI125 - NHP long 125um wide, staggered contacts - "1031": { - "model_name": "Neuropixels 1.0-NHP - long SOI125 staggered", - "x_pitch": 91, - "y_pitch": 20, - "contact_width": 12, - "stagger": 12.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 2208, - "contour_description": "nhp125", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # 1.0-NHP 45mm SOI115 / 125 linear - NHP long 125um wide, linear contacts - "1032": { - "model_name": "Neuropixels 1.0-NHP - long SOI125 linear", - "x_pitch": 103, - "y_pitch": 20, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 2208, - "contour_description": "nhp125", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Ultra probes 1 bank - "1100": { - "model_name": "Neuropixels Ultra (1 bank)", - "x_pitch": 6, - "y_pitch": 6, - "contact_width": 5, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 8, - "nrows_per_shank": 48, - "contour_description": "np70", - "contour_shift": [-14, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # Ultra probes 16 banks - "1110": { - "model_name": "Neuropixels Ultra (16 banks)", - "x_pitch": 6, - "y_pitch": 6, - "contact_width": 5, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 8, - "nrows_per_shank": 768, - "contour_description": "np70", - "contour_shift": [-14, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - "1121": { - "model_name": "Neuropixels Ultra - Type 2", - "x_pitch": 6, - "y_pitch": 3, - "contact_width": 2, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 1, - "nrows_per_shank": 384, - "contour_description": "np70", - "contour_shift": [-6.25, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, - # NP-Opto - "1300": { - "model_name": "Neuropixels Opto", - "x_pitch": 48, - "y_pitch": 20, - "contact_width": 12, - "stagger": 0.0, - "shank_pitch": 0, - "shank_number": 1, - "ncols_per_shank": 2, - "nrows_per_shank": 480, - "contour_description": "np70", - "contour_shift": [-11, -11], - "fields_in_imro_table": ( - "channel_ids", - "banks", - "references", - "ap_gains", - "lf_gains", - "ap_hp_filters", - ), - }, -} - - # Map imDatPrb_pn (probe number) to imDatPrb_type (probe type) when the latter is missing probe_part_number_to_probe_type = { # for old version without a probe number we assume NP1.0 @@ -515,10 +57,142 @@ "NP1121": "1121", # Ultra probe - beta configuration # Opto "NP1300": "1300", # Opto probe - # missing NP1200 - # missing NXT3000 } +probe_type_to_probe_part_number = {v: k for k, v in probe_part_number_to_probe_type.items()} + +imro_field_to_pi_field = { + "ap_gain": "ap_gains", + "ap_hipas_flt": "ap_hp_filters", + "bank": "banks", + "bank_mask": "banks", + "channel": "channel_ids", + "electrode": "elec_ids", + "lf_gain": "lf_gains", + "ref_id": "references", + "shank": "shank_id", + "group": "group", + "bankA": "bankA", + "bankB": "bankB", +} + +pi_to_pt_names = { + 'x_pitch': 'electrode_pitch_horz_um', + 'y_pitch': 'electrode_pitch_vert_um', + 'contact_width': 'electrode_size_horz_direction_um', + 'shank_pitch': 'shank_pitch_um', + 'shank_number': 'num_shanks', + 'ncols_per_shank': 'cols_per_shank', + 'nrows_per_shank': 'rows_per_shank', + 'adc_bit_depth': 'adc_bit_depth' , + 'model_name': 'description', + 'num_readout_channels': 'num_readout_channels', + 'shank_width_um': 'shank_width_um', + 'tip_length_um': 'tip_length_um', +} + +def make_npx_description(probe_part_number): + """ + Extracts probe metadata from the `probeinterface/resources/probe_features.json` file and converts + to probeinterface syntax. File is maintained by Bill Karsh in ProbeTable + (https://github.com/billkarsh/ProbeTable/tree/main). + + Parameters + ---------- + probe_part_number : str + The part number of the probe e.g. 'NP2013'. + """ + + is_phase3a = False + # These are all prototype NP1.0 probes, not contained in ProbeTable + if probe_part_number in ['PRB_1_4_0480_1', 'PRB_1_4_0480_1_C', 'PRB_1_2_0480_2', None]: + if probe_part_number is None: + is_phase3a = True + probe_part_number = 'NP1010' + + probe_features_filepath = Path(__file__).absolute().parent / Path("resources/probe_features.json") + probe_features = json.load(open(probe_features_filepath, "r")) + pt_metadata = probe_features['neuropixels_probes'].get(probe_part_number) + + if pt_metadata is None: + raise ValueError(f'Probe type {probe_part_number} not supported.') + + pi_metadata = {} + + # Extract most of the metadata + for pi_name, pt_name in pi_to_pt_names.items(): + if pt_name in ['num_shanks', 'cols_per_shank', 'rows_per_shank', 'adc_bit_depth', 'num_readout_channels']: + pi_metadata[pi_name] = int(pt_metadata[pt_name]) + elif pt_name in ['electrode_pitch_horz_um', 'electrode_pitch_vert_um', 'electrode_size_horz_direction_um', 'shank_pitch_um']: + pi_metadata[pi_name] = float(pt_metadata[pt_name]) + else: + pi_metadata[pi_name] = pt_metadata[pt_name] + + # Use offsets to compute stagger and contour shift + odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float(pt_metadata['odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um']) + even_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float(pt_metadata['even_row_horz_offset_left_edge_to_leftmost_electrode_center_um']) + middle_of_bottommost_electrode_to_top_of_shank_tip = 11 + pi_metadata['contour_shift'] = [-odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um, -middle_of_bottommost_electrode_to_top_of_shank_tip] + pi_metadata['stagger'] = even_row_horz_offset_left_edge_to_leftmost_electrode_center_um - odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um + + # Read the imro tables to find out which fields the imro tables contain + imro_table_format_type = pt_metadata['imro_table_format_type'] + imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] + + # parse the imro_table_fields, which look like (value value value ...) + list_of_imro_fields = imro_table_fields.replace('(','').replace(')','').split(" ") + + # The Phase3a probe does not contain the `ap_hipas_flt` imro table field. + if is_phase3a: + list_of_imro_fields.remove("ap_hipas_flt") + + pi_imro_fields = [] + for imro_field in list_of_imro_fields: + pi_imro_fields.append(imro_field_to_pi_field[imro_field]) + pi_metadata['fields_in_imro_table'] = tuple(pi_imro_fields) + + # Construct probe contour, for styling the probe + shank_width = float(pt_metadata['shank_width_um']) + tip_length = float(pt_metadata['tip_length_um']) + probe_length = 10_000 + pi_metadata['contour_description'] = get_probe_contour_vertices(shank_width, tip_length, probe_length) + + # Get the mux table + mux_table_format_type = pt_metadata['mux_table_format_type'] + mux_information = probe_features['z_mux_tables'].get(mux_table_format_type) + pi_metadata['mux_table_array'] = make_mux_table_array(mux_information) + + return pi_metadata + +def make_mux_table_array(mux_information) -> np.array: + + # mux_information looks like (num_adcs num_channels_per_adc)(int int int ...)(int int int ...)...(int int int ...) + # First split on ')(' to get a list of the information in the brackets, and remove the leading data + split_mux = mux_information.split(")(")[1:] + + # Then remove the brackets, and split using " " to get each integer as a list + mux_channels = [np.array(each_mux.replace('(','').replace(')','').split(" ")).astype('int') for each_mux in split_mux] + mux_channels_array = np.transpose(np.array(mux_channels)) + + return mux_channels_array + + +def get_probe_contour_vertices(shank_width, tip_length, probe_length): + """ + Function to get the vertices of the probe contour from probe properties. + """ + + # this dict define the contour for one shank (duplicated when several shanks so) + # note that a final "contour_shift" is applied + polygon_vertices = [ + (0, probe_length), + (0, 0), + (shank_width/2, -tip_length), + (shank_width, 0), + (shank_width, probe_length), + ] + + return polygon_vertices def read_imro(file_path: Union[str, Path]) -> Probe: """ @@ -580,8 +254,7 @@ def _make_npx_probe_from_description(probe_description, elec_ids, shank_ids): probe.set_contact_ids(contact_ids) # Add planar contour - contour_description = probe_description["contour_description"] - polygon = np.array(polygon_contour_description[contour_description]) + polygon = np.array(probe_description["contour_description"]) contour = [] shank_pitch = probe_description["shank_pitch"] @@ -633,22 +306,21 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: Optional[str] = None) -> Probe imro_table_header_str, *imro_table_values_list, _ = imro_str.strip().split(")") imro_table_header = tuple(map(int, imro_table_header_str[1:].split(","))) + imDatPrb_type = None if imDatPrb_pn is None: if len(imro_table_header) == 3: # In older versions of neuropixel arrays (phase 3A), imro tables were structured differently. probe_serial_number, probe_option, num_contact = imro_table_header imDatPrb_type = "Phase3a" + imDatPrb_pn = None elif len(imro_table_header) == 2: imDatPrb_type, num_contact = imro_table_header + imDatPrb_type = str(imDatPrb_type) + imDatPrb_pn = probe_type_to_probe_part_number[imDatPrb_type] else: raise ValueError(f"read_imro error, the header has a strange length: {imro_table_header}") - imDatPrb_type = str(imDatPrb_type) - else: - if imDatPrb_pn not in probe_part_number_to_probe_type: - raise NotImplementedError(f"Probe part number {imDatPrb_pn} is not supported yet") - imDatPrb_type = probe_part_number_to_probe_type[imDatPrb_pn] - probe_description = npx_descriptions[imDatPrb_type] + probe_description = make_npx_description(imDatPrb_pn) fields = probe_description["fields_in_imro_table"] contact_info = {k: [] for k in fields} @@ -707,11 +379,21 @@ def write_imro(file: str | Path, probe: Probe): ret = [f"({probe_type},{len(data)})"] if probe_type == "0": - for ch in range(len(data)): - ret.append( - f"({ch} 0 {annotations['references'][ch]} {annotations['ap_gains'][ch]} " - f"{annotations['lf_gains'][ch]} {annotations['ap_hp_filters'][ch]})" - ) + # Phase3a probe does not have `ap_hp_filters` annotation + if annotations.get('ap_hp_filters') is not None: + + for ch in range(len(data)): + ret.append( + f"({ch} 0 {annotations['references'][ch]} {annotations['ap_gains'][ch]} " + f"{annotations['lf_gains'][ch]} {annotations['ap_hp_filters'][ch]})" + ) + else: + + for ch in range(len(data)): + ret.append( + f"({ch} 0 {annotations['references'][ch]} {annotations['ap_gains'][ch]} " + f"{annotations['lf_gains'][ch]})" + ) elif probe_type in ("21", "2003", "2004"): for ch in range(len(data)): @@ -1090,11 +772,8 @@ def read_openephys( positions = np.array([xpos, ypos]).T probe_part_number = np_probe.get("probe_part_number", None) - if probe_part_number not in probe_part_number_to_probe_type: - raise NotImplementedError(f"Probe part number {probe_part_number} is not supported yet") - ptype = probe_part_number_to_probe_type[probe_part_number] - probe_dict = npx_descriptions[ptype] + probe_dict = make_npx_description(probe_part_number) shank_pitch = probe_dict["shank_pitch"] if fix_x_position_for_oe_5 and oe_version < parse("0.6.0") and shank_ids is not None: @@ -1114,9 +793,13 @@ def read_openephys( probe_stagger = probe_dict["stagger"] shank_number = probe_dict["shank_number"] + model_name = probe_dict.get("model_name") + if model_name is None: + model_name = "Unknown" + for i, pos in enumerate(positions): # Do not calculate contact ids if the probe type is not known - if ptype is None: + if model_name == "Unknown": contact_ids = None break @@ -1130,15 +813,20 @@ def read_openephys( # Map the positions to the contacts ids shank_id = shank_ids[i] if shank_number > 1 else 0 - contact_id = int( - (x_pos - row_stagger - shank_pitch * shank_id) / x_pitch + number_of_columns * y_pos / y_pitch - ) + if x_pitch == 0: + contact_id = int( number_of_columns * y_pos / y_pitch) + else: + contact_id = int( + (x_pos - row_stagger - shank_pitch * shank_id) / x_pitch + number_of_columns * y_pos / y_pitch + ) if shank_number > 1: contact_ids.append(f"s{shank_id}e{contact_id}") else: contact_ids.append(f"e{contact_id}") - model_name = probe_dict["model_name"] if ptype is not None else "Unknown" + mux_table_array = probe_dict["mux_table_array"] + + np_probe_dict = { "model_name": model_name, "shank_ids": shank_ids, @@ -1149,7 +837,7 @@ def read_openephys( "dock": dock, "serial_number": probe_serial_number, "part_number": probe_part_number, - "ptype": ptype, + "mux_table_array": mux_table_array } # Sequentially assign probe names if "custom_probe_name" in np_probe.attrib and np_probe.attrib["custom_probe_name"] != probe_serial_number: @@ -1247,16 +935,9 @@ def read_openephys( positions = np_probe_info["positions"] shank_ids = np_probe_info["shank_ids"] - ptype = np_probe_info["ptype"] - if ptype in npx_descriptions: - contact_width = probe_dict["contact_width"] - num_shanks = probe_dict["shank_number"] - contour_description = probe_dict["contour_description"] - else: - contact_width = 12 - shank_pitch = 250 - num_shanks = 1 - contour_description = npx_descriptions["0"]["contour_description"] + contact_width = probe_dict["contact_width"] + num_shanks = probe_dict["shank_number"] + contour_description = probe_dict["contour_description"] contact_ids = np_probe_info["contact_ids"] if np_probe_info["contact_ids"] is not None else None @@ -1290,12 +971,13 @@ def read_openephys( slot=np_probe_info["slot"], dock=np_probe_info["dock"], port=np_probe_info["port"], + mux_table_array=np_probe_info["mux_table_array"], ) if contact_ids is not None: probe.set_contact_ids(contact_ids) - polygon = polygon_contour_description[contour_description] + polygon = contour_description contour_shift = np.array(probe_dict["contour_shift"]) if shank_ids is None: contour = polygon diff --git a/src/probeinterface/resources/probe_features.json b/src/probeinterface/resources/probe_features.json new file mode 100644 index 00000000..2b05e8da --- /dev/null +++ b/src/probeinterface/resources/probe_features.json @@ -0,0 +1,2086 @@ +{ + "neuropixels_probes": { + "NP1010": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NEUROPIXELS 1.0 NHP SHORT_v2_digital", + "description": "Neuropixels 1.0 NHP short staggered probe with cap", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1010", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1011": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Neuropixels 1.0 NHP short staggered probe with cap, cabling, sharpened", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1011", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1012": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Neuropixels 1.0 NHP short staggered probe with cap, cabling, sharpened, parylene coating", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1012", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1013": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Neuropixels 1.0 NHP short staggered probe with cap, cabling, sharpened, parylene coating, sterile packaging", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1013", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1014": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Neuropixels 1.0 NHP short staggered probe with cap, cabling, sharpened, sterile packaging ", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1014", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1015": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 NHP SHORT-MEDIUM-LONG_DATASHEET", + "description": "Neuropixels 1.0 NHP short linear probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "191", + "part_number": "NP1015", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1016": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 NHP short wired side_DATASHEET", + "description": "Neuropixels 1.0 NHP short linear probe with cap, cabling, sharpened, sterile packaging ", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "191", + "part_number": "NP1016", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1017": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2023 - NEUROPIXELS 1.0 NHP short-S_DATASHEET", + "description": "Neuropixels 1.0 NHP short linear probe with cap, cabling, sharpened, sterile packaging sterilized", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "191", + "part_number": "NP1017", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP1020": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "6.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NEUROPIXELS 1.0 NHP medium-long leaflet_digital", + "description": "Npix 1.0 NHP MEDIUM SOI35", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "87", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "2496", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1020", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "1248", + "shank_pitch_um": "0", + "shank_thickness_um": "42", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "2496" + }, + "NP1021": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "6.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NEUROPIXELS 1.0 NHP medium-long leaflet_digital", + "description": "Npix 1.0 NHP MEDIUM SOI60", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "87", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "2496", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1021", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "1248", + "shank_pitch_um": "0", + "shank_thickness_um": "67", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "2496" + }, + "NP1022": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "6.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 NHP SHORT-MEDIUM-LONG_DATASHEET", + "description": "Neuropixels 1.0 NHP medium linear probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "103", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "2496", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1022", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "1248", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "2496" + }, + "NP1030": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "11.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NEUROPIXELS 1.0 NHP medium-long leaflet_digital", + "description": "Npix 1.0 NHP LONG SOI90", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "87", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "4416", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1030", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "2208", + "shank_pitch_um": "0", + "shank_thickness_um": "97", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "4416" + }, + "NP1031": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "11.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NEUROPIXELS 1.0 NHP medium-long leaflet_digital", + "description": "Npix 1.0 NHP LONG SOI125", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "87", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "4416", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1031", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "2208", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "4416" + }, + "NP1032": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "11.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 NHP SHORT-MEDIUM-LONG_DATASHEET", + "description": "Neuropixels 1.0 NHP long linear probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "103", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "4416", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1032", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "2208", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "4416" + }, + "NP1033": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "11.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "NA", + "description": "Neuropixels 1.0 NHP long linear probe with cap, cabling, sharpened, sterile packaging ", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "103", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "4416", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1033", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "2208", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "125", + "tip_length_um": "373", + "total_electrodes": "4416" + }, + "NP1100": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "8", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Npix 1.0 UHD1 passive", + "electrode_layout_type": "8x48", + "electrode_pitch_horz_um": "6", + "electrode_pitch_vert_um": "6", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "5", + "electrode_size_vert_direction_um": "5", + "electrodes_per_shank": "384", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "14", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "14", + "on_shank_ref_chan": "-1", + "part_number": "NP1100", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "48", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206.5", + "total_electrodes": "384" + }, + "NP1110": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "16.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "UHD groups", + "channels_per_bank": "384", + "cols_per_shank": "8", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 HD_DATASHEET", + "description": "Npix 1.0 UHD2 active", + "electrode_layout_type": "8x768", + "electrode_pitch_horz_um": "6", + "electrode_pitch_vert_um": "6", + "electrode_select_api_type": "selectElectrodeGroup", + "electrode_size_horz_direction_um": "5", + "electrode_size_vert_direction_um": "5", + "electrodes_per_shank": "6144", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "15.5", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1110", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "15.5", + "on_shank_ref_chan": "-1", + "part_number": "NP1110", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "768", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "73", + "tip_length_um": "203.5", + "total_electrodes": "6144" + }, + "NP1120": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Npix 1.0 UHD3 type 1", + "electrode_layout_type": "2x192", + "electrode_pitch_horz_um": "4.5", + "electrode_pitch_vert_um": "4.5", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "3.5", + "electrode_size_vert_direction_um": "3.5", + "electrodes_per_shank": "384", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "6.75", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "6.75", + "on_shank_ref_chan": "-1", + "part_number": "NP1120", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "192", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "205.75", + "total_electrodes": "384" + }, + "NP1121": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "1", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Npix 1.0 UHD3 type 2", + "electrode_layout_type": "1x384", + "electrode_pitch_horz_um": "0", + "electrode_pitch_vert_um": "3", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "2.5", + "electrode_size_vert_direction_um": "2.5", + "electrodes_per_shank": "384", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "6.25", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "6.25", + "on_shank_ref_chan": "-1", + "part_number": "NP1121", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "384", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "205.25", + "total_electrodes": "384" + }, + "NP1122": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "16", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Npix 1.0 UHD3 type 3", + "electrode_layout_type": "16x24", + "electrode_pitch_horz_um": "3", + "electrode_pitch_vert_um": "3", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "2.5", + "electrode_size_vert_direction_um": "2.5", + "electrodes_per_shank": "384", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "12.5", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "12.5", + "on_shank_ref_chan": "-1", + "part_number": "NP1122", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "24", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "205.25", + "total_electrodes": "384" + }, + "NP1123": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "12", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Npix 1.0 UHD3 type 4", + "electrode_layout_type": "12x32", + "electrode_pitch_horz_um": "4.5", + "electrode_pitch_vert_um": "4.5", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "3.5", + "electrode_size_vert_direction_um": "3.5", + "electrodes_per_shank": "384", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "10.25", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "10.25", + "on_shank_ref_chan": "-1", + "part_number": "NP1123", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "32", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "205.75", + "total_electrodes": "384" + }, + "NP1200": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "128", + "cols_per_shank": "2", + "databus_decoder_type": "1.0 with channel reordering", + "datasheet": "N/A", + "description": "NHP passive probe 25mm, used with 128 ch headstage", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "31", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "128", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "56.5", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "N", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1200", + "num_readout_channels": "128", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "36.5", + "on_shank_ref_chan": "-1", + "part_number": "NP1200", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "64", + "shank_pitch_um": "0", + "shank_thickness_um": "67", + "shank_width_um": "125", + "tip_length_um": "372", + "total_electrodes": "128" + }, + "NP1210": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "128", + "cols_per_shank": "2", + "databus_decoder_type": "1.0 with channel reordering", + "datasheet": "N/A", + "description": "NHP passive probe 45mm, used with 128 ch headstage", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "31", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "128", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "56.5", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "N", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1200", + "num_readout_channels": "128", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "36.5", + "on_shank_ref_chan": "-1", + "part_number": "NP1210", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "64", + "shank_pitch_um": "0", + "shank_thickness_um": "132", + "shank_width_um": "125", + "tip_length_um": "372", + "total_electrodes": "128" + }, + "NP1300": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "74", + "blue_emitter_count": "14", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "N/A", + "description": "Optopix phase1", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "48", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "100", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "NP1300", + "red_emitter0_dist_from_elec0_um": "68", + "red_emitter_count": "14", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "35", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "NP2000": { + "adc_bit_depth": "14", + "adc_range_vpp": "1", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "80", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph1", + "datasheet": "NEUROPIXELS 2.0 Fully-integrated CMOS digital neural probe for small animal recording_print", + "description": "duplicate of PRB2_1_2_0640_0", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2000", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "127", + "part_number": "NP2000", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2003": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2023 SK - NEUROPIXELS 2.0_DATASHEET_v4", + "description": "Neuropixels 2.0 single shank probe", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2003", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2003", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2004": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2023 SK - NEUROPIXELS 2.0_DATASHEET_v4", + "description": "Neuropixels 2.0 single shank probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2003", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2004", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2005": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2024 - NEUROPIXELS 2.0_DATASHEET", + "description": "Neuropixels 2.0 single shank NHP short linear probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2003", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2005", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2006": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2024 - NEUROPIXELS 2.0_DATASHEET", + "description": "Neuropixels 2.0 single shank NHP short staggered probe with cap, cabling, sharpened, sterile packaging ", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2003", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "-1", + "part_number": "NP2006", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "122", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2010": { + "adc_bit_depth": "14", + "adc_range_vpp": "1", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "80", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0MS blocks", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph1", + "datasheet": "NEUROPIXELS 2.0 Fully-integrated CMOS digital neural probe for small animal recording_print", + "description": "duplicate of PRB2_4_2_0640_0", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2010", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "127", + "part_number": "NP2010", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "NP2013": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0MS blocks", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2024 - NEUROPIXELS 2.0_DATASHEET", + "description": "Neuropixels 2.0 multishank probe", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2013", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2013", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "5120" + }, + "NP2014": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0MS blocks", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2B", + "datasheet": "2024 - NEUROPIXELS 2.0_DATASHEET", + "description": "Neuropixels 2.0 multishank probe with cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2013", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2014", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "5120" + }, + "NP2020": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank (1.0 style: ch 0 to electrode 0, 384, 768, 1152)", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2C", + "datasheet": "2024 - NEUROPIXELS 2.0 QB multishank_DATASHEET", + "description": "Neuropixels 2.0 multi shank probe quad base (Ph 2C)", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2020", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2020", + "num_readout_channels": "1536", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2020", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "5120" + }, + "NP2021": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.24", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank (1.0 style: ch 0 to electrode 0, 384, 768, 1152)", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph2C", + "datasheet": "2024 - NEUROPIXELS 2.0 QB multishank_DATASHEET", + "description": "Neuropixels 2.0 multi shank probe quad base with cap (Ph 2C)", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2020", + "is_commercial": "Y", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2020", + "num_readout_channels": "1536", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP2021", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "5120" + }, + "NP3000": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.00", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "128", + "cols_per_shank": "1", + "databus_decoder_type": "N/A", + "datasheet": "N/A", + "description": "Neuropixels NXT passive probe", + "electrode_layout_type": "1x128", + "electrode_pitch_horz_um": "0", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "NA", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "128", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "59", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "N", + "imro_table_format_type": "imro_np1000", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1200", + "num_readout_channels": "128", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "59", + "on_shank_ref_chan": "-1", + "part_number": "NP3000", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "128", + "shank_pitch_um": "0", + "shank_thickness_um": "35", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "128" + }, + "NP3010": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.34", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.40", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "912", + "cols_per_shank": "2", + "databus_decoder_type": "channel reordering", + "datasheet": "N/A", + "description": "Neuropixels NXT phase1B single shank silicon cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np3010", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np3010", + "num_readout_channels": "1536", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP3010", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "30", + "shank_width_um": "70", + "tip_length_um": "203", + "total_electrodes": "1280" + }, + "NP3011": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.34", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.40", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "912", + "cols_per_shank": "2", + "databus_decoder_type": "channel reordering", + "datasheet": "N/A", + "description": "Neuropixels NXT phase1B single shank metal cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np3010", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np3010", + "num_readout_channels": "1536", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP3011", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "30", + "shank_width_um": "70", + "tip_length_um": "203", + "total_electrodes": "1280" + }, + "NP3020": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.34", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.40", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "NXT blocks", + "channels_per_bank": "912", + "cols_per_shank": "2", + "databus_decoder_type": "channel reordering", + "datasheet": "N/A", + "description": "Neuropixels NXT phase1B multishank silicon cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np3020", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np3020", + "num_readout_channels": "1536", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP3020", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "30", + "shank_width_um": "70", + "tip_length_um": "204", + "total_electrodes": "5120" + }, + "NP3021": { + "adc_bit_depth": "12", + "adc_range_vpp": "1.34", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "100", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "1.40", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "NXT blocks", + "channels_per_bank": "912", + "cols_per_shank": "2", + "databus_decoder_type": "channel reordering", + "datasheet": "N/A", + "description": "Neuropixels NXT phase1B multishank metal cap", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np3020", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np3020", + "num_readout_channels": "1536", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "-1", + "part_number": "NP3021", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "30", + "shank_width_um": "70", + "tip_length_um": "204", + "total_electrodes": "5120" + }, + "PRB2_1_2_0640_0": { + "adc_bit_depth": "14", + "adc_range_vpp": "1", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "80", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0SS scrambled", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph1", + "datasheet": "NEUROPIXELS 2.0 Fully-integrated CMOS digital neural probe for small animal recording_print", + "description": "Neuropixels 2.0 phase 1 single shank", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrodeMask", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2000", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "127", + "part_number": "PRB2_1_2_0640_0", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "1280" + }, + "PRB2_4_2_0640_0": { + "adc_bit_depth": "14", + "adc_range_vpp": "1", + "ap_band_list_hz": "0.5,10000", + "ap_gain_list": "80", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "3.33", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "2.0MS blocks", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "2.0 Ph1", + "datasheet": "NEUROPIXELS 2.0 Fully-integrated CMOS digital neural probe for small animal recording_print", + "description": "Neuropixels 2.0 phase 1 multi shank", + "electrode_layout_type": "linear", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "15", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "1280", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "N", + "has_ap_bandpass": "N", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np2010", + "is_commercial": "N", + "lf_band_list_hz": "0", + "lf_gain_list": "1", + "mux_table_format_type": "mux_np2000", + "num_readout_channels": "384", + "num_shanks": "4", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "on_shank_ref_chan": "127", + "part_number": "PRB2_4_2_0640_0", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "640", + "shank_pitch_um": "250", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "206", + "total_electrodes": "5120" + }, + "PRB_1_2_480_2": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 Fully-integrated CMOS digital neural probe_DATASHEET", + "description": "Neuropixels 1.0 probe", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "PRB_1_2_480_2", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "PRB_1_4_0480_1": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 Fully-integrated CMOS digital neural probe_DATASHEET", + "description": "Neuropixels 1.0 probe", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "PRB_1_4_0480_1", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + }, + "PRB_1_4_0480_1_C": { + "adc_bit_depth": "10", + "adc_range_vpp": "1.2", + "ap_band_list_hz": "300,10000", + "ap_gain_list": "50,125,250,500,1000,1500,2000,3000", + "ap_sample_frequency_hz": "30000", + "banks_per_shank": "2.50", + "blue_emitter0_dist_from_elec0_um": "0", + "blue_emitter_count": "0", + "channel_mapping_type": "simple bank", + "channels_per_bank": "384", + "cols_per_shank": "2", + "databus_decoder_type": "1.0", + "datasheet": "2024 - NEUROPIXELS 1.0 Fully-integrated CMOS digital neural probe_DATASHEET", + "description": "Neuropixels 1.0 probe with cap", + "electrode_layout_type": "staggered", + "electrode_pitch_horz_um": "32", + "electrode_pitch_vert_um": "20", + "electrode_select_api_type": "selectElectrode", + "electrode_size_horz_direction_um": "12", + "electrode_size_vert_direction_um": "12", + "electrodes_per_shank": "960", + "emitter_pitch_um": "0", + "even_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "27", + "has_adc_calibration_file": "Y", + "has_ap_bandpass": "Y", + "has_tip_ref": "Y", + "imro_table_format_type": "imro_np1000", + "is_commercial": "Y", + "lf_band_list_hz": "0.5,500", + "lf_gain_list": "50,125,250,500,1000,1500,2000,3000", + "mux_table_format_type": "mux_np1000", + "num_readout_channels": "384", + "num_shanks": "1", + "odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um": "11", + "on_shank_ref_chan": "191", + "part_number": "PRB_1_4_0480_1_C", + "red_emitter0_dist_from_elec0_um": "0", + "red_emitter_count": "0", + "rows_per_shank": "480", + "shank_pitch_um": "0", + "shank_thickness_um": "24", + "shank_width_um": "70", + "tip_length_um": "209", + "total_electrodes": "960" + } + }, + "z_imro_formats": { + "imro_np1000_elm_flds": "(channel bank ref_id ap_gain lf_gain ap_hipas_flt)", + "imro_np1000_elm_fmt": "(%d %d %d %d %d %d)", + "imro_np1000_hdr_flds": "(type,num_channels)", + "imro_np1000_hdr_fmt": "(%d,%d)", + "imro_np1000_val_def": "type:{0,1020,1030,1100,1120,1121,1122,1123,1200,1300} num_channels:num_readout_channels channel:[0,num_readout_channels-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,tip)(2,bnk0)(3,bnk1)(4,bnk2) ap_gain:ap_gain_list lf_gain:lf_gain_list ap_hipas_flt:[0,1]", + "imro_np1110_elm_flds": "(group bankA bankB)", + "imro_np1110_elm_fmt": "(%d %d %d)", + "imro_np1110_hdr_flds": "(type,col_mode,ref_id,ap_gain,lf_gain,ap_hipas_flt)", + "imro_np1110_hdr_fmt": "(%d,%d,%d,%d,%d,%d)", + "imro_np1110_val_def": "type:1110 col_mode:(0,INNER)(1,OUTER)(2,ALL) ref_id:(0,ext)(1,tip) ap_gain:ap_gain_list lf_gain:lf_gain_list ap_hipas_flt:[0,1]", + "imro_np2000_elm_flds": "(channel bank_mask ref_id electrode)", + "imro_np2000_elm_fmt": "(%d %d %d %d)", + "imro_np2000_hdr_flds": "(type,num_channels)", + "imro_np2000_hdr_fmt": "(%d,%d)", + "imro_np2000_val_def": "type:21 num_channels:num_readout_channels channel:[0,num_readout_channels-1] bank_mask:(bit0,bnk0)(bit1,bnk1)(bit2,bnk2) ref_id:(0,ext)(1,tip)(2,bnk0)(3,bnk1)(4,bnk2) electrode:[0,electrodes_per_shank-1]", + "imro_np2003_elm_flds": "(channel bank_mask ref_id electrode)", + "imro_np2003_elm_fmt": "(%d %d %d %d)", + "imro_np2003_hdr_flds": "(type,num_channels)", + "imro_np2003_hdr_fmt": "(%d,%d)", + "imro_np2003_val_def": "type:2003 num_channels:num_readout_channels channel:[0,num_readout_channels-1] bank_mask:(bit0,bnk0)(bit1,bnk1)(bit2,bnk2) ref_id:(0,ext)(1,gnd)(2,tip) electrode:[0,electrodes_per_shank-1]", + "imro_np2010_elm_flds": "(channel shank bank ref_id electrode)", + "imro_np2010_elm_fmt": "(%d %d %d %d %d)", + "imro_np2010_hdr_flds": "(type,num_channels)", + "imro_np2010_hdr_fmt": "(%d,%d)", + "imro_np2010_val_def": "type:24 num_channels:num_readout_channels channel:[0,num_readout_channels-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,tip0)(2,tip1)(3,tip2)(4,tip3)(5,shk0,bnk0)(6,shk0,bnk1)(7,shk0,bnk2)(8,shk0,bnk3)(9,shk1,bnk0)(10,shk1,bnk1)(11,shk1,bnk2)(12,shk1,bnk3)(13,shk2,bnk0)(14,shk2,bnk1)(15,shk2,bnk2)(16,shk2,bnk3)(17,shk3,bnk0)(18,shk3,bnk1)(19,shk3,bnk2)(20,shk3,bnk3) ap_gain:ap_gain_list lf_gain:lf_gain_list ap_hipas_flt:[0,1]", + "imro_np2013_elm_flds": "(channel shank bank ref_id electrode)", + "imro_np2013_elm_fmt": "(%d %d %d %d %d)", + "imro_np2013_hdr_flds": "(type,num_channels)", + "imro_np2013_hdr_fmt": "(%d,%d)", + "imro_np2013_val_def": "type:2013 num_channels:num_readout_channels channel:[0,num_readout_channels-1] shank:[0,num_shanks-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,gnd)(2,tip0)(3,tip1)(4,tip2)(5,tip3) electrode:[0,electrodes_per_shank-1]", + "imro_np2020_elm_flds": "(channel shank bank ref_id electrode)", + "imro_np2020_elm_fmt": "(%d %d %d %d %d)", + "imro_np2020_hdr_flds": "(type,num_channels)", + "imro_np2020_hdr_fmt": "(%d,%d)", + "imro_np2020_val_def": "type:2020 num_channels:num_readout_channels channel:[0,num_readout_channels-1] shank:[0,num_shanks-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,gnd)(2,tip) electrode:[0,electrodes_per_shank-1]", + "imro_np3010_elm_flds": "(channel bank ref_id electrode)", + "imro_np3010_elm_fmt": "(%d %d %d %d)", + "imro_np3010_hdr_flds": "(type,num_channels)", + "imro_np3010_hdr_fmt": "(%d,%d)", + "imro_np3010_val_def": "type:3010 num_channels:num_readout_channels channel:[0,num_readout_channels-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,gnd)(2,tip) electrode:[0,electrodes_per_shank-1]", + "imro_np3020_elm_flds": "(channel shank bank ref_id electrode)", + "imro_np3020_elm_fmt": "(%d %d %d %d %d)", + "imro_np3020_hdr_flds": "(type,num_channels)", + "imro_np3020_hdr_fmt": "(%d,%d)", + "imro_np3020_val_def": "type:3020 num_channels:num_readout_channels channel:[0,num_readout_channels-1] shank:[0,num_shanks-1] bank:[0,banks_per_shank-1] ref_id:(0,ext)(1,gnd)(2,tip0)(3,tip1)(4,tip2)(5,tip3) electrode:[0,electrodes_per_shank-1]" + }, + "z_meta": { + "table_version": "1.2" + }, + "z_mux_tables": { + "mux_np1000": "(32,12)(0 1 24 25 48 49 72 73 96 97 120 121 144 145 168 169 192 193 216 217 240 241 264 265 288 289 312 313 336 337 360 361)(2 3 26 27 50 51 74 75 98 99 122 123 146 147 170 171 194 195 218 219 242 243 266 267 290 291 314 315 338 339 362 363)(4 5 28 29 52 53 76 77 100 101 124 125 148 149 172 173 196 197 220 221 244 245 268 269 292 293 316 317 340 341 364 365)(6 7 30 31 54 55 78 79 102 103 126 127 150 151 174 175 198 199 222 223 246 247 270 271 294 295 318 319 342 343 366 367)(8 9 32 33 56 57 80 81 104 105 128 129 152 153 176 177 200 201 224 225 248 249 272 273 296 297 320 321 344 345 368 369)(10 11 34 35 58 59 82 83 106 107 130 131 154 155 178 179 202 203 226 227 250 251 274 275 298 299 322 323 346 347 370 371)(12 13 36 37 60 61 84 85 108 109 132 133 156 157 180 181 204 205 228 229 252 253 276 277 300 301 324 325 348 349 372 373)(14 15 38 39 62 63 86 87 110 111 134 135 158 159 182 183 206 207 230 231 254 255 278 279 302 303 326 327 350 351 374 375)(16 17 40 41 64 65 88 89 112 113 136 137 160 161 184 185 208 209 232 233 256 257 280 281 304 305 328 329 352 353 376 377)(18 19 42 43 66 67 90 91 114 115 138 139 162 163 186 187 210 211 234 235 258 259 282 283 306 307 330 331 354 355 378 379)(20 21 44 45 68 69 92 93 116 117 140 141 164 165 188 189 212 213 236 237 260 261 284 285 308 309 332 333 356 357 380 381)(22 23 46 47 70 71 94 95 118 119 142 143 166 167 190 191 214 215 238 239 262 263 286 287 310 311 334 335 358 359 382 383)", + "mux_np1200": "(12,12)(84 11 85 5 74 10 56 112 46 121 39 127)(100 26 110 33 69 24 63 109 45 93 25 99)(87 0 82 6 71 15 53 117 43 122 42 116)(102 28 81 34 70 18 60 103 17 94 27 101)(73 1 86 7 68 16 50 106 40 123 128 128)(105 29 75 35 67 12 54 89 20 95 128 128)(76 2 83 8 65 13 47 118 49 124 128 128)(108 30 78 36 64 14 51 90 23 96 128 128)(79 3 80 9 62 114 44 119 52 125 128 128)(104 31 72 37 61 113 57 91 19 97 128 128)(88 4 77 21 59 111 41 120 55 126 128 128)(107 32 66 38 58 115 48 92 22 98 128 128)", + "mux_np2000": "(24,16)(0 1 32 33 64 65 96 97 128 129 160 161 192 193 224 225 256 257 288 289 320 321 352 353)(2 3 34 35 66 67 98 99 130 131 162 163 194 195 226 227 258 259 290 291 322 323 354 355)(4 5 36 37 68 69 100 101 132 133 164 165 196 197 228 229 260 261 292 293 324 325 356 357)(6 7 38 39 70 71 102 103 134 135 166 167 198 199 230 231 262 263 294 295 326 327 358 359)(8 9 40 41 72 73 104 105 136 137 168 169 200 201 232 233 264 265 296 297 328 329 360 361)(10 11 42 43 74 75 106 107 138 139 170 171 202 203 234 235 266 267 298 299 330 331 362 363)(12 13 44 45 76 77 108 109 140 141 172 173 204 205 236 237 268 269 300 301 332 333 364 365)(14 15 46 47 78 79 110 111 142 143 174 175 206 207 238 239 270 271 302 303 334 335 366 367)(16 17 48 49 80 81 112 113 144 145 176 177 208 209 240 241 272 273 304 305 336 337 368 369)(18 19 50 51 82 83 114 115 146 147 178 179 210 211 242 243 274 275 306 307 338 339 370 371)(20 21 52 53 84 85 116 117 148 149 180 181 212 213 244 245 276 277 308 309 340 341 372 373)(22 23 54 55 86 87 118 119 150 151 182 183 214 215 246 247 278 279 310 311 342 343 374 375)(24 25 56 57 88 89 120 121 152 153 184 185 216 217 248 249 280 281 312 313 344 345 376 377)(26 27 58 59 90 91 122 123 154 155 186 187 218 219 250 251 282 283 314 315 346 347 378 379)(28 29 60 61 92 93 124 125 156 157 188 189 220 221 252 253 284 285 316 317 348 349 380 381)(30 31 62 63 94 95 126 127 158 159 190 191 222 223 254 255 286 287 318 319 350 351 382 383)", + "mux_np2020": "(96,16)(0 1 32 33 64 65 96 97 128 129 160 161 192 193 224 225 256 257 288 289 320 321 352 353 384 385 416 417 448 449 480 481 512 513 544 545 576 577 608 609 640 641 672 673 704 705 736 737 768 769 800 801 832 833 864 865 896 897 928 929 960 961 992 993 1024 1025 1056 1057 1088 1089 1120 1121 1152 1153 1184 1185 1216 1217 1248 1249 1280 1281 1312 1313 1344 1345 1376 1377 1408 1409 1440 1441 1472 1473 1504 1505)(2 3 34 35 66 67 98 99 130 131 162 163 194 195 226 227 258 259 290 291 322 323 354 355 386 387 418 419 450 451 482 483 514 515 546 547 578 579 610 611 642 643 674 675 706 707 738 739 770 771 802 803 834 835 866 867 898 899 930 931 962 963 994 995 1026 1027 1058 1059 1090 1091 1122 1123 1154 1155 1186 1187 1218 1219 1250 1251 1282 1283 1314 1315 1346 1347 1378 1379 1410 1411 1442 1443 1474 1475 1506 1507)(4 5 36 37 68 69 100 101 132 133 164 165 196 197 228 229 260 261 292 293 324 325 356 357 388 389 420 421 452 453 484 485 516 517 548 549 580 581 612 613 644 645 676 677 708 709 740 741 772 773 804 805 836 837 868 869 900 901 932 933 964 965 996 997 1028 1029 1060 1061 1092 1093 1124 1125 1156 1157 1188 1189 1220 1221 1252 1253 1284 1285 1316 1317 1348 1349 1380 1381 1412 1413 1444 1445 1476 1477 1508 1509)(6 7 38 39 70 71 102 103 134 135 166 167 198 199 230 231 262 263 294 295 326 327 358 359 390 391 422 423 454 455 486 487 518 519 550 551 582 583 614 615 646 647 678 679 710 711 742 743 774 775 806 807 838 839 870 871 902 903 934 935 966 967 998 999 1030 1031 1062 1063 1094 1095 1126 1127 1158 1159 1190 1191 1222 1223 1254 1255 1286 1287 1318 1319 1350 1351 1382 1383 1414 1415 1446 1447 1478 1479 1510 1511)(8 9 40 41 72 73 104 105 136 137 168 169 200 201 232 233 264 265 296 297 328 329 360 361 392 393 424 425 456 457 488 489 520 521 552 553 584 585 616 617 648 649 680 681 712 713 744 745 776 777 808 809 840 841 872 873 904 905 936 937 968 969 1000 1001 1032 1033 1064 1065 1096 1097 1128 1129 1160 1161 1192 1193 1224 1225 1256 1257 1288 1289 1320 1321 1352 1353 1384 1385 1416 1417 1448 1449 1480 1481 1512 1513)(10 11 42 43 74 75 106 107 138 139 170 171 202 203 234 235 266 267 298 299 330 331 362 363 394 395 426 427 458 459 490 491 522 523 554 555 586 587 618 619 650 651 682 683 714 715 746 747 778 779 810 811 842 843 874 875 906 907 938 939 970 971 1002 1003 1034 1035 1066 1067 1098 1099 1130 1131 1162 1163 1194 1195 1226 1227 1258 1259 1290 1291 1322 1323 1354 1355 1386 1387 1418 1419 1450 1451 1482 1483 1514 1515)(12 13 44 45 76 77 108 109 140 141 172 173 204 205 236 237 268 269 300 301 332 333 364 365 396 397 428 429 460 461 492 493 524 525 556 557 588 589 620 621 652 653 684 685 716 717 748 749 780 781 812 813 844 845 876 877 908 909 940 941 972 973 1004 1005 1036 1037 1068 1069 1100 1101 1132 1133 1164 1165 1196 1197 1228 1229 1260 1261 1292 1293 1324 1325 1356 1357 1388 1389 1420 1421 1452 1453 1484 1485 1516 1517)(14 15 46 47 78 79 110 111 142 143 174 175 206 207 238 239 270 271 302 303 334 335 366 367 398 399 430 431 462 463 494 495 526 527 558 559 590 591 622 623 654 655 686 687 718 719 750 751 782 783 814 815 846 847 878 879 910 911 942 943 974 975 1006 1007 1038 1039 1070 1071 1102 1103 1134 1135 1166 1167 1198 1199 1230 1231 1262 1263 1294 1295 1326 1327 1358 1359 1390 1391 1422 1423 1454 1455 1486 1487 1518 1519)(16 17 48 49 80 81 112 113 144 145 176 177 208 209 240 241 272 273 304 305 336 337 368 369 400 401 432 433 464 465 496 497 528 529 560 561 592 593 624 625 656 657 688 689 720 721 752 753 784 785 816 817 848 849 880 881 912 913 944 945 976 977 1008 1009 1040 1041 1072 1073 1104 1105 1136 1137 1168 1169 1200 1201 1232 1233 1264 1265 1296 1297 1328 1329 1360 1361 1392 1393 1424 1425 1456 1457 1488 1489 1520 1521)(18 19 50 51 82 83 114 115 146 147 178 179 210 211 242 243 274 275 306 307 338 339 370 371 402 403 434 435 466 467 498 499 530 531 562 563 594 595 626 627 658 659 690 691 722 723 754 755 786 787 818 819 850 851 882 883 914 915 946 947 978 979 1010 1011 1042 1043 1074 1075 1106 1107 1138 1139 1170 1171 1202 1203 1234 1235 1266 1267 1298 1299 1330 1331 1362 1363 1394 1395 1426 1427 1458 1459 1490 1491 1522 1523)(20 21 52 53 84 85 116 117 148 149 180 181 212 213 244 245 276 277 308 309 340 341 372 373 404 405 436 437 468 469 500 501 532 533 564 565 596 597 628 629 660 661 692 693 724 725 756 757 788 789 820 821 852 853 884 885 916 917 948 949 980 981 1012 1013 1044 1045 1076 1077 1108 1109 1140 1141 1172 1173 1204 1205 1236 1237 1268 1269 1300 1301 1332 1333 1364 1365 1396 1397 1428 1429 1460 1461 1492 1493 1524 1525)(22 23 54 55 86 87 118 119 150 151 182 183 214 215 246 247 278 279 310 311 342 343 374 375 406 407 438 439 470 471 502 503 534 535 566 567 598 599 630 631 662 663 694 695 726 727 758 759 790 791 822 823 854 855 886 887 918 919 950 951 982 983 1014 1015 1046 1047 1078 1079 1110 1111 1142 1143 1174 1175 1206 1207 1238 1239 1270 1271 1302 1303 1334 1335 1366 1367 1398 1399 1430 1431 1462 1463 1494 1495 1526 1527)(24 25 56 57 88 89 120 121 152 153 184 185 216 217 248 249 280 281 312 313 344 345 376 377 408 409 440 441 472 473 504 505 536 537 568 569 600 601 632 633 664 665 696 697 728 729 760 761 792 793 824 825 856 857 888 889 920 921 952 953 984 985 1016 1017 1048 1049 1080 1081 1112 1113 1144 1145 1176 1177 1208 1209 1240 1241 1272 1273 1304 1305 1336 1337 1368 1369 1400 1401 1432 1433 1464 1465 1496 1497 1528 1529)(26 27 58 59 90 91 122 123 154 155 186 187 218 219 250 251 282 283 314 315 346 347 378 379 410 411 442 443 474 475 506 507 538 539 570 571 602 603 634 635 666 667 698 699 730 731 762 763 794 795 826 827 858 859 890 891 922 923 954 955 986 987 1018 1019 1050 1051 1082 1083 1114 1115 1146 1147 1178 1179 1210 1211 1242 1243 1274 1275 1306 1307 1338 1339 1370 1371 1402 1403 1434 1435 1466 1467 1498 1499 1530 1531)(28 29 60 61 92 93 124 125 156 157 188 189 220 221 252 253 284 285 316 317 348 349 380 381 412 413 444 445 476 477 508 509 540 541 572 573 604 605 636 637 668 669 700 701 732 733 764 765 796 797 828 829 860 861 892 893 924 925 956 957 988 989 1020 1021 1052 1053 1084 1085 1116 1117 1148 1149 1180 1181 1212 1213 1244 1245 1276 1277 1308 1309 1340 1341 1372 1373 1404 1405 1436 1437 1468 1469 1500 1501 1532 1533)(30 31 62 63 94 95 126 127 158 159 190 191 222 223 254 255 286 287 318 319 350 351 382 383 414 415 446 447 478 479 510 511 542 543 574 575 606 607 638 639 670 671 702 703 734 735 766 767 798 799 830 831 862 863 894 895 926 927 958 959 990 991 1022 1023 1054 1055 1086 1087 1118 1119 1150 1151 1182 1183 1214 1215 1246 1247 1278 1279 1310 1311 1342 1343 1374 1375 1406 1407 1438 1439 1470 1471 1502 1503 1534 1535)", + "mux_np3010": "(58,16)(0 1 32 33 64 65 96 97 128 129 160 161 192 193 224 225 256 257 288 289 320 321 352 353 384 385 416 417 448 449 480 481 512 513 544 545 576 577 608 609 640 641 672 673 704 705 736 737 768 769 800 801 832 833 864 865 896 897)(2 3 34 35 66 67 98 99 130 131 162 163 194 195 226 227 258 259 290 291 322 323 354 355 386 387 418 419 450 451 482 483 514 515 546 547 578 579 610 611 642 643 674 675 706 707 738 739 770 771 802 803 834 835 866 867 898 899)(4 5 36 37 68 69 100 101 132 133 164 165 196 197 228 229 260 261 292 293 324 325 356 357 388 389 420 421 452 453 484 485 516 517 548 549 580 581 612 613 644 645 676 677 708 709 740 741 772 773 804 805 836 837 868 869 900 901)(6 7 38 39 70 71 102 103 134 135 166 167 198 199 230 231 262 263 294 295 326 327 358 359 390 391 422 423 454 455 486 487 518 519 550 551 582 583 614 615 646 647 678 679 710 711 742 743 774 775 806 807 838 839 870 871 902 903)(8 9 40 41 72 73 104 105 136 137 168 169 200 201 232 233 264 265 296 297 328 329 360 361 392 393 424 425 456 457 488 489 520 521 552 553 584 585 616 617 648 649 680 681 712 713 744 745 776 777 808 809 840 841 872 873 904 905)(10 11 42 43 74 75 106 107 138 139 170 171 202 203 234 235 266 267 298 299 330 331 362 363 394 395 426 427 458 459 490 491 522 523 554 555 586 587 618 619 650 651 682 683 714 715 746 747 778 779 810 811 842 843 874 875 906 907)(12 13 44 45 76 77 108 109 140 141 172 173 204 205 236 237 268 269 300 301 332 333 364 365 396 397 428 429 460 461 492 493 524 525 556 557 588 589 620 621 652 653 684 685 716 717 748 749 780 781 812 813 844 845 876 877 908 909)(14 15 46 47 78 79 110 111 142 143 174 175 206 207 238 239 270 271 302 303 334 335 366 367 398 399 430 431 462 463 494 495 526 527 558 559 590 591 622 623 654 655 686 687 718 719 750 751 782 783 814 815 846 847 878 879 910 911)(16 17 48 49 80 81 112 113 144 145 176 177 208 209 240 241 272 273 304 305 336 337 368 369 400 401 432 433 464 465 496 497 528 529 560 561 592 593 624 625 656 657 688 689 720 721 752 753 784 785 816 817 848 849 880 881 912 913)(18 19 50 51 82 83 114 115 146 147 178 179 210 211 242 243 274 275 306 307 338 339 370 371 402 403 434 435 466 467 498 499 530 531 562 563 594 595 626 627 658 659 690 691 722 723 754 755 786 787 818 819 850 851 882 883 914 915)(20 21 52 53 84 85 116 117 148 149 180 181 212 213 244 245 276 277 308 309 340 341 372 373 404 405 436 437 468 469 500 501 532 533 564 565 596 597 628 629 660 661 692 693 724 725 756 757 788 789 820 821 852 853 884 885 916 917)(22 23 54 55 86 87 118 119 150 151 182 183 214 215 246 247 278 279 310 311 342 343 374 375 406 407 438 439 470 471 502 503 534 535 566 567 598 599 630 631 662 663 694 695 726 727 758 759 790 791 822 823 854 855 886 887 918 919)(24 25 56 57 88 89 120 121 152 153 184 185 216 217 248 249 280 281 312 313 344 345 376 377 408 409 440 441 472 473 504 505 536 537 568 569 600 601 632 633 664 665 696 697 728 729 760 761 792 793 824 825 856 857 888 889 920 921)(26 27 58 59 90 91 122 123 154 155 186 187 218 219 250 251 282 283 314 315 346 347 378 379 410 411 442 443 474 475 506 507 538 539 570 571 602 603 634 635 666 667 698 699 730 731 762 763 794 795 826 827 858 859 890 891 922 923)(28 29 60 61 92 93 124 125 156 157 188 189 220 221 252 253 284 285 316 317 348 349 380 381 412 413 444 445 476 477 508 509 540 541 572 573 604 605 636 637 668 669 700 701 732 733 764 765 796 797 828 829 860 861 892 893 924 925)(30 31 62 63 94 95 126 127 158 159 190 191 222 223 254 255 286 287 318 319 350 351 382 383 414 415 446 447 478 479 510 511 542 543 574 575 606 607 638 639 670 671 702 703 734 735 766 767 798 799 830 831 862 863 894 895 926 927)", + "mux_np3020": "(96,16)(0 1 32 33 64 65 96 97 128 129 160 161 192 193 224 225 256 257 288 289 320 321 352 353 384 385 416 417 448 449 480 481 512 513 544 545 576 577 608 609 640 641 672 673 704 705 736 737 768 769 800 801 832 833 864 865 896 897 928 929 960 961 992 993 1024 1025 1056 1057 1088 1089 1120 1121 1152 1153 1184 1185 1216 1217 1248 1249 1280 1281 1312 1313 1344 1345 1376 1377 1408 1409 1440 1441 1472 1473 1504 1505)(2 3 34 35 66 67 98 99 130 131 162 163 194 195 226 227 258 259 290 291 322 323 354 355 386 387 418 419 450 451 482 483 514 515 546 547 578 579 610 611 642 643 674 675 706 707 738 739 770 771 802 803 834 835 866 867 898 899 930 931 962 963 994 995 1026 1027 1058 1059 1090 1091 1122 1123 1154 1155 1186 1187 1218 1219 1250 1251 1282 1283 1314 1315 1346 1347 1378 1379 1410 1411 1442 1443 1474 1475 1506 1507)(4 5 36 37 68 69 100 101 132 133 164 165 196 197 228 229 260 261 292 293 324 325 356 357 388 389 420 421 452 453 484 485 516 517 548 549 580 581 612 613 644 645 676 677 708 709 740 741 772 773 804 805 836 837 868 869 900 901 932 933 964 965 996 997 1028 1029 1060 1061 1092 1093 1124 1125 1156 1157 1188 1189 1220 1221 1252 1253 1284 1285 1316 1317 1348 1349 1380 1381 1412 1413 1444 1445 1476 1477 1508 1509)(6 7 38 39 70 71 102 103 134 135 166 167 198 199 230 231 262 263 294 295 326 327 358 359 390 391 422 423 454 455 486 487 518 519 550 551 582 583 614 615 646 647 678 679 710 711 742 743 774 775 806 807 838 839 870 871 902 903 934 935 966 967 998 999 1030 1031 1062 1063 1094 1095 1126 1127 1158 1159 1190 1191 1222 1223 1254 1255 1286 1287 1318 1319 1350 1351 1382 1383 1414 1415 1446 1447 1478 1479 1510 1511)(8 9 40 41 72 73 104 105 136 137 168 169 200 201 232 233 264 265 296 297 328 329 360 361 392 393 424 425 456 457 488 489 520 521 552 553 584 585 616 617 648 649 680 681 712 713 744 745 776 777 808 809 840 841 872 873 904 905 936 937 968 969 1000 1001 1032 1033 1064 1065 1096 1097 1128 1129 1160 1161 1192 1193 1224 1225 1256 1257 1288 1289 1320 1321 1352 1353 1384 1385 1416 1417 1448 1449 1480 1481 1512 1513)(10 11 42 43 74 75 106 107 138 139 170 171 202 203 234 235 266 267 298 299 330 331 362 363 394 395 426 427 458 459 490 491 522 523 554 555 586 587 618 619 650 651 682 683 714 715 746 747 778 779 810 811 842 843 874 875 906 907 938 939 970 971 1002 1003 1034 1035 1066 1067 1098 1099 1130 1131 1162 1163 1194 1195 1226 1227 1258 1259 1290 1291 1322 1323 1354 1355 1386 1387 1418 1419 1450 1451 1482 1483 1514 1515)(12 13 44 45 76 77 108 109 140 141 172 173 204 205 236 237 268 269 300 301 332 333 364 365 396 397 428 429 460 461 492 493 524 525 556 557 588 589 620 621 652 653 684 685 716 717 748 749 780 781 812 813 844 845 876 877 908 909 940 941 972 973 1004 1005 1036 1037 1068 1069 1100 1101 1132 1133 1164 1165 1196 1197 1228 1229 1260 1261 1292 1293 1324 1325 1356 1357 1388 1389 1420 1421 1452 1453 1484 1485 1516 1517)(14 15 46 47 78 79 110 111 142 143 174 175 206 207 238 239 270 271 302 303 334 335 366 367 398 399 430 431 462 463 494 495 526 527 558 559 590 591 622 623 654 655 686 687 718 719 750 751 782 783 814 815 846 847 878 879 910 911 942 943 974 975 1006 1007 1038 1039 1070 1071 1102 1103 1134 1135 1166 1167 1198 1199 1230 1231 1262 1263 1294 1295 1326 1327 1358 1359 1390 1391 1422 1423 1454 1455 1486 1487 1518 1519)(16 17 48 49 80 81 112 113 144 145 176 177 208 209 240 241 272 273 304 305 336 337 368 369 400 401 432 433 464 465 496 497 528 529 560 561 592 593 624 625 656 657 688 689 720 721 752 753 784 785 816 817 848 849 880 881 912 913 944 945 976 977 1008 1009 1040 1041 1072 1073 1104 1105 1136 1137 1168 1169 1200 1201 1232 1233 1264 1265 1296 1297 1328 1329 1360 1361 1392 1393 1424 1425 1456 1457 1488 1489 1520 1521)(18 19 50 51 82 83 114 115 146 147 178 179 210 211 242 243 274 275 306 307 338 339 370 371 402 403 434 435 466 467 498 499 530 531 562 563 594 595 626 627 658 659 690 691 722 723 754 755 786 787 818 819 850 851 882 883 914 915 946 947 978 979 1010 1011 1042 1043 1074 1075 1106 1107 1138 1139 1170 1171 1202 1203 1234 1235 1266 1267 1298 1299 1330 1331 1362 1363 1394 1395 1426 1427 1458 1459 1490 1491 1522 1523)(20 21 52 53 84 85 116 117 148 149 180 181 212 213 244 245 276 277 308 309 340 341 372 373 404 405 436 437 468 469 500 501 532 533 564 565 596 597 628 629 660 661 692 693 724 725 756 757 788 789 820 821 852 853 884 885 916 917 948 949 980 981 1012 1013 1044 1045 1076 1077 1108 1109 1140 1141 1172 1173 1204 1205 1236 1237 1268 1269 1300 1301 1332 1333 1364 1365 1396 1397 1428 1429 1460 1461 1492 1493 1524 1525)(22 23 54 55 86 87 118 119 150 151 182 183 214 215 246 247 278 279 310 311 342 343 374 375 406 407 438 439 470 471 502 503 534 535 566 567 598 599 630 631 662 663 694 695 726 727 758 759 790 791 822 823 854 855 886 887 918 919 950 951 982 983 1014 1015 1046 1047 1078 1079 1110 1111 1142 1143 1174 1175 1206 1207 1238 1239 1270 1271 1302 1303 1334 1335 1366 1367 1398 1399 1430 1431 1462 1463 1494 1495 1526 1527)(24 25 56 57 88 89 120 121 152 153 184 185 216 217 248 249 280 281 312 313 344 345 376 377 408 409 440 441 472 473 504 505 536 537 568 569 600 601 632 633 664 665 696 697 728 729 760 761 792 793 824 825 856 857 888 889 920 921 952 953 984 985 1016 1017 1048 1049 1080 1081 1112 1113 1144 1145 1176 1177 1208 1209 1240 1241 1272 1273 1304 1305 1336 1337 1368 1369 1400 1401 1432 1433 1464 1465 1496 1497 1528 1529)(26 27 58 59 90 91 122 123 154 155 186 187 218 219 250 251 282 283 314 315 346 347 378 379 410 411 442 443 474 475 506 507 538 539 570 571 602 603 634 635 666 667 698 699 730 731 762 763 794 795 826 827 858 859 890 891 922 923 954 955 986 987 1018 1019 1050 1051 1082 1083 1114 1115 1146 1147 1178 1179 1210 1211 1242 1243 1274 1275 1306 1307 1338 1339 1370 1371 1402 1403 1434 1435 1466 1467 1498 1499 1530 1531)(28 29 60 61 92 93 124 125 156 157 188 189 220 221 252 253 284 285 316 317 348 349 380 381 412 413 444 445 476 477 508 509 540 541 572 573 604 605 636 637 668 669 700 701 732 733 764 765 796 797 828 829 860 861 892 893 924 925 956 957 988 989 1020 1021 1052 1053 1084 1085 1116 1117 1148 1149 1180 1181 1212 1213 1244 1245 1276 1277 1308 1309 1340 1341 1372 1373 1404 1405 1436 1437 1468 1469 1500 1501 1532 1533)(30 31 62 63 94 95 126 127 158 159 190 191 222 223 254 255 286 287 318 319 350 351 382 383 414 415 446 447 478 479 510 511 542 543 574 575 606 607 638 639 670 671 702 703 734 735 766 767 798 799 830 831 862 863 894 895 926 927 958 959 990 991 1022 1023 1054 1055 1086 1087 1118 1119 1150 1151 1182 1183 1214 1215 1246 1247 1278 1279 1310 1311 1342 1343 1374 1375 1406 1407 1438 1439 1470 1471 1502 1503 1534 1535)" + } +} diff --git a/tests/test_io/test_openephys.py b/tests/test_io/test_openephys.py index d8f070e0..3ab762b5 100644 --- a/tests/test_io/test_openephys.py +++ b/tests/test_io/test_openephys.py @@ -17,7 +17,6 @@ def test_NP2_OE_1_0(): probe_dict = probeA.to_dict(array_as_list=True) validate_probe_dict(probe_dict) assert probeA.get_shank_count() == 1 - assert "2.0" in probeA.model_name assert probeA.get_contact_count() == 384 @@ -27,7 +26,6 @@ def test_NP2(): probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) assert probe.get_shank_count() == 1 - assert "2.0 - Single Shank" in probe.model_name def test_NP2_four_shank(): @@ -37,7 +35,6 @@ def test_NP2_four_shank(): validate_probe_dict(probe_dict) # on this case, only shanks 2-3 are used assert probe.get_shank_count() == 2 - assert "2.0 - Four Shank" in probe.model_name def test_NP_Ultra(): @@ -48,7 +45,6 @@ def test_NP_Ultra(): ) probe_dict = probeA.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert "Ultra" in probeA.model_name assert probeA.get_shank_count() == 1 assert probeA.get_contact_count() == 384 @@ -58,7 +54,6 @@ def test_NP_Ultra(): ) probe_dict = probeB.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert "Ultra" in probeB.model_name assert probeB.get_shank_count() == 1 assert probeB.get_contact_count() == 384 @@ -68,7 +63,6 @@ def test_NP_Ultra(): ) probe_dict = probeF.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert "Ultra" in probeF.model_name assert probeF.get_shank_count() == 1 assert probeF.get_contact_count() == 384 @@ -78,7 +72,6 @@ def test_NP_Ultra(): ) probe_dict = probeD.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert "Ultra" in probeD.model_name and "Type 2" in probeD.model_name assert probeD.get_shank_count() == 1 assert probeD.get_contact_count() == 384 # for this probe model, all channels are aligned @@ -162,7 +155,6 @@ def test_multiple_probes(): ) assert probeB2.get_shank_count() == 1 - assert "2.0 - Four Shank" in probeB2.model_name ypos = probeB2.contact_positions[:, 1] assert np.min(ypos) >= 0 @@ -209,7 +201,6 @@ def test_np_opto_with_sync(): probe = read_openephys(data_path / "OE_Neuropix-PXI-opto-with-sync" / "settings.xml") probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert probe.model_name == "Neuropixels Opto" assert probe.get_shank_count() == 1 assert probe.get_contact_count() == 384 @@ -221,7 +212,6 @@ def test_older_than_06_format(): probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) assert probe.get_shank_count() == 4 - assert "2.0 - Four Shank" in probe.model_name ypos = probe.contact_positions[:, 1] assert np.min(ypos) >= 0 @@ -232,7 +222,6 @@ def test_multiple_signal_chains(): probe = read_openephys(data_path / "OE_Neuropix-PXI-multiple-signalchains" / "settings.xml") probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert probe.model_name == "Neuropixels 1.0" def test_quadbase(): @@ -241,7 +230,6 @@ def test_quadbase(): probe = read_openephys(data_path / "OE_Neuropix-PXI-QuadBase" / "settings.xml", probe_name=f"ProbeC-{i+1}") probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert probe.model_name == "Neuropixels 2.0 - Quad Base" assert probe.get_shank_count() == 1 assert probe.get_contact_count() == 384 assert set(probe.shank_ids) == set([str(i)]) @@ -252,7 +240,6 @@ def test_onebox(): probe = read_openephys(data_path / "OE_OneBox-NP-Ultra" / "settings.xml") probe_dict = probe.to_dict(array_as_list=True) validate_probe_dict(probe_dict) - assert probe.model_name == "Neuropixels Ultra (16 banks)" assert probe.get_shank_count() == 1 assert probe.get_contact_count() == 384 diff --git a/tests/test_io/test_spikeglx.py b/tests/test_io/test_spikeglx.py index 6680ab8f..e6a72e16 100644 --- a/tests/test_io/test_spikeglx.py +++ b/tests/test_io/test_spikeglx.py @@ -50,9 +50,7 @@ def test_NP_phase3A(): # Data provided by rtraghavan probe = read_spikeglx(data_path / "phase3a.imec.ap.meta") - assert probe.model_name == "Phase3a" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "Phase3a" assert probe.ndim == 2 assert probe.get_shank_count() == 1 @@ -75,9 +73,7 @@ def test_NP2_1_shanks(): def test_NP2_4_shanks(): probe = read_spikeglx(data_path / "NP2_4_shanks.imec0.ap.meta") - assert probe.model_name == "Neuropixels 2.0 - Four Shank - Prototype" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "24" assert probe.ndim == 2 assert probe.get_shank_count() == 4 @@ -99,9 +95,7 @@ def test_NP2_2013_all(): # Data provided by Jennifer Colonell probe = read_spikeglx(data_path / "NP2_2013_all_channels.imec0.ap.meta") - assert probe.model_name == "Neuropixels 2.0 - Four Shank" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "2013" assert probe.ndim == 2 # all channels are from the first shank @@ -124,9 +118,7 @@ def test_NP2_2013_subset(): # Data provided by Jennifer Colonell probe = read_spikeglx(data_path / "NP2_2013_subset_channels.imec0.ap.meta") - assert probe.model_name == "Neuropixels 2.0 - Four Shank" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "2013" assert probe.ndim == 2 # all channels are from the first shank @@ -149,9 +141,7 @@ def test_NP2_4_shanks_with_different_electrodes_saved(): # Data provided by Jennifer Colonell probe = read_spikeglx(data_path / "NP2_4_shanks_save_different_electrodes.imec0.ap.meta") - assert probe.model_name == "Neuropixels 2.0 - Four Shank - Prototype" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "24" assert probe.ndim == 2 assert probe.get_shank_count() == 4 @@ -201,9 +191,7 @@ def test_NPH_long_staggered(): # Data provided by Nate Dolensek probe = read_spikeglx(data_path / "non_human_primate_long_staggered.imec0.ap.meta") - assert probe.model_name == "Neuropixels 1.0-NHP - long SOI90 staggered" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "1030" assert probe.ndim == 2 assert probe.get_shank_count() == 1 @@ -225,17 +213,17 @@ def test_NPH_long_staggered(): # Every second contact the x position should increase by x_pitch increase = np.diff(x) every_second_increase = increase[::2] - x_pitch = 56 + x_pitch = 87 assert np.allclose(every_second_increase, x_pitch) # Every second contact should be staggered by contact_width every_second_contact = x[::2] staggered_values = np.abs(np.diff(every_second_contact)) - contact_width = 12 + contact_width = 16 assert np.allclose(staggered_values, contact_width) # Every second contact should increase by y_pitch - y_pitch = 20.0 + y_pitch = 20 every_second_contact = y[::2] increase = np.diff(every_second_contact) assert np.allclose(increase, y_pitch) @@ -257,9 +245,7 @@ def test_NPH_short_linear_probe_type_0(): # Data provided by Jonathan A Michaels probe = read_spikeglx(data_path / "non_human_primate_short_linear_probe_type_0.meta") - assert probe.model_name == "Neuropixels 1.0-NHP - short" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "1015" assert probe.ndim == 2 assert probe.get_shank_count() == 1 @@ -307,9 +293,7 @@ def test_ultra_probe(): # Data provided by Alessio probe = read_spikeglx(data_path / "npUltra.meta") - assert probe.model_name == "Neuropixels Ultra (1 bank)" assert probe.manufacturer == "IMEC" - assert probe.annotations["probe_type"] == "1100" # Test contact geometry contact_width = 5.0 diff --git a/tests/test_neuropixels_backwards_compat.py b/tests/test_neuropixels_backwards_compat.py new file mode 100644 index 00000000..c6680981 --- /dev/null +++ b/tests/test_neuropixels_backwards_compat.py @@ -0,0 +1,532 @@ +from probeinterface import Probe +from probeinterface.neuropixels_tools import make_npx_description +from pathlib import Path + +import numpy as np + +import pytest + + + +# Map imDatPrb_pn (probe number) to imDatPrb_type (probe type) when the latter is missing +probe_part_number_to_probe_type = { + # for old version without a probe number we assume NP1.0 + None: "0", + # NP1.0 + "PRB_1_4_0480_1": "0", + "PRB_1_4_0480_1_C": "0", # This is the metal cap version + "PRB_1_2_0480_2": "0", + "NP1010": "0", + # NHP probes lin + "NP1015": "1015", + "NP1016": "1015", + "NP1017": "1015", + # NHP probes stag med + "NP1020": "1020", + "NP1021": "1021", + "NP1022": "1022", + # NHP probes stag long + "NP1030": "1030", + "NP1031": "1031", + "NP1032": "1032", + # NP2.0 + "NP2000": "21", + "NP2010": "24", + "NP2013": "2013", + "NP2014": "2014", + "NP2003": "2003", + "NP2004": "2004", + "PRB2_1_2_0640_0": "21", + "PRB2_4_2_0640_0": "24", + # NXT + "NP2020": "2020", + # Ultra + "NP1100": "1100", # Ultra probe - 1 bank + "NP1110": "1110", # Ultra probe - 16 banks no handle beacuse + "NP1121": "1121", # Ultra probe - beta configuration + # Opto + "NP1300": "1300", # Opto probe +} + +# this dict define the contour for one shank (duplicated when several shanks so) +# note that a final "contour_shift" is applied +polygon_contour_description = { + # NP1 and NP2 (1 and 4 shanks) + "np70": [ + (0, 10000), + (0, 0), + (35, -175), + (70, 0), + (70, 10000), + ], + "nhp90": [ + (0, 10000), + (0, 0), + (45, -342), + (90, 0), + (90, 10000), + ], + "nhp125": [ + (0, 10000), + (0, 0), + (62.5, -342), + (125, 0), + (125, 10000), + ], +} + + +npx_descriptions = { + # Neuropixels 1.0 + # This probably should be None or something else because NOT ONLY the neuropixels 1.0 have that imDatPrb_type + "0": { + "model_name": "Neuropixels 1.0", + "x_pitch": 32, + "y_pitch": 20, + "contact_width": 12, + "stagger": 16, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 480, + "contour_description": "np70", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Neuropixels 2.0 - Single Shank - Prototype + "21": { + "model_name": "Neuropixels 2.0 - Single Shank - Prototype", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), + }, + # Neuropixels 2.0 - Four Shank - Prototype + "24": { + "model_name": "Neuropixels 2.0 - Four Shank - Prototype", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 250, + "shank_number": 4, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ( + "channel_ids", + "shank_id", + "banks", + "references", + "elec_ids", + ), + }, + # Neuropixels 2.0 - Single Shank - Commercial without metal cap + "2003": { + "model_name": "Neuropixels 2.0 - Single Shank", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), + }, + # Neuropixels 2.0 - Single Shank - Commercial with metal cap + "2004": { + "model_name": "Neuropixels 2.0 - Single Shank", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ("channel_ids", "banks", "references", "elec_ids"), + }, + # Neuropixels 2.0 - Four Shank - Commercial without metal cap + "2013": { + "model_name": "Neuropixels 2.0 - Four Shank", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 250, + "shank_number": 4, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ( + "channel_ids", + "shank_id", + "banks", + "references", + "elec_ids", + ), + }, + # Neuropixels 2.0 - Four Shank - Commercial with metal cap + "2014": { + "model_name": "Neuropixels 2.0 - Four Shank", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 250, + "shank_number": 4, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ( + "channel_ids", + "shank_id", + "banks", + "references", + "elec_ids", + ), + }, + # Neuropixels 2.0 Quad Base + "2020": { + "model_name": "Neuropixels 2.0 - Quad Base", + "x_pitch": 32, + "y_pitch": 15, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 250, + "shank_number": 4, + "ncols_per_shank": 2, + "nrows_per_shank": 640, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ( + "channel_ids", + "shank_id", + "banks", + "references", + "elec_ids", + ), + }, + # Experimental probes previous to 1.0 + "Phase3a": { + "model_name": "Phase3a", + "x_pitch": 32, + "y_pitch": 20, + "contact_width": 12, + "stagger": 16.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 480, + "contour_description": "np70", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + ), + }, + # Neuropixels 1.0-NHP Short (10mm) + "1015": { + "model_name": "Neuropixels 1.0-NHP - short", + "x_pitch": 32, + "y_pitch": 20, + "contact_width": 12, + "stagger": 0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 480, + "contour_description": "np70", + "contour_shift": [-27, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + ################# + # Neuropixels 1.0-NHP Medium (25mm) + "1020": { + "model_name": "Neuropixels 1.0-NHP - medium - staggered", + "x_pitch": 103 - 12, + "y_pitch": 20, + "contact_width": 12, + "stagger": 12.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 + "contour_description": "nhp125", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Neuropixels 1.0-NHP Medium (25mm) + "1021": { + "model_name": "Neuropixels 1.0-NHP - medium - staggered", + "x_pitch": 103 - 12, + "y_pitch": 20, + "contact_width": 12, + "stagger": 12.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 + "contour_description": "nhp125", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + ################# + # Neuropixels 1.0-NHP Medium (25mm) + "1022": { + "model_name": "Neuropixels 1.0-NHP - medium", + "x_pitch": 103, + "y_pitch": 20, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 1248, ### verify this number!!!!!!! Jennifer Colonell has 1368 + "contour_description": "nhp125", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Neuropixels 1.0-NHP 45mm SOI90 - NHP long 90um wide, staggered contacts + "1030": { + "model_name": "Neuropixels 1.0-NHP - long SOI90 staggered", + "x_pitch": 56, + "y_pitch": 20, + "stagger": 12, + "contact_width": 12, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 2208, + "contour_description": "nhp90", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Neuropixels 1.0-NHP 45mm SOI125 - NHP long 125um wide, staggered contacts + "1031": { + "model_name": "Neuropixels 1.0-NHP - long SOI125 staggered", + "x_pitch": 91, + "y_pitch": 20, + "contact_width": 12, + "stagger": 12.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 2208, + "contour_description": "nhp125", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # 1.0-NHP 45mm SOI115 / 125 linear - NHP long 125um wide, linear contacts + "1032": { + "model_name": "Neuropixels 1.0-NHP - long SOI125 linear", + "x_pitch": 103, + "y_pitch": 20, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 2208, + "contour_description": "nhp125", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Ultra probes 1 bank + "1100": { + "model_name": "Neuropixels Ultra (1 bank)", + "x_pitch": 6, + "y_pitch": 6, + "contact_width": 5, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 8, + "nrows_per_shank": 48, + "contour_description": "np70", + "contour_shift": [-14, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # Ultra probes 16 banks + "1110": { + "model_name": "Neuropixels Ultra (16 banks)", + "x_pitch": 6, + "y_pitch": 6, + "contact_width": 5, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 8, + "nrows_per_shank": 768, + "contour_description": "np70", + "contour_shift": [-14, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + "1121": { + "model_name": "Neuropixels Ultra - Type 2", + "x_pitch": 6, + "y_pitch": 3, + "contact_width": 2, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 1, + "nrows_per_shank": 384, + "contour_description": "np70", + "contour_shift": [-6.25, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, + # NP-Opto + "1300": { + "model_name": "Neuropixels Opto", + "x_pitch": 48, + "y_pitch": 20, + "contact_width": 12, + "stagger": 0.0, + "shank_pitch": 0, + "shank_number": 1, + "ncols_per_shank": 2, + "nrows_per_shank": 480, + "contour_description": "np70", + "contour_shift": [-11, -11], + "fields_in_imro_table": ( + "channel_ids", + "banks", + "references", + "ap_gains", + "lf_gains", + "ap_hp_filters", + ), + }, +} + + +def test_consistency_with_past(): + """ + Test to confirm consistency between ProbeTable and previous ProbeInterface + implementation. For each probe, we get the `npx_description` first using the + `make_npx_description` function, then the old, hard-coded dict (now stored + in this test page). + """ + + # known mismatches between ProbeTable and previous ProbeInterface implementation + # None is the Phase3a probe. + known_mismatches = { + None: ['fields_in_imro_table'], + 'NP1020': ['x_pitch', 'stagger'], + 'NP1021': ['x_pitch', 'stagger'], + 'NP1030': ['x_pitch', 'stagger'], + 'NP1031': ['x_pitch', 'stagger'], + 'NP1110': ['fields_in_imro_table', 'x_pitch'], + 'NP1121': ['x_pitch', 'contact_width'], + } + + for probe_part_number, probe_type in probe_part_number_to_probe_type.items(): + + if probe_part_number not in ["3000", "1200"]: + print(f"Checking probe {probe_part_number}, {probe_type}", flush=True) + probe_info = make_npx_description(probe_part_number) + old_probe_info = npx_descriptions[probe_type] + + for value in ["x_pitch", "y_pitch", "contact_width", "stagger", "shank_pitch", "shank_number", "ncols_per_shank", "nrows_per_shank", "fields_in_imro_table"]: + + if known_mismatches.get(probe_part_number) is not None: + if value in known_mismatches.get(probe_part_number): + continue + + assert probe_info[value] == old_probe_info[value] From 247f538d36822202e5ec2734cda30a85c107341a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 13:39:28 +0000 Subject: [PATCH 02/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/probeinterface/neuropixels_tools.py | 111 ++++++++++++--------- tests/test_neuropixels_backwards_compat.py | 31 ++++-- 2 files changed, 85 insertions(+), 57 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index a9c727f7..e79ee573 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -77,71 +77,87 @@ } pi_to_pt_names = { - 'x_pitch': 'electrode_pitch_horz_um', - 'y_pitch': 'electrode_pitch_vert_um', - 'contact_width': 'electrode_size_horz_direction_um', - 'shank_pitch': 'shank_pitch_um', - 'shank_number': 'num_shanks', - 'ncols_per_shank': 'cols_per_shank', - 'nrows_per_shank': 'rows_per_shank', - 'adc_bit_depth': 'adc_bit_depth' , - 'model_name': 'description', - 'num_readout_channels': 'num_readout_channels', - 'shank_width_um': 'shank_width_um', - 'tip_length_um': 'tip_length_um', + "x_pitch": "electrode_pitch_horz_um", + "y_pitch": "electrode_pitch_vert_um", + "contact_width": "electrode_size_horz_direction_um", + "shank_pitch": "shank_pitch_um", + "shank_number": "num_shanks", + "ncols_per_shank": "cols_per_shank", + "nrows_per_shank": "rows_per_shank", + "adc_bit_depth": "adc_bit_depth", + "model_name": "description", + "num_readout_channels": "num_readout_channels", + "shank_width_um": "shank_width_um", + "tip_length_um": "tip_length_um", } + def make_npx_description(probe_part_number): """ Extracts probe metadata from the `probeinterface/resources/probe_features.json` file and converts - to probeinterface syntax. File is maintained by Bill Karsh in ProbeTable + to probeinterface syntax. File is maintained by Bill Karsh in ProbeTable (https://github.com/billkarsh/ProbeTable/tree/main). Parameters ---------- probe_part_number : str - The part number of the probe e.g. 'NP2013'. + The part number of the probe e.g. 'NP2013'. """ is_phase3a = False # These are all prototype NP1.0 probes, not contained in ProbeTable - if probe_part_number in ['PRB_1_4_0480_1', 'PRB_1_4_0480_1_C', 'PRB_1_2_0480_2', None]: + if probe_part_number in ["PRB_1_4_0480_1", "PRB_1_4_0480_1_C", "PRB_1_2_0480_2", None]: if probe_part_number is None: is_phase3a = True - probe_part_number = 'NP1010' - + probe_part_number = "NP1010" + probe_features_filepath = Path(__file__).absolute().parent / Path("resources/probe_features.json") probe_features = json.load(open(probe_features_filepath, "r")) - pt_metadata = probe_features['neuropixels_probes'].get(probe_part_number) + pt_metadata = probe_features["neuropixels_probes"].get(probe_part_number) if pt_metadata is None: - raise ValueError(f'Probe type {probe_part_number} not supported.') + raise ValueError(f"Probe type {probe_part_number} not supported.") pi_metadata = {} - + # Extract most of the metadata for pi_name, pt_name in pi_to_pt_names.items(): - if pt_name in ['num_shanks', 'cols_per_shank', 'rows_per_shank', 'adc_bit_depth', 'num_readout_channels']: + if pt_name in ["num_shanks", "cols_per_shank", "rows_per_shank", "adc_bit_depth", "num_readout_channels"]: pi_metadata[pi_name] = int(pt_metadata[pt_name]) - elif pt_name in ['electrode_pitch_horz_um', 'electrode_pitch_vert_um', 'electrode_size_horz_direction_um', 'shank_pitch_um']: + elif pt_name in [ + "electrode_pitch_horz_um", + "electrode_pitch_vert_um", + "electrode_size_horz_direction_um", + "shank_pitch_um", + ]: pi_metadata[pi_name] = float(pt_metadata[pt_name]) else: pi_metadata[pi_name] = pt_metadata[pt_name] # Use offsets to compute stagger and contour shift - odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float(pt_metadata['odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um']) - even_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float(pt_metadata['even_row_horz_offset_left_edge_to_leftmost_electrode_center_um']) + odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float( + pt_metadata["odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um"] + ) + even_row_horz_offset_left_edge_to_leftmost_electrode_center_um = float( + pt_metadata["even_row_horz_offset_left_edge_to_leftmost_electrode_center_um"] + ) middle_of_bottommost_electrode_to_top_of_shank_tip = 11 - pi_metadata['contour_shift'] = [-odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um, -middle_of_bottommost_electrode_to_top_of_shank_tip] - pi_metadata['stagger'] = even_row_horz_offset_left_edge_to_leftmost_electrode_center_um - odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um + pi_metadata["contour_shift"] = [ + -odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um, + -middle_of_bottommost_electrode_to_top_of_shank_tip, + ] + pi_metadata["stagger"] = ( + even_row_horz_offset_left_edge_to_leftmost_electrode_center_um + - odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um + ) # Read the imro tables to find out which fields the imro tables contain - imro_table_format_type = pt_metadata['imro_table_format_type'] + imro_table_format_type = pt_metadata["imro_table_format_type"] imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] # parse the imro_table_fields, which look like (value value value ...) - list_of_imro_fields = imro_table_fields.replace('(','').replace(')','').split(" ") - + list_of_imro_fields = imro_table_fields.replace("(", "").replace(")", "").split(" ") + # The Phase3a probe does not contain the `ap_hipas_flt` imro table field. if is_phase3a: list_of_imro_fields.remove("ap_hipas_flt") @@ -149,33 +165,36 @@ def make_npx_description(probe_part_number): pi_imro_fields = [] for imro_field in list_of_imro_fields: pi_imro_fields.append(imro_field_to_pi_field[imro_field]) - pi_metadata['fields_in_imro_table'] = tuple(pi_imro_fields) + pi_metadata["fields_in_imro_table"] = tuple(pi_imro_fields) # Construct probe contour, for styling the probe - shank_width = float(pt_metadata['shank_width_um']) - tip_length = float(pt_metadata['tip_length_um']) + shank_width = float(pt_metadata["shank_width_um"]) + tip_length = float(pt_metadata["tip_length_um"]) probe_length = 10_000 - pi_metadata['contour_description'] = get_probe_contour_vertices(shank_width, tip_length, probe_length) + pi_metadata["contour_description"] = get_probe_contour_vertices(shank_width, tip_length, probe_length) # Get the mux table - mux_table_format_type = pt_metadata['mux_table_format_type'] - mux_information = probe_features['z_mux_tables'].get(mux_table_format_type) - pi_metadata['mux_table_array'] = make_mux_table_array(mux_information) + mux_table_format_type = pt_metadata["mux_table_format_type"] + mux_information = probe_features["z_mux_tables"].get(mux_table_format_type) + pi_metadata["mux_table_array"] = make_mux_table_array(mux_information) return pi_metadata + def make_mux_table_array(mux_information) -> np.array: - + # mux_information looks like (num_adcs num_channels_per_adc)(int int int ...)(int int int ...)...(int int int ...) # First split on ')(' to get a list of the information in the brackets, and remove the leading data split_mux = mux_information.split(")(")[1:] # Then remove the brackets, and split using " " to get each integer as a list - mux_channels = [np.array(each_mux.replace('(','').replace(')','').split(" ")).astype('int') for each_mux in split_mux] + mux_channels = [ + np.array(each_mux.replace("(", "").replace(")", "").split(" ")).astype("int") for each_mux in split_mux + ] mux_channels_array = np.transpose(np.array(mux_channels)) return mux_channels_array - + def get_probe_contour_vertices(shank_width, tip_length, probe_length): """ @@ -187,13 +206,14 @@ def get_probe_contour_vertices(shank_width, tip_length, probe_length): polygon_vertices = [ (0, probe_length), (0, 0), - (shank_width/2, -tip_length), + (shank_width / 2, -tip_length), (shank_width, 0), (shank_width, probe_length), ] return polygon_vertices + def read_imro(file_path: Union[str, Path]) -> Probe: """ Read probe position from the imro file used in input of SpikeGlx and Open-Ephys for neuropixels probes. @@ -380,15 +400,15 @@ def write_imro(file: str | Path, probe: Probe): if probe_type == "0": # Phase3a probe does not have `ap_hp_filters` annotation - if annotations.get('ap_hp_filters') is not None: - + if annotations.get("ap_hp_filters") is not None: + for ch in range(len(data)): ret.append( f"({ch} 0 {annotations['references'][ch]} {annotations['ap_gains'][ch]} " f"{annotations['lf_gains'][ch]} {annotations['ap_hp_filters'][ch]})" ) else: - + for ch in range(len(data)): ret.append( f"({ch} 0 {annotations['references'][ch]} {annotations['ap_gains'][ch]} " @@ -814,7 +834,7 @@ def read_openephys( shank_id = shank_ids[i] if shank_number > 1 else 0 if x_pitch == 0: - contact_id = int( number_of_columns * y_pos / y_pitch) + contact_id = int(number_of_columns * y_pos / y_pitch) else: contact_id = int( (x_pos - row_stagger - shank_pitch * shank_id) / x_pitch + number_of_columns * y_pos / y_pitch @@ -826,7 +846,6 @@ def read_openephys( mux_table_array = probe_dict["mux_table_array"] - np_probe_dict = { "model_name": model_name, "shank_ids": shank_ids, @@ -837,7 +856,7 @@ def read_openephys( "dock": dock, "serial_number": probe_serial_number, "part_number": probe_part_number, - "mux_table_array": mux_table_array + "mux_table_array": mux_table_array, } # Sequentially assign probe names if "custom_probe_name" in np_probe.attrib and np_probe.attrib["custom_probe_name"] != probe_serial_number: diff --git a/tests/test_neuropixels_backwards_compat.py b/tests/test_neuropixels_backwards_compat.py index c6680981..f0dcd664 100644 --- a/tests/test_neuropixels_backwards_compat.py +++ b/tests/test_neuropixels_backwards_compat.py @@ -7,7 +7,6 @@ import pytest - # Map imDatPrb_pn (probe number) to imDatPrb_type (probe type) when the latter is missing probe_part_number_to_probe_type = { # for old version without a probe number we assume NP1.0 @@ -507,13 +506,13 @@ def test_consistency_with_past(): # known mismatches between ProbeTable and previous ProbeInterface implementation # None is the Phase3a probe. known_mismatches = { - None: ['fields_in_imro_table'], - 'NP1020': ['x_pitch', 'stagger'], - 'NP1021': ['x_pitch', 'stagger'], - 'NP1030': ['x_pitch', 'stagger'], - 'NP1031': ['x_pitch', 'stagger'], - 'NP1110': ['fields_in_imro_table', 'x_pitch'], - 'NP1121': ['x_pitch', 'contact_width'], + None: ["fields_in_imro_table"], + "NP1020": ["x_pitch", "stagger"], + "NP1021": ["x_pitch", "stagger"], + "NP1030": ["x_pitch", "stagger"], + "NP1031": ["x_pitch", "stagger"], + "NP1110": ["fields_in_imro_table", "x_pitch"], + "NP1121": ["x_pitch", "contact_width"], } for probe_part_number, probe_type in probe_part_number_to_probe_type.items(): @@ -523,10 +522,20 @@ def test_consistency_with_past(): probe_info = make_npx_description(probe_part_number) old_probe_info = npx_descriptions[probe_type] - for value in ["x_pitch", "y_pitch", "contact_width", "stagger", "shank_pitch", "shank_number", "ncols_per_shank", "nrows_per_shank", "fields_in_imro_table"]: - + for value in [ + "x_pitch", + "y_pitch", + "contact_width", + "stagger", + "shank_pitch", + "shank_number", + "ncols_per_shank", + "nrows_per_shank", + "fields_in_imro_table", + ]: + if known_mismatches.get(probe_part_number) is not None: if value in known_mismatches.get(probe_part_number): continue - + assert probe_info[value] == old_probe_info[value] From bb8237ef03f43e1d6ab087fc18be1312fe9bc892 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Mon, 19 May 2025 18:11:13 +0100 Subject: [PATCH 03/11] update docstrings --- src/probeinterface/neuropixels_tools.py | 60 ++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index e79ee573..93e66dd3 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -101,7 +101,12 @@ def make_npx_description(probe_part_number): Parameters ---------- probe_part_number : str - The part number of the probe e.g. 'NP2013'. + The part number of the probe e.g. 'NP2013'. + + Returns + ------- + pi_metadata : dict + Dictionary containing metadata about NeuroPixels probes using ProbeInterface syntax. """ is_phase3a = False @@ -151,8 +156,8 @@ def make_npx_description(probe_part_number): - odd_row_horz_offset_left_edge_to_leftmost_electrode_center_um ) - # Read the imro tables to find out which fields the imro tables contain - imro_table_format_type = pt_metadata["imro_table_format_type"] + # Read the imro table formats to find out which fields the imro tables contain + imro_table_format_type = pt_metadata['imro_table_format_type'] imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] # parse the imro_table_fields, which look like (value value value ...) @@ -182,7 +187,20 @@ def make_npx_description(probe_part_number): def make_mux_table_array(mux_information) -> np.array: + """ + Function to parse the mux_table from ProbeTable. + Parameters + ---------- + mux_information : str + The information from `z_mux_tables` in the ProbeTable `probe_feature.json` file + + Returns + ------- + mux_channels_array : np.array + Array of which channels are in each adc group, shaped (number of `adc`s, number of channels in each `adc`). + """ + # mux_information looks like (num_adcs num_channels_per_adc)(int int int ...)(int int int ...)...(int int int ...) # First split on ')(' to get a list of the information in the brackets, and remove the leading data split_mux = mux_information.split(")(")[1:] @@ -196,20 +214,48 @@ def make_mux_table_array(mux_information) -> np.array: return mux_channels_array -def get_probe_contour_vertices(shank_width, tip_length, probe_length): +def get_probe_contour_vertices(shank_width, tip_length, probe_length) -> list: """ - Function to get the vertices of the probe contour from probe properties. + Function to get the vertices of the probe contour from probe properties. The probe contour can be constructed + from five points. These are the vertices shown in the following figure: + + A | | E + | | + . + . + . + | | + B | | D + \ / + \/ + C + + This function returns the points indicated in the diagram above in a list [A,B,C,D,E]. + + Parameters + ---------- + shank_width : float + Width of shank (um). + tip_length : float + Length of tip of probe (um). + probe_length : float + Length of entire probe (um). + + Returns + ------- + polygon_vertices : list + List of five points which make up the probe contour. """ # this dict define the contour for one shank (duplicated when several shanks so) # note that a final "contour_shift" is applied - polygon_vertices = [ + polygon_vertices = ( (0, probe_length), (0, 0), (shank_width / 2, -tip_length), (shank_width, 0), (shank_width, probe_length), - ] + ) return polygon_vertices From 11db7ec63c5cec2ad12980d9feb92adc500a2be6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 17:14:01 +0000 Subject: [PATCH 04/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/probeinterface/neuropixels_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index 93e66dd3..6f662342 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -101,7 +101,7 @@ def make_npx_description(probe_part_number): Parameters ---------- probe_part_number : str - The part number of the probe e.g. 'NP2013'. + The part number of the probe e.g. 'NP2013'. Returns ------- @@ -157,7 +157,7 @@ def make_npx_description(probe_part_number): ) # Read the imro table formats to find out which fields the imro tables contain - imro_table_format_type = pt_metadata['imro_table_format_type'] + imro_table_format_type = pt_metadata["imro_table_format_type"] imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] # parse the imro_table_fields, which look like (value value value ...) @@ -200,7 +200,7 @@ def make_mux_table_array(mux_information) -> np.array: mux_channels_array : np.array Array of which channels are in each adc group, shaped (number of `adc`s, number of channels in each `adc`). """ - + # mux_information looks like (num_adcs num_channels_per_adc)(int int int ...)(int int int ...)...(int int int ...) # First split on ')(' to get a list of the information in the brackets, and remove the leading data split_mux = mux_information.split(")(")[1:] From 8d499277437a81b2519aac9a25ae6356c1e3cd3e Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Wed, 28 May 2025 11:19:17 +0100 Subject: [PATCH 05/11] respond to Heberto --- src/probeinterface/neuropixels_tools.py | 107 ++++++++++-------- .../resources/probe_features.json | 2 +- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index 6f662342..3674492b 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -13,13 +13,13 @@ import warnings from packaging.version import parse import json - import numpy as np from .probe import Probe from .utils import import_safely # Map imDatPrb_pn (probe number) to imDatPrb_type (probe type) when the latter is missing +# ONLY needed for `read_imro` function probe_part_number_to_probe_type = { # for old version without a probe number we assume NP1.0 None: "0", @@ -59,8 +59,7 @@ "NP1300": "1300", # Opto probe } -probe_type_to_probe_part_number = {v: k for k, v in probe_part_number_to_probe_type.items()} - +# Map from imro format to ProbeInterface naming conventions imro_field_to_pi_field = { "ap_gain": "ap_gains", "ap_hipas_flt": "ap_hp_filters", @@ -76,6 +75,7 @@ "bankB": "bankB", } +# Map from ProbeInterface to ProbeTable naming conventions pi_to_pt_names = { "x_pitch": "electrode_pitch_horz_um", "y_pitch": "electrode_pitch_vert_um", @@ -91,6 +91,26 @@ "tip_length_um": "tip_length_um", } +def get_probe_length(probe_part_number: str) -> int: + """ + Returns the length of a given probe. We assume a length of + 1cm (10_000 microns) by default. + + Parameters + ---------- + probe_part_number : str + The part number of the probe e.g. 'NP2013'. + + Returns + ------- + probe_length : int + Lenth of full probe (microns) + """ + + probe_length = 10_000 + + return probe_length + def make_npx_description(probe_part_number): """ @@ -109,21 +129,15 @@ def make_npx_description(probe_part_number): Dictionary containing metadata about NeuroPixels probes using ProbeInterface syntax. """ - is_phase3a = False - # These are all prototype NP1.0 probes, not contained in ProbeTable - if probe_part_number in ["PRB_1_4_0480_1", "PRB_1_4_0480_1_C", "PRB_1_2_0480_2", None]: - if probe_part_number is None: - is_phase3a = True - probe_part_number = "NP1010" - probe_features_filepath = Path(__file__).absolute().parent / Path("resources/probe_features.json") probe_features = json.load(open(probe_features_filepath, "r")) + + # We use `pt` and `pi` as shorthand for `ProbeTable` and `ProbeInterface` throughout this function pt_metadata = probe_features["neuropixels_probes"].get(probe_part_number) + pi_metadata = {} if pt_metadata is None: - raise ValueError(f"Probe type {probe_part_number} not supported.") - - pi_metadata = {} + raise ValueError(f"Probe part number {probe_part_number} not supported.") # Extract most of the metadata for pi_name, pt_name in pi_to_pt_names.items(): @@ -159,14 +173,10 @@ def make_npx_description(probe_part_number): # Read the imro table formats to find out which fields the imro tables contain imro_table_format_type = pt_metadata["imro_table_format_type"] imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] - + # parse the imro_table_fields, which look like (value value value ...) list_of_imro_fields = imro_table_fields.replace("(", "").replace(")", "").split(" ") - # The Phase3a probe does not contain the `ap_hipas_flt` imro table field. - if is_phase3a: - list_of_imro_fields.remove("ap_hipas_flt") - pi_imro_fields = [] for imro_field in list_of_imro_fields: pi_imro_fields.append(imro_field_to_pi_field[imro_field]) @@ -175,10 +185,12 @@ def make_npx_description(probe_part_number): # Construct probe contour, for styling the probe shank_width = float(pt_metadata["shank_width_um"]) tip_length = float(pt_metadata["tip_length_um"]) - probe_length = 10_000 + + probe_length = get_probe_length(probe_part_number) pi_metadata["contour_description"] = get_probe_contour_vertices(shank_width, tip_length, probe_length) - # Get the mux table + # Get the mux table. This describes which electrodes are multiplexed together, meaning + # which electrodes are sampled at the same time. mux_table_format_type = pt_metadata["mux_table_format_type"] mux_information = probe_features["z_mux_tables"].get(mux_table_format_type) pi_metadata["mux_table_array"] = make_mux_table_array(mux_information) @@ -279,7 +291,25 @@ def read_imro(file_path: Union[str, Path]) -> Probe: assert meta_file.suffix == ".imro", "'file' should point to the .imro file" with meta_file.open(mode="r") as f: imro_str = str(f.read()) - return _read_imro_string(imro_str) + + imro_table_header_str, *imro_table_values_list, _ = imro_str.strip().split(")") + imro_table_header = tuple(map(int, imro_table_header_str[1:].split(","))) + + if len(imro_table_header) == 3: + # In older versions of neuropixel arrays (phase 3A), imro tables were structured differently. + # We use probe_type "0", which maps to probe_part_number NP1010 as a proxy for Phase3a. + imDatPrb_type = "0" + elif len(imro_table_header) == 2: + imDatPrb_type, _ = imro_table_header + else: + raise ValueError(f"read_imro error, the header has a strange length: {imro_table_header}") + imDatPrb_type = str(imDatPrb_type) + + for probe_part_number, probe_type in probe_part_number_to_probe_type.items(): + if imDatPrb_type == probe_type: + imDatPrb_pn = probe_part_number + + return _read_imro_string(imro_str, imDatPrb_pn) def _make_npx_probe_from_description(probe_description, elec_ids, shank_ids): @@ -369,30 +399,19 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: Optional[str] = None) -> Probe https://billkarsh.github.io/SpikeGLX/help/imroTables/ """ - imro_table_header_str, *imro_table_values_list, _ = imro_str.strip().split(")") - imro_table_header = tuple(map(int, imro_table_header_str[1:].split(","))) - imDatPrb_type = None - if imDatPrb_pn is None: - if len(imro_table_header) == 3: - # In older versions of neuropixel arrays (phase 3A), imro tables were structured differently. - probe_serial_number, probe_option, num_contact = imro_table_header - imDatPrb_type = "Phase3a" - imDatPrb_pn = None - elif len(imro_table_header) == 2: - imDatPrb_type, num_contact = imro_table_header - imDatPrb_type = str(imDatPrb_type) - imDatPrb_pn = probe_type_to_probe_part_number[imDatPrb_type] - else: - raise ValueError(f"read_imro error, the header has a strange length: {imro_table_header}") + probe_type_num_chans, *imro_table_values_list, _ = imro_str.strip().split(")") + + # probe_type_num_chans looks like f"({probe_type},{num_chans}" + probe_type = probe_type_num_chans.split(',')[0][1:] probe_description = make_npx_description(imDatPrb_pn) fields = probe_description["fields_in_imro_table"] contact_info = {k: [] for k in fields} for field_values_str in imro_table_values_list: # Imro table values look like '(value, value, value, ... ' + # Split them by space to get int('value'), int('value'), int('value'), ...) values = tuple(map(int, field_values_str[1:].split(" "))) - # Split them by space to get (int('value'), int('value'), int('value'), ...) for field, field_value in zip(fields, values): contact_info[field].append(field_value) @@ -416,12 +435,12 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: Optional[str] = None) -> Probe # this is scalar annotations probe.annotate( - probe_type=imDatPrb_type, + probe_type=probe_type, ) # this is vector annotations vector_properties = ("channel_ids", "banks", "references", "ap_gains", "lf_gains", "ap_hp_filters") - vector_properties_available = {k: v for k, v in contact_info.items() if k in vector_properties} + vector_properties_available = {k: v for k, v in contact_info.items() if (k in vector_properties) and (len(v)>0) } probe.annotate_contacts(**vector_properties_available) return probe @@ -494,12 +513,6 @@ def read_spikeglx(file: str | Path) -> Probe: The shape is auto generated as a shank. - Now reads: - * NP0.0 (=phase3A) - * NP1.0 (=phase3B2) - * NP2.0 with 4 shank - * NP1.0-NHP - Parameters ---------- file : Path or str @@ -530,6 +543,10 @@ def read_spikeglx(file: str | Path) -> Probe: imDatPrb_slot = meta.get("imDatPrb_slot", None) imDatPrb_part_number = meta.get("imDatPrb_pn", None) + # Only Phase3a probe has "imProbeOpt". Map this to NP10101. + if meta.get("imProbeOpt") is not None: + imDatPrb_pn = "NP1010" + probe = _read_imro_string(imro_str=imro_table, imDatPrb_pn=imDatPrb_pn) # add serial number and other annotations diff --git a/src/probeinterface/resources/probe_features.json b/src/probeinterface/resources/probe_features.json index 2b05e8da..e4d87dfd 100644 --- a/src/probeinterface/resources/probe_features.json +++ b/src/probeinterface/resources/probe_features.json @@ -1886,7 +1886,7 @@ "tip_length_um": "206", "total_electrodes": "5120" }, - "PRB_1_2_480_2": { + "PRB_1_2_0480_2": { "adc_bit_depth": "10", "adc_range_vpp": "1.2", "ap_band_list_hz": "300,10000", From 833b14f20dcf4fe9a76ee07fb40fc73805d4a7af Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 10:19:37 +0000 Subject: [PATCH 06/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/probeinterface/neuropixels_tools.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index 3674492b..4de58499 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -91,15 +91,16 @@ "tip_length_um": "tip_length_um", } + def get_probe_length(probe_part_number: str) -> int: """ - Returns the length of a given probe. We assume a length of + Returns the length of a given probe. We assume a length of 1cm (10_000 microns) by default. Parameters ---------- probe_part_number : str - The part number of the probe e.g. 'NP2013'. + The part number of the probe e.g. 'NP2013'. Returns ------- @@ -173,7 +174,7 @@ def make_npx_description(probe_part_number): # Read the imro table formats to find out which fields the imro tables contain imro_table_format_type = pt_metadata["imro_table_format_type"] imro_table_fields = probe_features["z_imro_formats"][imro_table_format_type + "_elm_flds"] - + # parse the imro_table_fields, which look like (value value value ...) list_of_imro_fields = imro_table_fields.replace("(", "").replace(")", "").split(" ") @@ -190,7 +191,7 @@ def make_npx_description(probe_part_number): pi_metadata["contour_description"] = get_probe_contour_vertices(shank_width, tip_length, probe_length) # Get the mux table. This describes which electrodes are multiplexed together, meaning - # which electrodes are sampled at the same time. + # which electrodes are sampled at the same time. mux_table_format_type = pt_metadata["mux_table_format_type"] mux_information = probe_features["z_mux_tables"].get(mux_table_format_type) pi_metadata["mux_table_array"] = make_mux_table_array(mux_information) @@ -403,7 +404,7 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: Optional[str] = None) -> Probe probe_type_num_chans, *imro_table_values_list, _ = imro_str.strip().split(")") # probe_type_num_chans looks like f"({probe_type},{num_chans}" - probe_type = probe_type_num_chans.split(',')[0][1:] + probe_type = probe_type_num_chans.split(",")[0][1:] probe_description = make_npx_description(imDatPrb_pn) @@ -440,7 +441,7 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: Optional[str] = None) -> Probe # this is vector annotations vector_properties = ("channel_ids", "banks", "references", "ap_gains", "lf_gains", "ap_hp_filters") - vector_properties_available = {k: v for k, v in contact_info.items() if (k in vector_properties) and (len(v)>0) } + vector_properties_available = {k: v for k, v in contact_info.items() if (k in vector_properties) and (len(v) > 0)} probe.annotate_contacts(**vector_properties_available) return probe From 0c42f582fef11a9c4bcf7760975cf26e31cdbb29 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Wed, 28 May 2025 11:33:56 +0100 Subject: [PATCH 07/11] Bits and pieces --- src/probeinterface/neuropixels_tools.py | 7 ++- tests/test_neuropixels_backwards_compat.py | 52 ++-------------------- 2 files changed, 8 insertions(+), 51 deletions(-) diff --git a/src/probeinterface/neuropixels_tools.py b/src/probeinterface/neuropixels_tools.py index 4de58499..b818a249 100644 --- a/src/probeinterface/neuropixels_tools.py +++ b/src/probeinterface/neuropixels_tools.py @@ -138,7 +138,8 @@ def make_npx_description(probe_part_number): pi_metadata = {} if pt_metadata is None: - raise ValueError(f"Probe part number {probe_part_number} not supported.") + warnings.warn(f"Probe part number {probe_part_number} not known. Assume a NP1.0 probe.") + pt_metadata = probe_features["neuropixels_probes"].get("NP1010") # Extract most of the metadata for pi_name, pt_name in pi_to_pt_names.items(): @@ -882,7 +883,7 @@ def read_openephys( model_name = "Unknown" for i, pos in enumerate(positions): - # Do not calculate contact ids if the probe type is not known + # Do not calculate contact ids if the model name is not known if model_name == "Unknown": contact_ids = None break @@ -897,6 +898,8 @@ def read_openephys( # Map the positions to the contacts ids shank_id = shank_ids[i] if shank_number > 1 else 0 + # Contact ids are computed from the positions of the electrodes. The computation + # is different for probes with one row of electrodes, or more than one. if x_pitch == 0: contact_id = int(number_of_columns * y_pos / y_pitch) else: diff --git a/tests/test_neuropixels_backwards_compat.py b/tests/test_neuropixels_backwards_compat.py index f0dcd664..3e4118e4 100644 --- a/tests/test_neuropixels_backwards_compat.py +++ b/tests/test_neuropixels_backwards_compat.py @@ -1,51 +1,5 @@ -from probeinterface import Probe -from probeinterface.neuropixels_tools import make_npx_description -from pathlib import Path +from probeinterface.neuropixels_tools import make_npx_description, probe_part_number_to_probe_type -import numpy as np - -import pytest - - -# Map imDatPrb_pn (probe number) to imDatPrb_type (probe type) when the latter is missing -probe_part_number_to_probe_type = { - # for old version without a probe number we assume NP1.0 - None: "0", - # NP1.0 - "PRB_1_4_0480_1": "0", - "PRB_1_4_0480_1_C": "0", # This is the metal cap version - "PRB_1_2_0480_2": "0", - "NP1010": "0", - # NHP probes lin - "NP1015": "1015", - "NP1016": "1015", - "NP1017": "1015", - # NHP probes stag med - "NP1020": "1020", - "NP1021": "1021", - "NP1022": "1022", - # NHP probes stag long - "NP1030": "1030", - "NP1031": "1031", - "NP1032": "1032", - # NP2.0 - "NP2000": "21", - "NP2010": "24", - "NP2013": "2013", - "NP2014": "2014", - "NP2003": "2003", - "NP2004": "2004", - "PRB2_1_2_0640_0": "21", - "PRB2_4_2_0640_0": "24", - # NXT - "NP2020": "2020", - # Ultra - "NP1100": "1100", # Ultra probe - 1 bank - "NP1110": "1110", # Ultra probe - 16 banks no handle beacuse - "NP1121": "1121", # Ultra probe - beta configuration - # Opto - "NP1300": "1300", # Opto probe -} # this dict define the contour for one shank (duplicated when several shanks so) # note that a final "contour_shift" is applied @@ -506,7 +460,7 @@ def test_consistency_with_past(): # known mismatches between ProbeTable and previous ProbeInterface implementation # None is the Phase3a probe. known_mismatches = { - None: ["fields_in_imro_table"], + # "Phase3a": ["fields_in_imro_table"], "NP1020": ["x_pitch", "stagger"], "NP1021": ["x_pitch", "stagger"], "NP1030": ["x_pitch", "stagger"], @@ -518,7 +472,7 @@ def test_consistency_with_past(): for probe_part_number, probe_type in probe_part_number_to_probe_type.items(): if probe_part_number not in ["3000", "1200"]: - print(f"Checking probe {probe_part_number}, {probe_type}", flush=True) + probe_info = make_npx_description(probe_part_number) old_probe_info = npx_descriptions[probe_type] From dd4d632add146c3b4354f9434837520a4a3d89d7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 10:34:05 +0000 Subject: [PATCH 08/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_neuropixels_backwards_compat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_neuropixels_backwards_compat.py b/tests/test_neuropixels_backwards_compat.py index 3e4118e4..207b2bdf 100644 --- a/tests/test_neuropixels_backwards_compat.py +++ b/tests/test_neuropixels_backwards_compat.py @@ -472,7 +472,7 @@ def test_consistency_with_past(): for probe_part_number, probe_type in probe_part_number_to_probe_type.items(): if probe_part_number not in ["3000", "1200"]: - + probe_info = make_npx_description(probe_part_number) old_probe_info = npx_descriptions[probe_type] From c9973ce3bad90dc0f727316da6fd476c3c26019c Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Sun, 1 Jun 2025 12:06:16 +0100 Subject: [PATCH 09/11] add github action to copy probe features --- .github/workflows/copy_probe_features.yml | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/copy_probe_features.yml diff --git a/.github/workflows/copy_probe_features.yml b/.github/workflows/copy_probe_features.yml new file mode 100644 index 00000000..918b8113 --- /dev/null +++ b/.github/workflows/copy_probe_features.yml @@ -0,0 +1,31 @@ +name: Sync probe_features from ProbeTable + +on: + schedule: + - cron: '0 0 * * 1' # Every Monday at 00:00 UTC + workflow_dispatch: + +jobs: + copy-file: + runs-on: ubuntu-latest + + steps: + - name: Checkout current repository + uses: actions/checkout@v4 + + - name: Copy file from external repo + run: | + # Download the file directly + curl -o src/probeinterface/resources/probe_features.json \ + https://raw.githubusercontent.com/billkarsh/ProbeTable/refs/heads/main/Tables/probe_features.json + + - name: Commit changes if any + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + + git add src/probeinterface/resources/probe_features.json + + # Only commit if there are changes + git diff --staged --quiet || git commit -m "Update probe_features from ProbeTable" + git push \ No newline at end of file From f00695ae388c3bf9e120743f69b79f210f2e316f Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Sun, 1 Jun 2025 12:25:58 +0100 Subject: [PATCH 10/11] try to fix action whitespace --- .github/workflows/copy_probe_features.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/copy_probe_features.yml b/.github/workflows/copy_probe_features.yml index 918b8113..6df0557c 100644 --- a/.github/workflows/copy_probe_features.yml +++ b/.github/workflows/copy_probe_features.yml @@ -2,13 +2,13 @@ name: Sync probe_features from ProbeTable on: schedule: - - cron: '0 0 * * 1' # Every Monday at 00:00 UTC + - cron: '0 0 * * 1' # Every Monday at 00:00 UTC workflow_dispatch: jobs: copy-file: runs-on: ubuntu-latest - + steps: - name: Checkout current repository uses: actions/checkout@v4 @@ -23,9 +23,9 @@ jobs: run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - + git add src/probeinterface/resources/probe_features.json - + # Only commit if there are changes git diff --staged --quiet || git commit -m "Update probe_features from ProbeTable" git push \ No newline at end of file From 851a69649cb8f62ef988493900641a92621f6a63 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Sun, 1 Jun 2025 12:30:05 +0100 Subject: [PATCH 11/11] defo fix whitespace --- .github/workflows/copy_probe_features.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/copy_probe_features.yml b/.github/workflows/copy_probe_features.yml index 6df0557c..0a457987 100644 --- a/.github/workflows/copy_probe_features.yml +++ b/.github/workflows/copy_probe_features.yml @@ -28,4 +28,4 @@ jobs: # Only commit if there are changes git diff --staged --quiet || git commit -m "Update probe_features from ProbeTable" - git push \ No newline at end of file + git push