Skip to content

Commit c631fbb

Browse files
authored
Merge pull request #177 from h-mayorquin/add_np_ultra_probe
Add ultra probe testing data for spikeglx
2 parents 6108921 + a32ed31 commit c631fbb

File tree

3 files changed

+132
-41
lines changed

3 files changed

+132
-41
lines changed

probeinterface/io.py

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -778,16 +778,7 @@ def write_csv(file, probe):
778778
"elec_ids",
779779
),
780780
},
781-
'Ultra': {
782-
"x_pitch": 6,
783-
"y_pitch": 6,
784-
"contact_width": 5,
785-
"stagger": 0.0,
786-
"shank_pitch": 0,
787-
"shank_number": 1,
788-
"ncol": 8
789-
},
790-
#
781+
# Experimental probes previous to 1.0
791782
"Phase3a": {
792783
"probe_name": "Phase3a",
793784
"x_pitch": 32,
@@ -906,6 +897,26 @@ def write_csv(file, probe):
906897
"ap_hp_filters",
907898
),
908899
},
900+
# Ultra probe
901+
1100: {
902+
"probe_name": "Ultra probe",
903+
"x_pitch": 6,
904+
"y_pitch": 6,
905+
"contact_width": 5,
906+
"stagger": 0.0,
907+
"shank_pitch": 0,
908+
"shank_number": 1,
909+
"ncol": 8,
910+
"polygon": polygon_description["default"],
911+
"fields_in_imro_table": (
912+
"channel_ids",
913+
"banks",
914+
"references",
915+
"ap_gains",
916+
"lf_gains",
917+
"ap_hp_filters",
918+
),
919+
},
909920
}
910921

911922
# Map imDatPrb_pn to imDatPrb_type when the latter is missing
@@ -960,34 +971,35 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: str = None) -> Probe:
960971
imDatPrb_type, num_contact = header
961972
else:
962973
raise RuntimeError(f'read_imro error, the header has a strange length: {len(header)}')
963-
974+
964975
if imDatPrb_type in [0, None]:
965976
imDatPrb_type = probe_number_to_probe_type[imDatPrb_pn]
966977

967-
fields = npx_probe[imDatPrb_type]["fields_in_imro_table"]
978+
probe_description = npx_probe[imDatPrb_type]
979+
fields = probe_description["fields_in_imro_table"]
968980
contact_info = {k: [] for k in fields}
969981
for i, part in enumerate(parts):
970982
values = tuple(map(int, part[1:].split(' ')))
971983
for k, v in zip(fields, values):
972984
contact_info[k].append(v)
973985

974986
channel_ids = np.array(contact_info['channel_ids'])
975-
if 'elec_ids' in contact_info:
976-
elec_ids = np.array(contact_info['elec_ids'])
977-
978-
if imDatPrb_type == 0 or imDatPrb_type == 'Phase3a' or (imDatPrb_type in (1015, 1022, 1030, 1031, 1032)):
979-
# for NP1 and previous the elec_id is not in the list
987+
probe_types_without_elec_ids_in_their_imro_table = (0, 1015, 1022, 1030, 1031, 1032, "Phase3a", 1100)
988+
if imDatPrb_type in probe_types_without_elec_ids_in_their_imro_table:
980989
banks = np.array(contact_info['banks'])
981990
elec_ids = banks * 384 + channel_ids
982-
991+
else:
992+
elec_ids = np.array(contact_info['elec_ids'])
993+
983994
# compute position
984-
y_idx, x_idx = np.divmod(elec_ids, npx_probe[imDatPrb_type]["ncol"])
985-
x_pitch = npx_probe[imDatPrb_type ]["x_pitch"]
986-
y_pitch = npx_probe[imDatPrb_type ]["y_pitch"]
995+
y_idx, x_idx = np.divmod(elec_ids, probe_description["ncol"])
996+
x_pitch = probe_description["x_pitch"]
997+
y_pitch = probe_description["y_pitch"]
987998

988-
stagger = np.mod(y_idx + 1, 2) * npx_probe[imDatPrb_type]["stagger"]
999+
stagger = np.mod(y_idx + 1, 2) * probe_description["stagger"]
9891000
x_pos = x_idx * x_pitch + stagger
9901001
y_pos = y_idx * y_pitch
1002+
positions = np.stack((x_pos, y_pos), axis=1)
9911003

9921004
if imDatPrb_type == 24:
9931005
shank_ids = np.array(contact_info['shank_id'])
@@ -996,31 +1008,31 @@ def _read_imro_string(imro_str: str, imDatPrb_pn: str = None) -> Probe:
9961008
shank_ids = None
9971009
contact_ids = [f'e{elec_id}' for elec_id in elec_ids]
9981010

999-
1000-
positions = np.zeros((num_contact, 2), dtype='float64')
1001-
positions[:, 0] = x_pos
1002-
positions[:, 1] = y_pos
1003-
10041011
# construct Probe object
10051012
probe = Probe(ndim=2, si_units='um')
1006-
probe.set_contacts(positions=positions, shapes='square',
1007-
shank_ids=shank_ids,
1008-
shape_params={'width': npx_probe[imDatPrb_type]["contact_width"]})
1013+
probe.set_contacts(
1014+
positions=positions,
1015+
shapes="square",
1016+
shank_ids=shank_ids,
1017+
shape_params={"width": probe_description["contact_width"]},
1018+
)
1019+
10091020
probe.set_contact_ids(contact_ids)
10101021

10111022
# Add planar contour
1012-
polygon = np.array(npx_probe[imDatPrb_type]["polygon"])
1023+
polygon = np.array(probe_description["polygon"])
10131024
contour = []
1014-
for shank_id in range(npx_probe[imDatPrb_type]["shank_number"]):
1015-
shift = [npx_probe[imDatPrb_type]["shank_pitch"] * shank_id, 0]
1025+
shank_pitch = probe_description["shank_pitch"]
1026+
for shank_id in range(probe_description["shank_number"]):
1027+
shift = [shank_pitch * shank_id, 0]
10161028
contour += list(polygon + shift)
10171029

10181030
# shift
10191031
contour = np.array(contour) - [11, 11]
10201032
probe.set_planar_contour(contour)
10211033

10221034
# this is scalar annotations
1023-
probe_name = npx_probe[imDatPrb_type]["probe_name"]
1035+
probe_name = probe_description["probe_name"]
10241036
probe.annotate(
10251037
name=probe_name,
10261038
manufacturer="IMEC",
@@ -1344,7 +1356,7 @@ def read_openephys(
13441356
ptype = 0
13451357
x_shift = -11
13461358
elif "Ultra" in pname:
1347-
ptype = "Ultra"
1359+
ptype = 1100
13481360
x_shift = -8
13491361
else: # Probe type unknown
13501362
ptype = None

0 commit comments

Comments
 (0)