Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude spacers from dud protocols #899

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions ibllib/io/extractors/ephys_fpga.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"""int: The number of encoder pulses per channel for one complete rotation."""

BPOD_FPGA_DRIFT_THRESHOLD_PPM = 150
"""int: Throws an error if Bpod to FPGA clock drift is higher than this value."""
"""int: Logs a warning if Bpod to FPGA clock drift is higher than this value."""

CHMAPS = {'3A':
{'ap':
Expand Down Expand Up @@ -545,17 +545,23 @@ def get_main_probe_sync(session_path, bin_exists=False):
return sync, sync_chmap


def get_protocol_period(session_path, protocol_number, bpod_sync):
def get_protocol_period(session_path, protocol_number, bpod_sync, exclude_empty_periods=True):
"""
Return the start and end time of the protocol number.

Note that the start time is the start of the spacer pulses and the end time is either None
if the protocol is the final one, or the start of the next spacer.

Parameters
----------
session_path : str, pathlib.Path
The absolute session path, i.e. '/path/to/subject/yyyy-mm-dd/nnn'.
protocol_number : int
The order that the protocol was run in.
The order that the protocol was run in, counted from 0.
bpod_sync : dict
The sync times and polarities for Bpod BNC1.
exclude_empty_periods : bool
When true, spacers are ignored if no bpod pulses are detected between periods.

Returns
-------
Expand All @@ -565,7 +571,14 @@ def get_protocol_period(session_path, protocol_number, bpod_sync):
The time of the next detected spacer or None if this is the last protocol run.
"""
# The spacers are TTLs generated by Bpod at the start of each protocol
spacer_times = Spacer().find_spacers_from_fronts(bpod_sync)
sp = Spacer()
spacer_times = sp.find_spacers_from_fronts(bpod_sync)
if exclude_empty_periods:
# Drop dud protocol spacers (those without any bpod pulses after the spacer)
spacer_length = len(sp.generate_template(fs=1000)) / 1000
periods = np.c_[spacer_times + spacer_length, np.r_[spacer_times[1:], np.inf]]
valid = [np.any((bpod_sync['times'] > pp[0]) & (bpod_sync['times'] < pp[1])) for pp in periods]
spacer_times = spacer_times[valid]
# Ensure that the number of detected spacers matched the number of expected tasks
if acquisition_description := session_params.read_params(session_path):
n_tasks = len(acquisition_description.get('tasks', []))
Expand Down
2 changes: 1 addition & 1 deletion ibllib/pipes/behavior_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from ibllib.pipes import training_status
from ibllib.plots.figures import BehaviourPlots

_logger = logging.getLogger('ibllib')
_logger = logging.getLogger(__name__)


class HabituationRegisterRaw(base_tasks.RegisterRawDataTask, base_tasks.BehaviourTask):
Expand Down
Loading