From 6c2c270d15c43189064d230f59fdcb83360f9c11 Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:40:32 -0700 Subject: [PATCH 01/11] Update io.py Updated to newer MaxOne electrode geometry. --- src/probeinterface/io.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index d3d7c5ef..1f88542a 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -519,9 +519,12 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " prb = {"channel_groups": {1: {}}} channels = list(mapping["channel"]) - electrodes = list(mapping["electrode"]) - x_pos = list(mapping["x"]) - y_pos = list(mapping["y"]) + seen = set() + uniqid = [i for i,x in enumerate(channels) if x not in seen and not seen.add(x)] + channels = [channels[i] for i in uniqid] + electrodes = [list(mapping["electrode"])[i] for i in uniqid] + x_pos = [list(mapping["x"])[i] for i in uniqid] + y_pos = [list(mapping["y"])[i] for i in uniqid] geometry = {} for c, x, y in zip(channels, x_pos, y_pos): geometry[c] = [x, y] @@ -535,10 +538,12 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " chans = np.array(prb["channel_groups"][1]["channels"], dtype="int64") positions = np.array([prb["channel_groups"][1]["geometry"][c] for c in chans], dtype="float64") - - probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": 5.45, "height": 9.3}) + + e_w = 8.75 + e_h = 12.5 + probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": e_w, "height": e_h}) probe.annotate_contacts(electrode=electrodes) - probe.set_planar_contour(([-12.5, -12.5], [3845, -12.5], [3845, 2095], [-12.5, 2095])) + probe.set_planar_contour(([-e_w/2, -e_h/2], [3832.5+e_w/2, -e_h/2], [3832.5+e_w/2, 2082.5+e_h/2], [-e_w/2, 2082.5+e_h/2])) probe.set_device_channel_indices(np.arange(positions.shape[0])) From ae97ae2f9bd4f5b708772ea03fb3093aa725ad98 Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:45:16 -0700 Subject: [PATCH 02/11] Update io.py Updated with new MaxOne electrode geometry. From ee7208193c45fb0865d8886d0876e9802ad0328b Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Sun, 29 Jun 2025 22:57:05 -0700 Subject: [PATCH 03/11] Update io.py Updated MaxWell array geometry to newer version and removed non-bijective channel-electrode mapping. --- src/probeinterface/io.py | 50 ++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 1f88542a..9a52bdb8 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -510,6 +510,7 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " h5py = import_safely("h5py") my_file = h5py.File(file, mode="r") + version = int(my_file["version"][0].decode()) if "mapping" in my_file.keys(): mapping = my_file["mapping"][:] @@ -519,12 +520,32 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " prb = {"channel_groups": {1: {}}} channels = list(mapping["channel"]) - seen = set() - uniqid = [i for i,x in enumerate(channels) if x not in seen and not seen.add(x)] - channels = [channels[i] for i in uniqid] - electrodes = [list(mapping["electrode"])[i] for i in uniqid] - x_pos = [list(mapping["x"])[i] for i in uniqid] - y_pos = [list(mapping["y"])[i] for i in uniqid] + electrodes = list(mapping["electrode"]) + assert len(channels) == len(electrodes) + mask = np.full(len(channels), True, dtype=bool) + mask_id = np.argwhere(mask).flatten().tolist() + + # remove all duplicate channel-to-electrode assignments + channels_electrodes = [str(a) + ' ' + str(b) for a,b in zip(channels,electrodes)] + dupid = np.where(pd.DataFrame(channels_electrodes).duplicated(keep='first')) + for i in dupid[0]: + mask[mask_id.pop(i)] = False + + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) + dupid = np.where(pd.DataFrame(channels[mask]).duplicated(keep=False)) + for i in dupid[0]: + mask[mask_id.pop(i)] = False + + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) + dupid = np.where(pd.DataFrame(electrodes[mask]).duplicated(keep='first')) + for i in dupid[0]: + mask[mask_id.pop(i)] = False + + channels = channels[mask] + electrodes = electrodes[mask] + x_pos = list(mapping["x"])[mask] + y_pos = list(mapping["y"])[mask] + geometry = {} for c, x, y in zip(channels, x_pos, y_pos): geometry[c] = [x, y] @@ -538,13 +559,18 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " chans = np.array(prb["channel_groups"][1]["channels"], dtype="int64") positions = np.array([prb["channel_groups"][1]["geometry"][c] for c in chans], dtype="float64") + + if version <= 20160704: + probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": 5.45, "height": 9.3}) + probe.annotate_contacts(electrode=electrodes) + probe.set_planar_contour(([-12.5, -12.5], [3845, -12.5], [3845, 2095], [-12.5, 2095])) + else: + e_w = 8.75 + e_h = 12.5 + probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": e_w, "height": e_h}) + probe.annotate_contacts(electrode=electrodes) + probe.set_planar_contour(([-e_w/2, -e_h/2], [3832.5+e_w/2, -e_h/2], [3832.5+e_w/2, 2082.5+e_h/2], [-e_w/2, 2082.5+e_h/2])) - e_w = 8.75 - e_h = 12.5 - probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": e_w, "height": e_h}) - probe.annotate_contacts(electrode=electrodes) - probe.set_planar_contour(([-e_w/2, -e_h/2], [3832.5+e_w/2, -e_h/2], [3832.5+e_w/2, 2082.5+e_h/2], [-e_w/2, 2082.5+e_h/2])) - probe.set_device_channel_indices(np.arange(positions.shape[0])) return probe From b968bef9de755c6c1cd7c87a62aa347c5bd980aa Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Sun, 29 Jun 2025 22:58:50 -0700 Subject: [PATCH 04/11] Update io.py --- src/probeinterface/io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 9a52bdb8..46291de7 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -504,7 +504,9 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " probe : Probe object """ - + + pd = import_safely("pandas") + file = Path(file).absolute() assert file.is_file() From 38ecd91dbf6482b1b557529a197e0ffa2300fe08 Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Sun, 29 Jun 2025 23:11:21 -0700 Subject: [PATCH 05/11] Update io.py --- src/probeinterface/io.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 46291de7..052bba28 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -521,8 +521,8 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " prb = {"channel_groups": {1: {}}} - channels = list(mapping["channel"]) - electrodes = list(mapping["electrode"]) + channels = np.array(mapping["channel"]) + electrodes = np.array(mapping["electrode"]) assert len(channels) == len(electrodes) mask = np.full(len(channels), True, dtype=bool) mask_id = np.argwhere(mask).flatten().tolist() @@ -545,8 +545,8 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " channels = channels[mask] electrodes = electrodes[mask] - x_pos = list(mapping["x"])[mask] - y_pos = list(mapping["y"])[mask] + x_pos = np.array(mapping["x"])[mask] + y_pos = np.array(mapping["y"])[mask] geometry = {} for c, x, y in zip(channels, x_pos, y_pos): From 6e8c4433dd10d64973af33dd34202ef690ec45e1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 06:21:53 +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/io.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 052bba28..18e09f3a 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -504,9 +504,9 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " probe : Probe object """ - + pd = import_safely("pandas") - + file = Path(file).absolute() assert file.is_file() @@ -528,26 +528,26 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " mask_id = np.argwhere(mask).flatten().tolist() # remove all duplicate channel-to-electrode assignments - channels_electrodes = [str(a) + ' ' + str(b) for a,b in zip(channels,electrodes)] - dupid = np.where(pd.DataFrame(channels_electrodes).duplicated(keep='first')) + channels_electrodes = [str(a) + " " + str(b) for a, b in zip(channels, electrodes)] + dupid = np.where(pd.DataFrame(channels_electrodes).duplicated(keep="first")) for i in dupid[0]: mask[mask_id.pop(i)] = False - + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) dupid = np.where(pd.DataFrame(channels[mask]).duplicated(keep=False)) for i in dupid[0]: mask[mask_id.pop(i)] = False - + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) - dupid = np.where(pd.DataFrame(electrodes[mask]).duplicated(keep='first')) + dupid = np.where(pd.DataFrame(electrodes[mask]).duplicated(keep="first")) for i in dupid[0]: mask[mask_id.pop(i)] = False - + channels = channels[mask] electrodes = electrodes[mask] x_pos = np.array(mapping["x"])[mask] y_pos = np.array(mapping["y"])[mask] - + geometry = {} for c, x, y in zip(channels, x_pos, y_pos): geometry[c] = [x, y] @@ -561,7 +561,7 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " chans = np.array(prb["channel_groups"][1]["channels"], dtype="int64") positions = np.array([prb["channel_groups"][1]["geometry"][c] for c in chans], dtype="float64") - + if version <= 20160704: probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": 5.45, "height": 9.3}) probe.annotate_contacts(electrode=electrodes) @@ -571,8 +571,15 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " e_h = 12.5 probe.set_contacts(positions=positions, shapes="rect", shape_params={"width": e_w, "height": e_h}) probe.annotate_contacts(electrode=electrodes) - probe.set_planar_contour(([-e_w/2, -e_h/2], [3832.5+e_w/2, -e_h/2], [3832.5+e_w/2, 2082.5+e_h/2], [-e_w/2, 2082.5+e_h/2])) - + probe.set_planar_contour( + ( + [-e_w / 2, -e_h / 2], + [3832.5 + e_w / 2, -e_h / 2], + [3832.5 + e_w / 2, 2082.5 + e_h / 2], + [-e_w / 2, 2082.5 + e_h / 2], + ) + ) + probe.set_device_channel_indices(np.arange(positions.shape[0])) return probe From 9ee9ee8d77c7d9660b2099ad7fe245b23e3ac8aa Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:28:18 -0700 Subject: [PATCH 07/11] Update io.py --- src/probeinterface/io.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 18e09f3a..d833bcbf 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -525,24 +525,26 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " electrodes = np.array(mapping["electrode"]) assert len(channels) == len(electrodes) mask = np.full(len(channels), True, dtype=bool) - mask_id = np.argwhere(mask).flatten().tolist() - + # remove all duplicate channel-to-electrode assignments + mask_id = np.argwhere(mask).flatten() channels_electrodes = [str(a) + " " + str(b) for a, b in zip(channels, electrodes)] - dupid = np.where(pd.DataFrame(channels_electrodes).duplicated(keep="first")) - for i in dupid[0]: - mask[mask_id.pop(i)] = False - + [u,u_i,u_v,u_c] = np.unique(channels_electrodes, return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c>1]]: + mask[mask_id[np.argwhere(channels_electrodes == u[i])[1:].flatten()]] = False + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) - dupid = np.where(pd.DataFrame(channels[mask]).duplicated(keep=False)) - for i in dupid[0]: - mask[mask_id.pop(i)] = False - + mask_id = np.argwhere(mask).flatten() + [u,u_i,u_v,u_c] = np.unique(channels[mask], return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c>1]]: + mask[mask_id[np.argwhere(channels[mask] == u[i])[:].flatten()]] = False + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) - dupid = np.where(pd.DataFrame(electrodes[mask]).duplicated(keep="first")) - for i in dupid[0]: - mask[mask_id.pop(i)] = False - + mask_id = np.argwhere(mask).flatten() + [u,u_i,u_v,u_c] = np.unique(electrodes[mask], return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c>1]]: + mask[mask_id[np.argwhere(electrodes[mask] == u[i])[1:].flatten()]] = False + channels = channels[mask] electrodes = electrodes[mask] x_pos = np.array(mapping["x"])[mask] From 55d5f08d63b1b2fb398ac69733ef195409330b27 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 17:28:26 +0000 Subject: [PATCH 08/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/probeinterface/io.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index d833bcbf..f3e8a448 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -525,26 +525,26 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " electrodes = np.array(mapping["electrode"]) assert len(channels) == len(electrodes) mask = np.full(len(channels), True, dtype=bool) - + # remove all duplicate channel-to-electrode assignments mask_id = np.argwhere(mask).flatten() channels_electrodes = [str(a) + " " + str(b) for a, b in zip(channels, electrodes)] - [u,u_i,u_v,u_c] = np.unique(channels_electrodes, return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c>1]]: + [u, u_i, u_v, u_c] = np.unique(channels_electrodes, return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c > 1]]: mask[mask_id[np.argwhere(channels_electrodes == u[i])[1:].flatten()]] = False - + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) mask_id = np.argwhere(mask).flatten() - [u,u_i,u_v,u_c] = np.unique(channels[mask], return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c>1]]: + [u, u_i, u_v, u_c] = np.unique(channels[mask], return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c > 1]]: mask[mask_id[np.argwhere(channels[mask] == u[i])[:].flatten()]] = False - + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) mask_id = np.argwhere(mask).flatten() - [u,u_i,u_v,u_c] = np.unique(electrodes[mask], return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c>1]]: + [u, u_i, u_v, u_c] = np.unique(electrodes[mask], return_index=True, return_inverse=True, return_counts=True) + for i in u_v[u_i[u_c > 1]]: mask[mask_id[np.argwhere(electrodes[mask] == u[i])[1:].flatten()]] = False - + channels = channels[mask] electrodes = electrodes[mask] x_pos = np.array(mapping["x"])[mask] From f35f7ef073c22b7d6b999c0f3494026712b9bb9c Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:30:36 -0700 Subject: [PATCH 09/11] Update io.py --- src/probeinterface/io.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index f3e8a448..b2dedc64 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -505,8 +505,6 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " """ - pd = import_safely("pandas") - file = Path(file).absolute() assert file.is_file() From e0953682e33a7bef27c0de75b5523dc494fda7d5 Mon Sep 17 00:00:00 2001 From: cmccrimmon <103812790+cmccrimmon@users.noreply.github.com> Date: Tue, 1 Jul 2025 09:52:55 -0700 Subject: [PATCH 10/11] Update io.py --- src/probeinterface/io.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index b2dedc64..06da3497 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -523,26 +523,19 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " electrodes = np.array(mapping["electrode"]) assert len(channels) == len(electrodes) mask = np.full(len(channels), True, dtype=bool) - - # remove all duplicate channel-to-electrode assignments - mask_id = np.argwhere(mask).flatten() - channels_electrodes = [str(a) + " " + str(b) for a, b in zip(channels, electrodes)] - [u, u_i, u_v, u_c] = np.unique(channels_electrodes, return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c > 1]]: - mask[mask_id[np.argwhere(channels_electrodes == u[i])[1:].flatten()]] = False - + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) mask_id = np.argwhere(mask).flatten() - [u, u_i, u_v, u_c] = np.unique(channels[mask], return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c > 1]]: + [u, u_c] = np.unique(channels[mask], return_counts=True) + for i in np.argwhere(u_c>1).flatten(): mask[mask_id[np.argwhere(channels[mask] == u[i])[:].flatten()]] = False - + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) mask_id = np.argwhere(mask).flatten() - [u, u_i, u_v, u_c] = np.unique(electrodes[mask], return_index=True, return_inverse=True, return_counts=True) - for i in u_v[u_i[u_c > 1]]: + [u, u_c] = np.unique(electrodes[mask], return_counts=True) + for i in np.argwhere(u_c>1).flatten(): mask[mask_id[np.argwhere(electrodes[mask] == u[i])[1:].flatten()]] = False - + channels = channels[mask] electrodes = electrodes[mask] x_pos = np.array(mapping["x"])[mask] From 2441fa8117133b16acd8916a42349f9ceeeeaac7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 16:53:04 +0000 Subject: [PATCH 11/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/probeinterface/io.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/probeinterface/io.py b/src/probeinterface/io.py index 06da3497..752a4fea 100644 --- a/src/probeinterface/io.py +++ b/src/probeinterface/io.py @@ -523,19 +523,19 @@ def read_maxwell(file: str | Path, well_name: str = "well000", rec_name: str = " electrodes = np.array(mapping["electrode"]) assert len(channels) == len(electrodes) mask = np.full(len(channels), True, dtype=bool) - + # remove all duplicate channel assigments corresponding to different electrodes (channel is a mix of mulitple electrode signals) mask_id = np.argwhere(mask).flatten() [u, u_c] = np.unique(channels[mask], return_counts=True) - for i in np.argwhere(u_c>1).flatten(): + for i in np.argwhere(u_c > 1).flatten(): mask[mask_id[np.argwhere(channels[mask] == u[i])[:].flatten()]] = False - + # remove subsequent duplicated electrodes (single electrode saved to multiple channels) mask_id = np.argwhere(mask).flatten() [u, u_c] = np.unique(electrodes[mask], return_counts=True) - for i in np.argwhere(u_c>1).flatten(): + for i in np.argwhere(u_c > 1).flatten(): mask[mask_id[np.argwhere(electrodes[mask] == u[i])[1:].flatten()]] = False - + channels = channels[mask] electrodes = electrodes[mask] x_pos = np.array(mapping["x"])[mask]