Skip to content

Commit ec8c842

Browse files
committed
small improvements
1 parent 8c0a3bc commit ec8c842

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

src/probeinterface/probegroup.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,11 @@ def get_slice(self, selection: np.ndarray[bool | int]) -> "ProbeGroup":
427427
if k not in new_probe.annotations:
428428
new_probe.annotate(**{k: orig_probe.annotations[k]})
429429

430+
# probe_planar_contour is a probe-level attribute, not part of the to_numpy dtype,
431+
# so from_numpy cannot restore it; copy it over explicitly.
432+
if orig_probe.probe_planar_contour is not None and new_probe.probe_planar_contour is None:
433+
new_probe.set_planar_contour(orig_probe.probe_planar_contour)
434+
430435
return sliced_probe_group
431436

432437
def select_probes(self, probe_ids: str | np.ndarray | list) -> "ProbeGroup":
@@ -494,6 +499,21 @@ def select_contacts(
494499
f"contact_ids must be unique, but {duplicated.tolist()} appear more than once. "
495500
"If the same contact id is on multiple probes, use probe_ids to disambiguate."
496501
)
502+
# each requested contact id must live on exactly one probe; collect every
503+
# ambiguous one so the user can disambiguate them all at once
504+
ambiguous = {}
505+
for contact_id in contact_ids:
506+
probes_for_id = np.unique(all_probe_ids[all_contact_ids == contact_id]).tolist()
507+
if len(probes_for_id) > 1:
508+
ambiguous[str(contact_id)] = probes_for_id
509+
if ambiguous:
510+
ambiguity_lines = "\n".join(
511+
f'"{contact_id}" lives on probes {probes}' for contact_id, probes in ambiguous.items()
512+
)
513+
message = f"""\
514+
Some contact ids are ambiguous because they live on multiple probes; pass probe_ids to disambiguate which probe each belongs to:
515+
{ambiguity_lines}"""
516+
raise ValueError(message)
497517
probe_ids = [None] * len(contact_ids)
498518
else:
499519
if len(probe_ids) != len(contact_ids):

tests/test_probegroup.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,49 @@ def test_add_probe_default_id_with_non_numeric_ids():
675675
assert pg.probe_ids == ["left", "right", "0"]
676676

677677

678+
def test_select_contacts_ambiguous_id_message_points_to_probe_ids():
679+
"""
680+
When a contact id exists on several probes and no probe_ids are given, the
681+
error must guide the user to pass probe_ids rather than claim it cannot happen.
682+
"""
683+
pg = _probegroup_with_contact_ids(unique=False)
684+
expected_error = """Some contact ids are ambiguous because they live on multiple probes; pass probe_ids to disambiguate which probe each belongs to:
685+
"c0" lives on probes ['0', '1', '2']"""
686+
with pytest.raises(ValueError) as exc_info:
687+
pg.select_contacts(["c0"])
688+
assert str(exc_info.value) == expected_error
689+
690+
691+
def test_select_contacts_reports_all_ambiguous_ids_at_once():
692+
"""
693+
When several requested contact ids are ambiguous, the error lists all of them
694+
(with the probes each lives on) rather than failing on the first one.
695+
"""
696+
pg = _probegroup_with_contact_ids(unique=False)
697+
expected_error = """Some contact ids are ambiguous because they live on multiple probes; pass probe_ids to disambiguate which probe each belongs to:
698+
"c0" lives on probes ['0', '1', '2']
699+
"c1" lives on probes ['0', '1', '2']"""
700+
with pytest.raises(ValueError) as exc_info:
701+
pg.select_contacts(["c0", "c1"])
702+
assert str(exc_info.value) == expected_error
703+
704+
705+
def test_get_slice_preserves_planar_contour():
706+
"""
707+
probe_planar_contour is a probe-level attribute (not part of the to_numpy
708+
dtype), so get_slice must copy it over explicitly instead of losing it.
709+
"""
710+
pg = ProbeGroup()
711+
probe = generate_dummy_probe()
712+
contour = [[-10, -10], [-10, 100], [50, 120], [50, -10]]
713+
probe.set_planar_contour(contour)
714+
pg.add_probe(probe)
715+
716+
sub = pg.get_slice(np.array([0, 1, 2]))
717+
assert sub.probes[0].probe_planar_contour is not None
718+
np.testing.assert_array_equal(sub.probes[0].probe_planar_contour, contour)
719+
720+
678721
if __name__ == "__main__":
679722
probegroup = _make_probegroup()
680723

0 commit comments

Comments
 (0)