Skip to content

Commit ceec396

Browse files
committed
improve regex
1 parent 90721d3 commit ceec396

File tree

1 file changed

+75
-40
lines changed

1 file changed

+75
-40
lines changed

neo/rawio/spikeglxrawio.py

Lines changed: 75 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -475,47 +475,82 @@ def parse_spikeglx_fname(fname):
475475
stream_kind: str or None
476476
The data type identifier, "lf", "ap", "obx", or None
477477
"""
478-
re_standard = re.findall(r"(\S*)_g(\d*)_t(\d*)\.(\S*).(ap|lf)", fname)
479-
re_tcat = re.findall(r"(\S*)_g(\d*)_tcat.(\S*).(ap|lf)", fname)
480-
re_nidq = re.findall(r"(\S*)_g(\d*)_t(\d*)\.(\S*)", fname)
481-
re_obx = re.findall(r"(\S*)_g(\d*)_t(\d*)\.(\S*)\.obx", fname)
482478

483-
if len(re_standard) == 1:
484-
# standard case with probe
485-
run_name, gate_num, trigger_num, device, stream_kind = re_standard[0]
486-
elif len(re_tcat) == 1:
487-
# tcat case
488-
run_name, gate_num, device, stream_kind = re_tcat[0]
489-
trigger_num = "cat"
490-
elif len(re_obx) == 1:
491-
# OneBox case
492-
run_name, gate_num, trigger_num, device = re_obx[0]
493-
stream_kind = "obx"
494-
elif len(re_nidq) == 1:
495-
# case for nidaq
496-
run_name, gate_num, trigger_num, device = re_nidq[0]
497-
stream_kind = None
498-
else:
499-
# the naming do not correspond lets try something more easy
500-
# example: sglx_xxx.imec0.ap or sglx_xxx.obx0.obx
501-
re_else = re.findall(r"(\S*)\.(\S*).(ap|lf)", fname)
502-
re_else_nidq = re.findall(r"(\S*)\.(\S*)", fname)
503-
if len(re_else) == 1:
504-
run_name, device, stream_kind = re_else[0]
505-
gate_num, trigger_num = None, None
506-
elif len(re_else_nidq) == 1:
507-
# easy case for nidaq, example: sglx_xxx.nidq
508-
run_name, device = re_else_nidq[0]
509-
gate_num, trigger_num, stream_kind = None, None, None
510-
else:
511-
raise ValueError(f"Cannot parse filename {fname}")
512-
513-
if gate_num is not None:
514-
gate_num = int(gate_num)
515-
if trigger_num is not None and trigger_num != "cat":
516-
trigger_num = int(trigger_num)
517-
518-
return (run_name, gate_num, trigger_num, device, stream_kind)
479+
# Standard case: contains gate, trigger, device, and stream kind
480+
# Example: Noise4Sam_g0_t0.imec0.ap
481+
# Format: {run_name}_g{gate_num}_t{trigger_num}.{device}.{stream_kind}
482+
# Regex tokens:
483+
# \S+ → one or more non-whitespace characters
484+
# \d+ → one or more digits
485+
# ap|lf → either 'ap' or 'lf'
486+
regex = r"(?P<run_name>\S+)_g(?P<gate_num>\d+)_t(?P<trigger_num>\d+)\.(?P<device>\S+)\.(?P<stream_kind>ap|lf)"
487+
match = re.match(regex, fname)
488+
if match:
489+
gd = match.groupdict()
490+
return gd["run_name"], int(gd["gate_num"]), int(gd["trigger_num"]), gd["device"], gd["stream_kind"]
491+
492+
# CatGT case: trigger renamed to 'tcat'
493+
# Example: Noise4Sam_g0_tcat.imec0.ap
494+
# Format: {run_name}_g{gate_num}_tcat.{device}.{stream_kind}
495+
# Regex tokens:
496+
# \S+ → one or more non-whitespace characters
497+
# \d+ → one or more digits
498+
# ap|lf → either 'ap' or 'lf'
499+
regex = r"(?P<run_name>\S+)_g(?P<gate_num>\d+)_tcat\.(?P<device>\S+)\.(?P<stream_kind>ap|lf)"
500+
match = re.match(regex, fname)
501+
if match:
502+
gd = match.groupdict()
503+
return gd["run_name"], int(gd["gate_num"]), "cat", gd["device"], gd["stream_kind"]
504+
505+
# OneBox case: ends in .obx
506+
# Example: myRun_g0_t0.obx0.obx
507+
# Format: {run_name}_g{gate_num}_t{trigger_num}.{device}.obx
508+
# Regex tokens:
509+
# \S+ → one or more non-whitespace characters
510+
# \d+ → one or more digits
511+
regex = r"(?P<run_name>\S+)_g(?P<gate_num>\d+)_t(?P<trigger_num>\d+)\.(?P<device>\S+)\.obx"
512+
match = re.match(regex, fname)
513+
if match:
514+
gd = match.groupdict()
515+
return gd["run_name"], int(gd["gate_num"]), int(gd["trigger_num"]), gd["device"], "obx"
516+
517+
# NIDQ case no stream kind (not ap or lf)
518+
# Example: Noise4Sam_g0_t0.nidq
519+
# Format: {run_name}_g{gate_num}_t{trigger_num}.{device}
520+
# Regex tokens:
521+
# \S+ → one or more non-whitespace characters
522+
# \d+ → one or more digits
523+
regex = r"(?P<run_name>\S+)_g(?P<gate_num>\d+)_t(?P<trigger_num>\d+)\.(?P<device>\S+)"
524+
match = re.match(regex, fname)
525+
if match:
526+
gd = match.groupdict()
527+
return gd["run_name"], int(gd["gate_num"]), int(gd["trigger_num"]), gd["device"], None
528+
529+
# Fallback case 1): no gate/trigger, includes device and stream kind
530+
# Example: sglx_name.imec0.ap
531+
# Format: {run_name}.{device}.{stream_kind}
532+
# Regex tokens:
533+
# \S+ → one or more non-whitespace characters
534+
# ap|lf → either 'ap' or 'lf'
535+
regex = r"(?P<run_name>\S+)\.(?P<device>\S+)\.(?P<stream_kind>ap|lf)"
536+
match = re.match(regex, fname)
537+
if match:
538+
gd = match.groupdict()
539+
return gd["run_name"], None, None, gd["device"], gd["stream_kind"]
540+
541+
# Fallback NIDQ-style: no stream kind
542+
# Example: sglx_name.nidq
543+
# Format: {run_name}.{device}
544+
# Regex tokens:
545+
# \S+ → one or more non-whitespace characters
546+
regex = r"(?P<run_name>\S+)\.(?P<device>\S+)"
547+
match = re.match(regex, fname)
548+
if match:
549+
gd = match.groupdict()
550+
return gd["run_name"], None, None, gd["device"], None
551+
552+
# No known pattern matched
553+
raise ValueError(f"Cannot parse filename {fname}")
519554

520555

521556
def read_meta_file(meta_file):

0 commit comments

Comments
 (0)