Skip to content

Commit 61983ff

Browse files
authored
Merge branch 'main' into change_to_hatchling
2 parents d5a12f7 + 35d2b19 commit 61983ff

41 files changed

Lines changed: 10210 additions & 1148 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ dev_*
2525
.coverage
2626
cov.xml
2727
.DS_Store
28+
29+
30+
neuropixel_library_generated/*

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.6.0
3+
rev: v5.0.0
44
hooks:
55
- id: check-yaml
66
- id: end-of-file-fixer
77
- id: trailing-whitespace
88
- repo: https://github.com/psf/black
9-
rev: 24.8.0
9+
rev: 25.1.0
1010
hooks:
1111
- id: black
1212
files: ^src/|^tests/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ In addition, ProbeInterface also offers the following features:
7373

7474
## Documentation
7575

76-
Detailed documentation of the latest PyPI release of ProbeInterface can be found [here](https://probeinterface.readthedocs.io/en/0.2.18).
76+
Detailed documentation of the latest PyPI release of ProbeInterface can be found [here](https://probeinterface.readthedocs.io/en/stable).
7777

7878
Detailed documentation of the development version of ProbeInterface can be found [here](https://probeinterface.readthedocs.io/en/latest).
7979

doc/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Release notes
66
.. toctree::
77
:maxdepth: 1
88

9+
releases/0.2.26.rst
10+
releases/0.2.25.rst
911
releases/0.2.24.rst
1012
releases/0.2.23.rst
1113
releases/0.2.22.rst

doc/releases/0.2.25.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
probeinterface 0.2.25
2+
---------------------
3+
4+
Feb, 6th 2025
5+
6+
7+
Features
8+
^^^^^^^^
9+
10+
* Add cambridge neurotech adaptor to wiring > RHD2164 (#304)
11+
* Refactor neuropixel in a separate file and generate the NP library (#316)
12+
* Regenerate ASSY-1-P1 and ASSY-1-P2 probes (#317)
13+
14+
Bug fixes
15+
^^^^^^^^^
16+
17+
* Fix OpenEphys interface issue with multiple probes of which some are disabled (#308)
18+
* Update schema to floats for radius, width, height (#296, #297)
19+
20+
Tests
21+
^^^^^
22+
23+
* Add json validation to tests (#310)
24+
25+
Packaging
26+
^^^^^^^^^
27+
* Upper bound to zarr version (#314)

doc/releases/0.2.26.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
probeinterface 0.2.26
2+
---------------------
3+
4+
Mar, 11th 2025
5+
6+
7+
Features
8+
^^^^^^^^
9+
10+
* Support OneBox processor for Neuropixels-Open Ephys (#327)
11+
* Wiring pathway for Cambridge A64 adaptor with 2x intan RHD2132 (#306)
12+
* Add support for NP2020 (Neuropixels 2.0 - Quad Base) (#323)
13+
14+
Bug fixes
15+
^^^^^^^^^
16+
17+
* Fix NP contour from Open Ephys and remove `oe_x_shift`(#323)
18+
19+
Tests
20+
^^^^^
21+
22+
* Add test file and test for for NP2 - Quad Base (#328)
23+
24+
Packaging
25+
^^^^^^^^^
26+
* Add json schema to core and make jsonschema dependency optional (#326)
27+
* Rename `-` to `_` in wiring_references (#320)

examples/ex_11_automatic_wiring.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,31 +41,35 @@
4141

4242
##############################################################################
4343
# In order to ease this process, `probeinterface` also includes some commonly
44-
# used wirings based on standard connectors. In our case, we can simply use:
44+
# used wirings based on standard connectors. We created references and spreadsheets
45+
# showing how these wirings are computed at `probeinterface/resources/wiring_references
46+
# <https://github.com/SpikeInterface/probeinterface/tree/9776684948e3ceba71601e5c0f90c2672f665234/resources>`_.
47+
# If we have a Intan RHD2132 Headstage attached to a NeuroNexus H32 Connector, we can
48+
# import this wiring as follows:
4549

4650
probe.wiring_to_device('H32>RHD2132')
4751
print(probe.device_channel_indices)
4852

4953
##############################################################################
5054
# In this figure we have 2 numbers for each contact:
51-
# * the upper number "prbXX" is the Neuronexus index (one-based)
55+
# * the upper number "prbXX" is the contact id (one-based, from NeuroNexus)
5256
# * the lower "devXX" is the channel on the Intan device (zero-based)
5357

5458
fig, ax = plt.subplots(figsize=(5, 15))
5559
plot_probe(probe, with_contact_id=True, with_device_index=True, ax=ax)
5660

5761

58-
plt.show()
59-
60-
"""
61-
Available wiring "pathways"
62-
---------------------------
63-
64-
The available pathways can be found in the `probeinterface.wiring <>`_ module.
65-
66-
The following pathways are available:
67-
"""
62+
##############################################################################
63+
# Available wiring "pathways"
64+
# ---------------------------
65+
#
66+
# The available pathways can be found in the `probeinterface.wiring <https://github.com/SpikeInterface/probeinterface/blob/main/src/probeinterface/wiring.py>`_ module.
67+
#
68+
# The following pathways are available:
69+
#
6870

6971
from probeinterface import get_available_pathways
7072

7173
print(get_available_pathways())
74+
75+
plt.show()

pyproject.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "probeinterface"
3-
version = "0.2.24"
3+
version = "0.2.26"
44
authors = [
55
{ name="Samuel Garcia", email="sam.garcia.die@gmail.com" },
66
{ name="Alessio Buccino", email="alessiop.buccino@gmail.com" },
@@ -37,16 +37,18 @@ packages = ["src/probeinterface"]
3737
[tool.hatch.build.targets.sdist]
3838
packages = ["src/probeinterface"]
3939

40+
4041
[project.optional-dependencies]
4142

4243
test = [
44+
"jsonschema",
4345
"pytest",
4446
"pytest-cov",
4547
"matplotlib",
4648
"scipy",
4749
"pandas",
4850
"h5py",
49-
"zarr>=2.16.0"
51+
"zarr>=2.16.0,<3.0.0"
5052
]
5153

5254
docs = [

resources/generate_cambridgeneurotech_libray.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
# work_dir = '/home/samuel/Documents/SpikeInterface/2022-05-20-probeinterface_CambridgeNeurotech/'
5151
# work_dir = '/home/samuel/Documents/SpikeInterface/2022-10-18-probeinterface_CambridgeNeurotech/'
5252
# work_dir = '/home/samuel/OwnCloudCNRS/probeinterface/2023-06-14-probeinterface-CambridgeNeurotech/'
53-
work_dir = '/home/samuel/OwnCloudCNRS/probeinterface/2023-10-30-probeinterface-CambridgeNeurotech/'
53+
# work_dir = '/home/samuel/OwnCloudCNRS/probeinterface/2023-10-30-probeinterface-CambridgeNeurotech/'
54+
work_dir = '/home/samuel/NextcloudCNRS/probeinterface/2025-01-27-probeinterface-CambridgeNeurotech/'
5455

5556

5657
library_folder = '/home/samuel/Documents/SpikeInterface/probeinterface_library/cambridgeneurotech/'
@@ -59,7 +60,7 @@
5960

6061
work_dir = Path(work_dir).absolute()
6162

62-
export_folder = work_dir / 'export_2023_10_30'
63+
export_folder = work_dir / 'export_2025_01_27'
6364
probe_map_file = work_dir / 'ProbeMaps_Final2023.xlsx'
6465
probe_info_table_file = work_dir / 'ProbesDataBase_Final2023.csv'
6566

@@ -112,18 +113,21 @@ def get_contact_order(connector, probe_type):
112113
if probe_type == 'H5' or probe_type == 'H9':
113114
probe_type = 'H5 & H9'
114115

115-
#~ print(df[probe_type])
116+
# print(df[probe_type])
116117
tmpList = []
117118
for i in df[probe_type].columns:
119+
# print('i', i, len(df[probe_type].columns))
118120
if len(df[probe_type].columns) == 1:
119121
tmpList = np.flip(df[probe_type].values.astype(int).flatten())
120122
else:
121123
tmp = df[probe_type][i].values
122124
tmp = tmp[~np.isnan(tmp)].astype(int) # get rid of nan and convert to integer
123125
tmp = np.flip(tmp) # this flips the value to match index that goes from tip to headstage of the probe
126+
# print('tmp', tmp)
124127
tmpList = np.append(tmpList, tmp)
125128
tmpList = tmpList.astype(int)
126129

130+
# print('tmpList', tmpList)
127131
return tmpList
128132

129133

@@ -200,7 +204,7 @@ def create_CN_figure(probe_name, probe):
200204
ax.spines['right'].set_visible(False) #remove external axis
201205
ax.spines['top'].set_visible(False) #remove external axis
202206

203-
ax.set_title('\n' +'CambridgeNeuroTech' +'\n'+ probe.annotations.get('name'), fontsize = 24)
207+
ax.set_title('\n' +'CambridgeNeuroTech' +'\n'+ probe.annotations.get('model_name'), fontsize = 24)
204208

205209
fig.tight_layout() #modif tight layout
206210

@@ -242,6 +246,11 @@ def generate_all_probes():
242246
for i, probe_info in probe_info_table.iterrows():
243247
print(i, probe_info['part'])
244248

249+
# DEBUG
250+
# if not probe_info['part'] in ('P-1', 'P-2'):
251+
# continue
252+
253+
# print(probe_info)
245254

246255
if probe_info['shanks_n'] == 1:
247256
# one shank
@@ -254,16 +263,29 @@ def generate_all_probes():
254263
for connector in list(probe_info[probe_info.index.str.contains('ASSY')].dropna().index):
255264
probe_name = connector+'-'+probe_info['part']
256265

257-
#~ if probe_name != 'ASSY-77-H10':
258-
#~ continue
266+
# DEBUG
267+
# if connector != 'ASSY-1':
268+
# continue
269+
270+
259271
print(' ', probe_name)
260272

261273
contact_order = get_contact_order(connector = connector, probe_type = probe_info['part'])
262274

275+
# print(probe_unordered)
276+
# print(probe_unordered.contact_ids)
277+
# print(contact_order)
278+
# print(probe_unordered.)
279+
# fig, ax = plt.subplots()
280+
# plot_probe(probe_unordered, ax=ax, with_contact_id=True)
281+
# plt.show()
282+
283+
284+
263285
sorted_indices = np.argsort(contact_order)
264286
probe = probe_unordered.get_slice(sorted_indices)
265287

266-
probe.annotate(name=probe_name, manufacturer='cambridgeneurotech')
288+
probe.annotate(model_name=probe_name, manufacturer='cambridgeneurotech')
267289

268290
# one based in cambridge neurotech
269291
contact_ids = np.arange(sorted_indices.size) + 1
@@ -272,6 +294,7 @@ def generate_all_probes():
272294

273295
export_one_probe(probe_name, probe)
274296

297+
# break
275298

276299
def synchronize_library():
277300

@@ -309,6 +332,8 @@ def synchronize_library():
309332

310333
# library_folder
311334

335+
336+
312337
if __name__ == '__main__':
313-
# generate_all_probes()
338+
generate_all_probes()
314339
synchronize_library()
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import shutil
2+
from pathlib import Path
3+
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
7+
from probeinterface.neuropixels_tools import npx_descriptions, probe_part_number_to_probe_type, _make_npx_probe_from_description
8+
from probeinterface.plotting import plot_probe
9+
from probeinterface import write_probeinterface
10+
11+
12+
base_folder = Path("./neuropixels_library_generated")
13+
14+
15+
16+
def generate_all_npx():
17+
18+
# if not base_folder.exists():
19+
base_folder.mkdir(exist_ok=True)
20+
21+
22+
for probe_number, probe_type in probe_part_number_to_probe_type.items():
23+
24+
if probe_number is None:
25+
continue
26+
27+
if probe_number == "1110":
28+
# the formula by the imrow table is wrong and more complicated
29+
continue
30+
31+
probe_folder = base_folder / probe_number
32+
probe_folder.mkdir(exist_ok=True)
33+
34+
print(probe_number, probe_type)
35+
36+
probe_description = npx_descriptions[probe_type]
37+
38+
39+
40+
num_shank = probe_description["shank_number"]
41+
contact_per_shank = probe_description["ncols_per_shank"] * probe_description["nrows_per_shank"]
42+
if num_shank == 1:
43+
elec_ids = np.arange(contact_per_shank)
44+
shank_ids = None
45+
else:
46+
elec_ids = np.concatenate([np.arange(contact_per_shank) for i in range(num_shank)])
47+
shank_ids = np.concatenate([np.zeros(contact_per_shank) + i for i in range(num_shank)])
48+
49+
probe = _make_npx_probe_from_description(probe_description, elec_ids, shank_ids)
50+
51+
# ploting
52+
fig, axs = plt.subplots(ncols=2)
53+
54+
ax = axs[0]
55+
plot_probe(probe, ax=ax)
56+
ax.set_title("")
57+
58+
ax.xaxis.set_visible(False)
59+
ax.spines["top"].set_visible(False)
60+
ax.spines["right"].set_visible(False)
61+
ax.spines["bottom"].set_visible(False)
62+
63+
ax = axs[1]
64+
65+
66+
# plot_probe(probe, ax=ax, text_on_contact=probe._contact_ids)
67+
plot_probe(probe, ax=ax)
68+
ax.set_title("")
69+
70+
yp = probe_description["y_pitch"]
71+
ax.set_ylim(-yp*8, yp*13)
72+
ax.yaxis.set_visible(False)
73+
ax.spines["top"].set_visible(False)
74+
ax.spines["right"].set_visible(False)
75+
ax.spines["left"].set_visible(False)
76+
77+
n = probe.get_contact_count()
78+
79+
title = probe_number
80+
title += f"\n{probe.manufacturer} - {probe.model_name}"
81+
title += f"\n {n}ch"
82+
if probe.shank_ids is not None:
83+
num_shank = probe.get_shank_count()
84+
title += f" - {num_shank}shanks"
85+
86+
87+
fig.suptitle(title)
88+
89+
# plt.show()
90+
91+
fig.savefig(probe_folder / f"{probe_number}.png")
92+
93+
write_probeinterface(probe_folder / f"{probe_number}.json", probe)
94+
95+
plt.close(fig)
96+
97+
98+
99+
100+
101+
102+
103+
104+
105+
if __name__ == "__main__":
106+
generate_all_npx()

0 commit comments

Comments
 (0)