Skip to content

Commit 9056db8

Browse files
committed
2 parents 41e4d6d + 780352b commit 9056db8

File tree

11 files changed

+85
-65
lines changed

11 files changed

+85
-65
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and
44
[Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention.
55

6+
## [0.3.5] - 2024-08-16
7+
8+
+ Fix - Improve `spikeglx` loader in extracting neuropixels probe type from the meta file
9+
+ Update - Explicit call to `probe.create_neuropixels_probe_types()` to create entries in ProbeType
10+
11+
612
## [0.3.4] - 2024-03-22
713

814
+ Add - pytest

element_array_ephys/ephys_acute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def auto_generate_entries(cls, session_key):
188188

189189
probe_dir = meta_filepath.parent
190190
try:
191-
probe_number = re.search("(imec)?\d{1}$", probe_dir.name).group()
191+
probe_number = re.search(r"(imec)?\d{1}$", probe_dir.name).group()
192192
probe_number = int(probe_number.replace("imec", ""))
193193
except AttributeError:
194194
probe_number = meta_fp_idx

element_array_ephys/ephys_no_curation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def auto_generate_entries(cls, session_key):
189189

190190
probe_dir = meta_filepath.parent
191191
try:
192-
probe_number = re.search("(imec)?\d{1}$", probe_dir.name).group()
192+
probe_number = re.search(r"(imec)?\d{1}$", probe_dir.name).group()
193193
probe_number = int(probe_number.replace("imec", ""))
194194
except AttributeError:
195195
probe_number = meta_fp_idx

element_array_ephys/probe.py

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
"""
2-
Neuropixels Probes
3-
"""
4-
51
import datajoint as dj
62

73
from .readers import probe_geometry
84
from .readers.probe_geometry import build_electrode_layouts
95

6+
log = dj.logger
7+
108
schema = dj.schema()
119

1210

@@ -33,20 +31,6 @@ def activate(
3331
schema_name, create_schema=create_schema, create_tables=create_tables
3432
)
3533

36-
# Add neuropixels probes
37-
for probe_type in (
38-
"neuropixels 1.0 - 3A",
39-
"neuropixels 1.0 - 3B",
40-
"neuropixels UHD",
41-
"neuropixels 2.0 - SS",
42-
"neuropixels 2.0 - MS",
43-
):
44-
if not (ProbeType & {"probe_type": probe_type}):
45-
try:
46-
ProbeType.create_neuropixels_probe(probe_type)
47-
except dj.errors.DataJointError as e:
48-
print(f"Unable to create probe-type: {probe_type}\n{str(e)}")
49-
5034

5135
@schema
5236
class ProbeType(dj.Lookup):
@@ -87,39 +71,10 @@ class Electrode(dj.Part):
8771

8872
@staticmethod
8973
def create_neuropixels_probe(probe_type: str = "neuropixels 1.0 - 3A"):
90-
"""
91-
Create `ProbeType` and `Electrode` for neuropixels probes:
92-
+ neuropixels 1.0 - 3A
93-
+ neuropixels 1.0 - 3B
94-
+ neuropixels UHD
95-
+ neuropixels 2.0 - SS
96-
+ neuropixels 2.0 - MS
97-
98-
For electrode location, the (0, 0) is the
99-
bottom left corner of the probe (ignore the tip portion)
100-
Electrode numbering is 0-indexing
101-
"""
102-
103-
npx_probes_config = probe_geometry.M
104-
npx_probes_config["neuropixels 1.0 - 3A"] = npx_probes_config["3A"]
105-
npx_probes_config["neuropixels 1.0 - 3B"] = npx_probes_config["NP1010"]
106-
npx_probes_config["neuropixels UHD"] = npx_probes_config["NP1100"]
107-
npx_probes_config["neuropixels 2.0 - SS"] = npx_probes_config["NP2000"]
108-
npx_probes_config["neuropixels 2.0 - MS"] = npx_probes_config["NP2010"]
109-
110-
probe_type = {"probe_type": probe_type}
111-
probe_params = dict(
112-
zip(
113-
probe_geometry.geom_param_names,
114-
npx_probes_config[probe_type["probe_type"]],
115-
)
116-
)
117-
electrode_layouts = probe_geometry.build_npx_probe(
118-
**{**probe_params, **probe_type}
74+
log.warning(
75+
"Class method `ProbeType.create_neuropixels_probe` is deprecated. Use `create_neuropixels_probe` instead.",
11976
)
120-
with ProbeType.connection.transaction:
121-
ProbeType.insert1(probe_type, skip_duplicates=True)
122-
ProbeType.Electrode.insert(electrode_layouts, skip_duplicates=True)
77+
return create_neuropixels_probe(probe_type)
12378

12479

12580
@schema
@@ -171,3 +126,49 @@ class Electrode(dj.Part):
171126
-> master
172127
-> ProbeType.Electrode
173128
"""
129+
130+
131+
def create_neuropixels_probe_types():
132+
# Add neuropixels probes
133+
for probe_type in (
134+
"neuropixels 1.0 - 3A",
135+
"neuropixels 1.0 - 3B",
136+
"neuropixels UHD",
137+
"neuropixels 2.0 - SS",
138+
"neuropixels 2.0 - MS",
139+
):
140+
if not (ProbeType & {"probe_type": probe_type}):
141+
create_neuropixels_probe(probe_type)
142+
143+
144+
def create_neuropixels_probe(probe_type: str = "neuropixels 1.0 - 3A"):
145+
"""
146+
Create `ProbeType` and `Electrode` for neuropixels probes:
147+
+ neuropixels 1.0 - 3A
148+
+ neuropixels 1.0 - 3B
149+
+ neuropixels UHD
150+
+ neuropixels 2.0 - SS
151+
+ neuropixels 2.0 - MS
152+
153+
For electrode location, the (0, 0) is the
154+
bottom left corner of the probe (ignore the tip portion)
155+
Electrode numbering is 0-indexing
156+
"""
157+
npx_probes_config = probe_geometry.M
158+
if probe_type not in npx_probes_config:
159+
raise ValueError(
160+
f"Probe type {probe_type} not found in probe_geometry configuration. Not a Neuropixels probe?"
161+
)
162+
163+
probe_params = dict(
164+
zip(
165+
probe_geometry.geom_param_names,
166+
npx_probes_config[probe_type],
167+
)
168+
)
169+
electrode_layouts = probe_geometry.build_npx_probe(
170+
**{**probe_params, "probe_type": probe_type}
171+
)
172+
with ProbeType.connection.transaction:
173+
ProbeType.insert1({"probe_type": probe_type})
174+
ProbeType.Electrode.insert(electrode_layouts)

element_array_ephys/readers/kilosort.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,14 @@ def extract_clustering_info(cluster_output_dir):
201201
is_curated = bool(np.any(curation_row))
202202
if creation_time is None and is_curated:
203203
row_meta = phylog.meta[np.where(curation_row)[0].max()]
204-
datetime_str = re.search("\d{2}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}", row_meta)
204+
datetime_str = re.search(r"\d{2}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}", row_meta)
205205
if datetime_str:
206206
creation_time = datetime.strptime(
207207
datetime_str.group(), "%Y-%m-%d %H:%M:%S"
208208
)
209209
else:
210210
creation_time = datetime.fromtimestamp(phylog_filepath.stat().st_ctime)
211-
time_str = re.search("\d{2}:\d{2}:\d{2}", row_meta)
211+
time_str = re.search(r"\d{2}:\d{2}:\d{2}", row_meta)
212212
if time_str:
213213
creation_time = datetime.combine(
214214
creation_time.date(),

element_array_ephys/readers/kilosort_triggering.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def __init__(
9898

9999
def parse_input_filename(self):
100100
meta_filename = next(self._npx_input_dir.glob("*.ap.meta")).name
101-
match = re.search("(.*)_g(\d)_t(\d+|cat)\.imec(\d?)\.ap\.meta", meta_filename)
101+
match = re.search(r"(.*)_g(\d)_t(\d+|cat)\.imec(\d?)\.ap\.meta", meta_filename)
102102
session_str, gate_str, trigger_str, probe_str = match.groups()
103103
return session_str, gate_str, trigger_str, probe_str or "0"
104104

@@ -719,7 +719,7 @@ def _get_median_subtraction_duration_from_log(self):
719719
) and previous_line.startswith("Total processing time:"):
720720
# regex to search for the processing duration - a float value
721721
duration = int(
722-
re.search("\d+\.?\d+", previous_line).group()
722+
re.search(r"\d+\.?\d+", previous_line).group()
723723
)
724724
return duration
725725
previous_line = line

element_array_ephys/readers/probe_geometry.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@
101101
]
102102
)
103103

104+
# additional alias to maintain compatibility with previous naming in the pipeline
105+
M["neuropixels 1.0 - 3A"] = M["3A"]
106+
M["neuropixels 1.0 - 3B"] = M["NP1010"]
107+
M["neuropixels 1.0"] = M["NP1010"]
108+
M["neuropixels UHD"] = M["NP1100"]
109+
M["neuropixels 2.0 - SS"] = M["NP2000"]
110+
M["neuropixels 2.0 - MS"] = M["NP2010"]
111+
104112

105113
def build_npx_probe(
106114
nShank: int,

element_array_ephys/readers/spikeglx.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,18 @@ def __init__(self, meta_filepath):
262262
self.fname = meta_filepath
263263
self.meta = _read_meta(meta_filepath)
264264

265+
# Get probe part number
266+
self.probe_PN = self.meta.get("imDatPrb_pn", "3A")
267+
265268
# Infer npx probe model (e.g. 1.0 (3A, 3B) or 2.0)
266-
probe_model = self.meta.get("imDatPrb_type", 1)
267-
if probe_model <= 1:
268-
if "typeEnabled" in self.meta:
269+
probe_model = self.meta.get("imDatPrb_type", 0)
270+
if probe_model < 1:
271+
if "typeEnabled" in self.meta and self.probe_PN == "3A":
269272
self.probe_model = "neuropixels 1.0 - 3A"
270-
elif "typeImEnabled" in self.meta:
271-
self.probe_model = "neuropixels 1.0 - 3B"
273+
elif "typeImEnabled" in self.meta and self.probe_PN == "NP1010":
274+
self.probe_model = "neuropixels 1.0"
275+
else:
276+
self.probe_model = self.probe_PN
272277
elif probe_model == 1100:
273278
self.probe_model = "neuropixels UHD"
274279
elif probe_model == 21:
@@ -293,8 +298,6 @@ def __init__(self, meta_filepath):
293298
"Probe Serial Number not found in"
294299
' either "imProbeSN" or "imDatPrb_sn"'
295300
)
296-
# Get probe part number
297-
self.probe_PN = self.meta.get("imDatPrb_pn", "3A")
298301

299302
# Parse channel info
300303
self.chanmap = (

element_array_ephys/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Package metadata."""
22

3-
__version__ = "0.3.4"
3+
__version__ = "0.3.5"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"plotly",
3636
"seaborn",
3737
"spikeinterface",
38-
"scikit-image",
38+
"scikit-image>=0.20",
3939
"nbformat>=4.2.0",
4040
"pyopenephys>=1.1.6",
4141
],

0 commit comments

Comments
 (0)