From fd088e2aad58edab55dcd6296f86f18df645122f Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 15 Sep 2026 14:50:11 -0700 Subject: [PATCH 1/2] slows bias intervention to 20 trials for final and graduated --- schema/coupled_baiting.json | 4 ++-- schema/uncoupled.json | 4 ++-- schema/uncoupled_baiting.json | 4 ++-- .../coupled_baiting/stages.py | 4 ++-- .../uncoupled/stages.py | 4 ++-- .../uncoupled_baiting/stages.py | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/schema/coupled_baiting.json b/schema/coupled_baiting.json index a890441..7694efd 100644 --- a/schema/coupled_baiting.json +++ b/schema/coupled_baiting.json @@ -589,7 +589,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, @@ -703,7 +703,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, diff --git a/schema/uncoupled.json b/schema/uncoupled.json index f649fc2..c69fae8 100644 --- a/schema/uncoupled.json +++ b/schema/uncoupled.json @@ -571,7 +571,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, @@ -665,7 +665,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, diff --git a/schema/uncoupled_baiting.json b/schema/uncoupled_baiting.json index fcd0ac7..0fe7cd4 100644 --- a/schema/uncoupled_baiting.json +++ b/schema/uncoupled_baiting.json @@ -571,7 +571,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, @@ -665,7 +665,7 @@ "upper": 0.5, "lower": 0.0 }, - "intervention_interval": 10, + "intervention_interval": 20, "maximum_water_corrections": 2, "bias_window_length": 200, "lickspout_offset_delta": 0.05, diff --git a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/coupled_baiting/stages.py b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/coupled_baiting/stages.py index a1525fd..b38ba30 100644 --- a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/coupled_baiting/stages.py +++ b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/coupled_baiting/stages.py @@ -336,7 +336,7 @@ def make_s_stage_final(): autowater_parameters=None, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, @@ -387,7 +387,7 @@ def make_s_stage_graduated(): autowater_parameters=None, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, diff --git a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled/stages.py b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled/stages.py index 98fe9b9..0f47107 100644 --- a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled/stages.py +++ b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled/stages.py @@ -333,7 +333,7 @@ def make_s_stage_final(): reward_consumption_duration=3.0, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, @@ -357,7 +357,7 @@ def make_s_stage_graduated(): autowater_parameters=None, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, diff --git a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled_baiting/stages.py b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled_baiting/stages.py index 9d832b9..1e5011b 100644 --- a/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled_baiting/stages.py +++ b/workspace/aind_behavior_dynamic_foraging_curricula/src/aind_behavior_dynamic_foraging_curricula/uncoupled_baiting/stages.py @@ -333,7 +333,7 @@ def make_s_stage_final(): autowater_parameters=None, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, @@ -377,7 +377,7 @@ def make_s_stage_graduated(): autowater_parameters=None, bias_intervention_parameters=BiasInterventionParameters( threshold=BiasThreshold(upper=0.5, lower=0.0), - intervention_interval=10, + intervention_interval=20, maximum_water_corrections=2, bias_window_length=200, lickspout_offset_delta=0.05, From 12d3b325253925cde2da12632a19d9d48c289a01 Mon Sep 17 00:00:00 2001 From: Micah Woodard Date: Tue, 15 Sep 2026 14:56:55 -0700 Subject: [PATCH 2/2] fixes bias window length --- .../trial_generators/block_based_trial_generator.py | 9 ++++++++- .../task_logic/utils/calculate_bias.py | 8 +++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/block_based_trial_generator.py b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/block_based_trial_generator.py index 5d659bc..51c061f 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/block_based_trial_generator.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/block_based_trial_generator.py @@ -192,7 +192,14 @@ def update(self, outcome: TrialOutcome | str): # trial ignored so current baiting state retained pass - self.bias = calculate_bias(outcomes=self.outcome_history) + self.bias = calculate_bias( + outcomes=self.outcome_history, + outcome_window_length=( + 200 + if not self.spec.bias_intervention_parameters + else self.spec.bias_intervention_parameters.bias_window_length + ), + ) def next(self) -> Trial | None: """Generates the next trial in the session. diff --git a/src/aind_behavior_dynamic_foraging/task_logic/utils/calculate_bias.py b/src/aind_behavior_dynamic_foraging/task_logic/utils/calculate_bias.py index 3442641..4e4b875 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/utils/calculate_bias.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/utils/calculate_bias.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) -def calculate_bias(outcomes: List[TrialOutcome]) -> float: +def calculate_bias(outcomes: List[TrialOutcome], outcome_window_length: int = 200) -> float: """Estimate the side bias of an animal using logistic regression on recent trial history. Fits a Su2022-style logistic regression model using rewarded and unrewarded choice @@ -20,7 +20,9 @@ def calculate_bias(outcomes: List[TrialOutcome]) -> float: ---------- outcomes : List[TrialOutcome] List of trial outcomes. Auto-response and ignored trials are excluded. - Only the most recent 200 trials are used. + Only the most recent `outcome_window_length` trials are used. + outcome_window_length : int + Number of recent trials to consider for bias calculation. Returns ------- @@ -34,7 +36,7 @@ def calculate_bias(outcomes: List[TrialOutcome]) -> float: trial_window_length = 5 regularization_strength = 10 - outcomes = outcomes[-200:] + outcomes = outcomes[-outcome_window_length:] # exclude auto response and ignored trials filtered = [t for t in outcomes if t.is_right_choice is not None]