diff --git a/bonsai/Bonsai.config b/bonsai/Bonsai.config index 1f46300..44af239 100644 --- a/bonsai/Bonsai.config +++ b/bonsai/Bonsai.config @@ -34,6 +34,7 @@ + @@ -107,6 +108,7 @@ + @@ -149,6 +151,7 @@ + diff --git a/examples/coupled_trial_generator.py b/examples/coupled_trial_generator.py new file mode 100644 index 0000000..2cc96cf --- /dev/null +++ b/examples/coupled_trial_generator.py @@ -0,0 +1,22 @@ +import logging +import random + +from aind_behavior_dynamic_foraging.task_logic.trial_generators.coupled_trial_generator import CoupledTrialGeneratorSpec +from aind_behavior_dynamic_foraging.task_logic.trial_models import Trial, TrialOutcome + + +def main(): + coupled_trial_generator = CoupledTrialGeneratorSpec().create_generator() + trial = Trial() + for i in range(100): + trial_outcome = TrialOutcome( + trial=trial, is_right_choice=random.choice([True, False, None]), is_rewarded=random.choice([True, False]) + ) + coupled_trial_generator.update(trial_outcome) + trial = coupled_trial_generator.next() + print(f"Next trial: {trial}") + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + main() diff --git a/examples/task_logic.py b/examples/task_logic.py index a7e13d1..dc16f9d 100644 --- a/examples/task_logic.py +++ b/examples/task_logic.py @@ -8,27 +8,12 @@ task_logic = AindDynamicForagingTaskLogic( task_parameters=AindDynamicForagingTaskParameters( rng_seed=42, - warmup=df_task_logic.Warmup(min_trial=50, max_choice_ratio_bias=0.1, min_finish_ratio=0.8, windowsize=20), - reward_probability=df_task_logic.RewardProbability(base_reward_sum=0.8, family=3, pairs_n=1), - block_parameters=df_task_logic.BlockParameters(min=10, max=30, beta=10, min_reward=0), - inter_trial_interval=df_task_logic.InterTrialInterval(min=1, max=7, beta=3), - delay_period=df_task_logic.DelayPeriod(min=0, max=0, beta=0), - reward_delay=0.1, reward_size=df_task_logic.RewardSize(right_value_volume=4.0, left_value_volume=4.0), - auto_water=df_task_logic.AutoWater( - auto_water_type="Natural", - multiplier=0.5, - unrewarded=3, - ignored=3, - ), - auto_block=df_task_logic.AutoBlock(advanced_block_auto="now", switch_thr=0.5, points_in_a_row=5), - response_time=df_task_logic.Response(response_time=5, reward_consume_time=1), - uncoupled_reward=[0.1, 0.3, 0.7], ) ) -def main(path_seed: str = "./local/PatchForaging_{schema}.json"): +def main(path_seed: str = "./local/DynamicForaging_{schema}.json"): example_task_logic = task_logic example_trainer_state = TrainerState( stage=Stage(name="example_stage", task=example_task_logic), curriculum=None, is_on_curriculum=False diff --git a/pyproject.toml b/pyproject.toml index 10aef73..48eb413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ version = "0.0.2rc13" readme = {file = "README.md", content-type = "text/markdown"} dependencies = [ - "aind_behavior_services<0.14", + "aind_behavior_services>=0.13.2", "pydantic-settings", ] diff --git a/schema/aind_behavior_dynamic_foraging.json b/schema/aind_behavior_dynamic_foraging.json index fdcf1ad..ce6d683 100644 --- a/schema/aind_behavior_dynamic_foraging.json +++ b/schema/aind_behavior_dynamic_foraging.json @@ -3,7 +3,7 @@ "AindDynamicForagingRig": { "properties": { "aind_behavior_services_pkg_version": { - "default": "0.13.0", + "default": "0.13.2", "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", "title": "aind_behavior_services package version", "type": "string" @@ -195,110 +195,11 @@ "title": "Rng Seed" }, "aind_behavior_services_pkg_version": { - "default": "0.13.0", + "default": "0.13.2", "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", "title": "aind_behavior_services package version", "type": "string" }, - "block_parameters": { - "$ref": "#/$defs/BlockParameters", - "default": { - "min": 20, - "max": 60, - "beta": 20, - "min_reward": 1 - }, - "description": "Parameters describing block conditions." - }, - "reward_probability": { - "$ref": "#/$defs/RewardProbability", - "default": { - "base_reward_sum": 0.8, - "family": 1, - "pairs_n": 1 - }, - "description": "Parameters describing reward_probability." - }, - "uncoupled_reward": { - "default": [ - 0.1, - 0.3, - 0.7 - ], - "oneOf": [ - { - "items": { - "type": "number" - }, - "maxItems": 3, - "minItems": 3, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Uncoupled reward" - }, - "randomness": { - "default": "Exponential", - "enum": [ - "Exponential", - "Even" - ], - "title": "Randomness mode", - "type": "string" - }, - "delay_period": { - "$ref": "#/$defs/DelayPeriod", - "default": { - "min": 0.0, - "max": 1.0, - "beta": 1.0 - }, - "description": "Parameters describing delay period." - }, - "reward_delay": { - "default": 0, - "title": "Reward delay (sec)", - "type": "number" - }, - "auto_water": { - "default": null, - "description": "Parameters describing auto water.", - "oneOf": [ - { - "$ref": "#/$defs/aind_behavior_dynamic_foraging__task_logic__AutoWater" - }, - { - "type": "null" - } - ] - }, - "inter_trial_interval": { - "$ref": "#/$defs/InterTrialInterval", - "description": "Parameters describing iti." - }, - "response_time": { - "$ref": "#/$defs/Response", - "default": { - "response_time": 1.0, - "reward_consume_time": 3.0 - }, - "description": "Parameters describing response time." - }, - "auto_block": { - "default": null, - "description": "Parameters describing auto advancement to next block.", - "oneOf": [ - { - "$ref": "#/$defs/AutoBlock" - }, - { - "type": "null" - } - ] - }, "reward_size": { "$ref": "#/$defs/RewardSize", "default": { @@ -307,48 +208,6 @@ }, "description": "Parameters describing reward size." }, - "warmup": { - "default": null, - "description": "Parameters describing warmup.", - "oneOf": [ - { - "$ref": "#/$defs/Warmup" - }, - { - "type": "null" - } - ] - }, - "no_response_trial_addition": { - "default": true, - "description": "Add one trial to the block length on both lickspouts.", - "title": "No Response Trial Addition", - "type": "boolean" - }, - "reward_n": { - "default": null, - "oneOf": [ - { - "$ref": "#/$defs/RewardN" - }, - { - "type": "null" - } - ] - }, - "lick_spout_retraction": { - "default": false, - "description": "Lick spout retraction enabled.", - "oneOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "title": "Lick Spout Retraction" - }, "trial_generator": { "$ref": "#/$defs/TrialGeneratorSpec", "default": { @@ -574,31 +433,6 @@ "title": "AuditorySecondaryReinforcer", "type": "object" }, - "AutoBlock": { - "properties": { - "advanced_block_auto": { - "default": "now", - "enum": [ - "now", - "once" - ], - "title": "Auto block mode", - "type": "string" - }, - "switch_thr": { - "default": 0.5, - "title": "Switch threshold for auto block", - "type": "number" - }, - "points_in_a_row": { - "default": 5, - "title": "Points in a row for auto block", - "type": "integer" - } - }, - "title": "AutoBlock", - "type": "object" - }, "Axis": { "description": "Motor axis available", "enum": [ @@ -680,30 +514,183 @@ "title": "BaseModel", "type": "object" }, - "BlockParameters": { + "BehaviorStabilityParameters": { + "description": "Parameters controlling when behavior is considered stable enough to switch blocks.", "properties": { - "min": { - "default": 20, - "title": "Block length (min)", - "type": "integer" + "behavior_evaluation_mode": { + "default": "end", + "description": "When to evaluate stability \u2014 at the end of the block (end) or at any point during the block (anytime).", + "enum": [ + "end", + "anytime" + ], + "title": "Behavior Evaluation Mode", + "type": "string" }, - "max": { - "default": 60, - "title": "Block length (max)", + "behavior_stability_fraction": { + "default": 0.5, + "description": "Fraction scaling reward-probability difference for behavior.", + "maximum": 1, + "minimum": 0, + "title": "Behavior Stability Fraction", + "type": "number" + }, + "min_consecutive_stable_trials": { + "default": 5, + "description": "Minimum number of consecutive trials satisfying the behavioral stability fraction.", + "minimum": 0, + "title": "Min Consecutive Stable Trials", "type": "integer" + } + }, + "title": "BehaviorStabilityParameters", + "type": "object" + }, + "BetaDistribution": { + "description": "A beta probability distribution.\n\nContinuous distribution bounded between 0 and 1. Commonly used\nfor modeling probabilities and proportions.", + "properties": { + "family": { + "const": "Beta", + "default": "Beta", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/BetaDistributionParameters", + "default": { + "family": "Beta", + "alpha": 5.0, + "beta": 5.0 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "BetaDistribution", + "type": "object" + }, + "BetaDistributionParameters": { + "description": "Parameters for a beta distribution.\n\nDefined by alpha and beta shape parameters.", + "properties": { + "family": { + "const": "Beta", + "default": "Beta", + "title": "Family", + "type": "string" + }, + "alpha": { + "default": 5, + "description": "Alpha parameter of the distribution", + "minimum": 0, + "title": "Alpha", + "type": "number" }, "beta": { - "default": 20, - "title": "Block length (beta)", - "type": "integer" + "default": 5, + "description": "Beta parameter of the distribution", + "minimum": 0, + "title": "Beta", + "type": "number" + } + }, + "title": "BetaDistributionParameters", + "type": "object" + }, + "BinomialDistribution": { + "description": "A binomial probability distribution.\n\nModels the number of successes in a fixed number of independent\nBernoulli trials with constant success probability.", + "properties": { + "family": { + "const": "Binomial", + "default": "Binomial", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/BinomialDistributionParameters", + "default": { + "family": "Binomial", + "n": 1, + "p": 0.5 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "BinomialDistribution", + "type": "object" + }, + "BinomialDistributionParameters": { + "description": "Parameters for a binomial distribution.\n\nDefined by number of trials (n) and success probability (p).", + "properties": { + "family": { + "const": "Binomial", + "default": "Binomial", + "title": "Family", + "type": "string" }, - "min_reward": { + "n": { "default": 1, - "title": "Minimal rewards in a block to switch", + "description": "Number of trials", + "minimum": 0, + "title": "N", "type": "integer" + }, + "p": { + "default": 0.5, + "description": "Probability of success", + "maximum": 1, + "minimum": 0, + "title": "P", + "type": "number" } }, - "title": "BlockParameters", + "title": "BinomialDistributionParameters", "type": "object" }, "CameraController_SpinnakerCamera_": { @@ -832,6 +819,47 @@ "title": "ConnectedClockOutput", "type": "object" }, + "CoupledTrialGenerationEndConditions": { + "description": "Defines the conditions under which a foraging session should terminate.", + "properties": { + "ignore_win": { + "default": 30, + "description": "Number of recent trials to check for ignored responses.", + "minimum": 0, + "title": "Ignore Win", + "type": "integer" + }, + "ignore_ratio_threshold": { + "default": 0.8, + "description": "Maximum fraction of ignored trials within the window before the session is ended.", + "maximum": 1, + "minimum": 0, + "title": "Ignore Ratio Threshold", + "type": "number" + }, + "max_trial": { + "default": 1000, + "description": "Maximum number of trials allowed in a session.", + "minimum": 0, + "title": "Max Trial", + "type": "integer" + }, + "max_time": { + "default": 4500, + "description": "Maximum session duration (sec).", + "title": "Max Time", + "type": "number" + }, + "min_time": { + "default": 1800, + "description": "Minimum session duration (sec)", + "title": "Min Time", + "type": "number" + } + }, + "title": "CoupledTrialGenerationEndConditions", + "type": "object" + }, "CoupledTrialGeneratorSpec": { "properties": { "type": { @@ -840,66 +868,56 @@ "title": "Type", "type": "string" }, - "iti": { + "quiescent_duration": { + "$ref": "#/$defs/Distribution", "default": { "family": "Exponential", "distribution_parameters": { "family": "Exponential", - "rate": 0.5 + "rate": 1.0 }, "truncation_parameters": { - "max": 8.0, - "min": 1.0, + "max": 1.0, + "min": 0.0, "truncation_mode": "exclude" }, "scaling_parameters": null }, - "oneOf": [ - { - "$ref": "#/$defs/UniformDistribution" - }, - { - "$ref": "#/$defs/ExponentialDistribution" - } - ], - "title": "Iti" + "description": "Distribution describing the quiescence period before trial starts (in seconds). Each lick resets the timer." }, - "quiescent_period": { - "default": { - "family": "Exponential", + "response_duration": { + "default": 1.0, + "description": "Duration after go cue for animal response.", + "minimum": 0, + "title": "Response Duration", + "type": "number" + }, + "reward_consumption_duration": { + "default": 3.0, + "description": "Duration of reward consumption before transition to ITI (in seconds).", + "minimum": 0, + "title": "Reward Consumption Duration", + "type": "number" + }, + "inter_trial_interval_duration": { + "$ref": "#/$defs/Distribution", + "default": { + "family": "Exponential", "distribution_parameters": { "family": "Exponential", - "rate": 1.0 + "rate": 0.5 }, "truncation_parameters": { - "max": 1.0, - "min": 0.0, + "max": 8.0, + "min": 1.0, "truncation_mode": "exclude" }, "scaling_parameters": null }, - "oneOf": [ - { - "$ref": "#/$defs/UniformDistribution" - }, - { - "$ref": "#/$defs/ExponentialDistribution" - } - ], - "title": "Quiescent Period" - }, - "response_time": { - "default": 1.0, - "title": "Response time", - "type": "number" + "description": "Distribution describing the inter-trial interval (in seconds)." }, - "reward_consume_time": { - "default": 3.0, - "description": "Time of the no-lick period before trial end", - "title": "Reward consume time", - "type": "number" - }, - "block_parameters": { + "block_len": { + "$ref": "#/$defs/Distribution", "default": { "family": "Exponential", "distribution_parameters": { @@ -913,185 +931,126 @@ }, "scaling_parameters": null }, - "oneOf": [ - { - "$ref": "#/$defs/UniformDistribution" - }, - { - "$ref": "#/$defs/ExponentialDistribution" - } - ], - "title": "Block Parameters" + "description": "Distribution describing block length." }, - "min_reward": { + "min_block_reward": { "default": 1, + "minimum": 0, "title": "Minimal rewards in a block to switch", "type": "integer" }, - "auto_water": { - "default": null, - "description": "Parameters describing auto water.", - "oneOf": [ - { - "$ref": "#/$defs/aind_behavior_dynamic_foraging__task_logic__trial_generators__coupled_trial_generator__AutoWater" - }, - { - "type": "null" - } - ] + "kernel_size": { + "default": 2, + "description": "Kernel to evaluate choice fraction.", + "title": "Kernel Size", + "type": "integer" }, - "behavior_evaluation_mode": { - "default": "ignore", - "enum": [ - "ignore", - "end", - "anytime" - ], - "title": "Auto block mode", - "type": "string" + "reward_probability_parameters": { + "$ref": "#/$defs/RewardProbabilityParameters", + "default": { + "base_reward_sum": 0.8, + "reward_pairs": [ + [ + 8.0, + 1.0 + ] + ] + }, + "description": "Parameters defining the reward probability structure." }, - "switch_thr": { - "default": 0.5, - "title": "Switch threshold for auto block", - "type": "number" + "is_baiting": { + "default": false, + "description": "Whether uncollected rewards carry over to the next trial.", + "title": "Is Baiting", + "type": "boolean" }, - "points_in_a_row": { - "default": 5, - "title": "Points in a row for auto block", - "type": "integer" + "trial_generation_end_parameters": { + "$ref": "#/$defs/CoupledTrialGenerationEndConditions", + "default": { + "ignore_win": 30, + "ignore_ratio_threshold": 0.8, + "max_trial": 1000, + "max_time": 4500.0, + "min_time": 1800.0 + }, + "description": "Conditions to end trial generation." }, - "warmup": { - "default": null, - "description": "Parameters describing warmup.", + "behavior_stability_parameters": { + "default": { + "behavior_evaluation_mode": "end", + "behavior_stability_fraction": 0.5, + "min_consecutive_stable_trials": 5 + }, + "description": "Parameters controlling behavior-dependent block switching. If None, block switches rely only on length and reward criteria.", "oneOf": [ { - "$ref": "#/$defs/Warmup" + "$ref": "#/$defs/BehaviorStabilityParameters" }, { "type": "null" } ] }, - "no_response_trial_addition": { + "extend_block_on_no_response": { "default": true, - "description": "Add one trial to the block length on both lickspouts.", - "title": "No Response Trial Addition", + "description": "Whether to extend the minimum block length by one trial when the animal does not respond.", + "title": "Extend Block On No Response", "type": "boolean" - }, - "kernel_size": { - "title": "Kernel Size", - "type": "integer" - }, - "reward_probability_specs": { - "$ref": "#/$defs/RewardProbability", - "default": { - "base_reward_sum": 0.8, - "family": 1, - "pairs_n": 1 - } - }, - "reward_family": { - "default": [ - [ - [ - 8, - 1 - ], - [ - 6, - 1 - ], - [ - 3, - 1 - ], - [ - 1, - 1 - ] - ], - [ - [ - 8, - 1 - ], - [ - 1, - 1 - ] - ], - [ - [ - 1, - 0 - ], - [ - 0.9, - 0.1 - ], - [ - 0.8, - 0.2 - ], - [ - 0.7, - 0.3 - ], - [ - 0.6, - 0.4 - ], - [ - 0.5, - 0.5 - ] - ], - [ - [ - 6, - 1 - ], - [ - 3, - 1 - ], - [ - 1, - 1 - ] - ] - ], - "items": {}, - "title": "Reward Family", - "type": "array" } }, - "required": [ - "kernel_size" - ], "title": "CoupledTrialGeneratorSpec", "type": "object" }, - "DelayPeriod": { - "properties": { - "min": { - "default": 0.0, - "title": "Delay period (min) ", - "type": "number" + "Distribution": { + "description": "Available distributions", + "discriminator": { + "mapping": { + "Beta": "#/$defs/BetaDistribution", + "Binomial": "#/$defs/BinomialDistribution", + "Exponential": "#/$defs/ExponentialDistribution", + "Gamma": "#/$defs/GammaDistribution", + "LogNormal": "#/$defs/LogNormalDistribution", + "Normal": "#/$defs/NormalDistribution", + "Pdf": "#/$defs/PdfDistribution", + "Poisson": "#/$defs/PoissonDistribution", + "Scalar": "#/$defs/Scalar", + "Uniform": "#/$defs/UniformDistribution" + }, + "propertyName": "family" + }, + "oneOf": [ + { + "$ref": "#/$defs/Scalar" }, - "max": { - "default": 1.0, - "title": "Delay period (max) ", - "type": "number" + { + "$ref": "#/$defs/NormalDistribution" }, - "beta": { - "default": 1.0, - "title": "Delay period (beta)", - "type": "number" + { + "$ref": "#/$defs/LogNormalDistribution" + }, + { + "$ref": "#/$defs/ExponentialDistribution" + }, + { + "$ref": "#/$defs/UniformDistribution" + }, + { + "$ref": "#/$defs/PoissonDistribution" + }, + { + "$ref": "#/$defs/BinomialDistribution" + }, + { + "$ref": "#/$defs/BetaDistribution" + }, + { + "$ref": "#/$defs/GammaDistribution" + }, + { + "$ref": "#/$defs/PdfDistribution" } - }, - "title": "DelayPeriod", - "type": "object" + ], + "title": "Distribution" }, "DynamicForagingSoundCard": { "description": "A calibrated sound card for the dynamic foraging rig. This is a subclass of the HarpSoundCard that includes the sound card calibration.", @@ -1222,6 +1181,79 @@ "title": "ExponentialDistributionParameters", "type": "object" }, + "GammaDistribution": { + "description": "A gamma probability distribution.\n\nGeneralizes the exponential distribution. Used for modeling\npositive continuous variables with right-skewed distributions.", + "properties": { + "family": { + "const": "Gamma", + "default": "Gamma", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/GammaDistributionParameters", + "default": { + "family": "Gamma", + "shape": 1.0, + "rate": 1.0 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "GammaDistribution", + "type": "object" + }, + "GammaDistributionParameters": { + "description": "Parameters for a gamma distribution.\n\nDefined by shape (k) and rate (\u03b8\u207b\u00b9) parameters.", + "properties": { + "family": { + "const": "Gamma", + "default": "Gamma", + "title": "Family", + "type": "string" + }, + "shape": { + "default": 1, + "description": "Shape parameter of the distribution", + "minimum": 0, + "title": "Shape", + "type": "number" + }, + "rate": { + "default": 1, + "description": "Rate parameter of the distribution", + "minimum": 0, + "title": "Rate", + "type": "number" + } + }, + "title": "GammaDistributionParameters", + "type": "object" + }, "HarpBehavior": { "properties": { "device_type": { @@ -1498,132 +1530,399 @@ "title": "IntegrationTestTrialGeneratorSpec", "type": "object" }, - "InterTrialInterval": { + "LogNormalDistribution": { + "description": "A log-normal probability distribution.\n\nDistribution where the logarithm of the variable is normally distributed.\nAlways produces positive values and is right-skewed.", "properties": { - "min": { - "default": 1.0, - "title": "ITI (min)", + "family": { + "const": "LogNormal", + "default": "LogNormal", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/LogNormalDistributionParameters", + "default": { + "family": "LogNormal", + "mean": 0.0, + "std": 0.0 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "LogNormalDistribution", + "type": "object" + }, + "LogNormalDistributionParameters": { + "description": "Parameters for a log-normal distribution.\n\nDefined by the mean and standard deviation of the underlying normal distribution.", + "properties": { + "family": { + "const": "LogNormal", + "default": "LogNormal", + "title": "Family", + "type": "string" + }, + "mean": { + "default": 0, + "description": "Mean of the distribution", + "title": "Mean", "type": "number" }, - "max": { - "default": 8.0, - "title": "ITI (max)", + "std": { + "default": 0, + "description": "Standard deviation of the distribution", + "title": "Std", + "type": "number" + } + }, + "title": "LogNormalDistributionParameters", + "type": "object" + }, + "ManipulatorPosition": { + "description": "Represents a position in the manipulator coordinate system", + "properties": { + "x": { + "title": "X coordinate", "type": "number" }, - "beta": { - "default": 2.0, - "title": "ITI (beta)", + "y1": { + "title": "Y1 coordinate", "type": "number" }, - "increase": { - "default": 0.0, - "title": "ITI increase", + "y2": { + "title": "Y2 coordinate", + "type": "number" + }, + "z": { + "title": "Z coordinate", + "type": "number" + } + }, + "required": [ + "x", + "y1", + "y2", + "z" + ], + "title": "ManipulatorPosition", + "type": "object" + }, + "Measurement": { + "description": "Input for water valve calibration class", + "properties": { + "valve_open_interval": { + "description": "Time between two consecutive valve openings (s)", + "exclusiveMinimum": 0, + "title": "Valve open interval", "type": "number" + }, + "valve_open_time": { + "description": "Valve open interval (s)", + "exclusiveMinimum": 0, + "title": "Valve open time", + "type": "number" + }, + "water_weight": { + "description": "Weight of water delivered (g)", + "items": { + "exclusiveMinimum": 0, + "type": "number" + }, + "minItems": 1, + "title": "Water weight", + "type": "array" + }, + "repeat_count": { + "description": "Number of times the valve opened.", + "minimum": 0, + "title": "Repeat count", + "type": "integer" + } + }, + "required": [ + "valve_open_interval", + "valve_open_time", + "water_weight", + "repeat_count" + ], + "title": "Measurement", + "type": "object" + }, + "MicrostepResolution": { + "description": "Microstep resolution available", + "enum": [ + 0, + 1, + 2, + 3 + ], + "title": "MicrostepResolution", + "type": "integer", + "x-enumNames": [ + "Microstep8", + "Microstep16", + "Microstep32", + "Microstep64" + ] + }, + "MotorOperationMode": { + "description": "Motor operation mode", + "enum": [ + 0, + 1 + ], + "title": "MotorOperationMode", + "type": "integer", + "x-enumNames": [ + "Quiet", + "Dynamic" + ] + }, + "NormalDistribution": { + "description": "A normal (Gaussian) probability distribution.\n\nBell-shaped distribution symmetric around the mean, commonly used\nfor modeling naturally occurring random variables.", + "properties": { + "family": { + "const": "Normal", + "default": "Normal", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/NormalDistributionParameters", + "default": { + "family": "Normal", + "mean": 0.0, + "std": 0.0 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "NormalDistribution", + "type": "object" + }, + "NormalDistributionParameters": { + "description": "Parameters for a normal (Gaussian) distribution.\n\nDefined by mean (center) and standard deviation (spread).", + "properties": { + "family": { + "const": "Normal", + "default": "Normal", + "title": "Family", + "type": "string" + }, + "mean": { + "default": 0, + "description": "Mean of the distribution", + "title": "Mean", + "type": "number" + }, + "std": { + "default": 0, + "description": "Standard deviation of the distribution", + "title": "Std", + "type": "number" + } + }, + "title": "NormalDistributionParameters", + "type": "object" + }, + "PdfDistribution": { + "description": "A custom probability density function distribution.\n\nAllows defining arbitrary discrete distributions by specifying\nprobability values and their corresponding indices.", + "properties": { + "family": { + "const": "Pdf", + "default": "Pdf", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/PdfDistributionParameters", + "default": { + "family": "Pdf", + "pdf": [ + 1.0 + ], + "index": [ + 0.0 + ] + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] + }, + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] + } + }, + "title": "PdfDistribution", + "type": "object" + }, + "PdfDistributionParameters": { + "description": "Parameters for a custom probability density function distribution.\n\nDefined by explicit probability values and their corresponding indices.\nProbabilities are automatically normalized to sum to 1.", + "properties": { + "family": { + "const": "Pdf", + "default": "Pdf", + "title": "Family", + "type": "string" + }, + "pdf": { + "default": [ + 1 + ], + "description": "The probability density function", + "items": { + "minimum": 0, + "type": "number" + }, + "title": "Pdf", + "type": "array" + }, + "index": { + "default": [ + 0 + ], + "description": "The index of the probability density function", + "items": { + "type": "number" + }, + "title": "Index", + "type": "array" } }, - "title": "InterTrialInterval", + "title": "PdfDistributionParameters", "type": "object" }, - "ManipulatorPosition": { - "description": "Represents a position in the manipulator coordinate system", + "PoissonDistribution": { + "description": "A Poisson probability distribution.\n\nModels the number of events occurring in a fixed interval of time or space\nwhen events occur independently at a constant rate.", "properties": { - "x": { - "title": "X coordinate", - "type": "number" + "family": { + "const": "Poisson", + "default": "Poisson", + "title": "Family", + "type": "string" }, - "y1": { - "title": "Y1 coordinate", - "type": "number" + "distribution_parameters": { + "$ref": "#/$defs/PoissonDistributionParameters", + "default": { + "family": "Poisson", + "rate": 1.0 + }, + "description": "Parameters of the distribution" }, - "y2": { - "title": "Y2 coordinate", - "type": "number" + "truncation_parameters": { + "default": null, + "description": "Truncation parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/TruncationParameters" + }, + { + "type": "null" + } + ] }, - "z": { - "title": "Z coordinate", - "type": "number" + "scaling_parameters": { + "default": null, + "description": "Scaling parameters of the distribution", + "oneOf": [ + { + "$ref": "#/$defs/ScalingParameters" + }, + { + "type": "null" + } + ] } }, - "required": [ - "x", - "y1", - "y2", - "z" - ], - "title": "ManipulatorPosition", + "title": "PoissonDistribution", "type": "object" }, - "Measurement": { - "description": "Input for water valve calibration class", + "PoissonDistributionParameters": { + "description": "Parameters for a Poisson distribution.\n\nDefined by the rate parameter (average number of events).", "properties": { - "valve_open_interval": { - "description": "Time between two consecutive valve openings (s)", - "exclusiveMinimum": 0, - "title": "Valve open interval", - "type": "number" - }, - "valve_open_time": { - "description": "Valve open interval (s)", - "exclusiveMinimum": 0, - "title": "Valve open time", - "type": "number" - }, - "water_weight": { - "description": "Weight of water delivered (g)", - "items": { - "exclusiveMinimum": 0, - "type": "number" - }, - "minItems": 1, - "title": "Water weight", - "type": "array" + "family": { + "const": "Poisson", + "default": "Poisson", + "title": "Family", + "type": "string" }, - "repeat_count": { - "description": "Number of times the valve opened.", + "rate": { + "default": 1, + "description": "Rate parameter of the Poisson process that generates the distribution", "minimum": 0, - "title": "Repeat count", - "type": "integer" + "title": "Rate", + "type": "number" } }, - "required": [ - "valve_open_interval", - "valve_open_time", - "water_weight", - "repeat_count" - ], - "title": "Measurement", + "title": "PoissonDistributionParameters", "type": "object" }, - "MicrostepResolution": { - "description": "Microstep resolution available", - "enum": [ - 0, - 1, - 2, - 3 - ], - "title": "MicrostepResolution", - "type": "integer", - "x-enumNames": [ - "Microstep8", - "Microstep16", - "Microstep32", - "Microstep64" - ] - }, - "MotorOperationMode": { - "description": "Motor operation mode", - "enum": [ - 0, - 1 - ], - "title": "MotorOperationMode", - "type": "integer", - "x-enumNames": [ - "Quiet", - "Dynamic" - ] - }, "Rect": { "description": "Represents a rectangle defined by its top-left corner, width, and height.", "properties": { @@ -1659,69 +1958,51 @@ "title": "Rect", "type": "object" }, - "Response": { - "properties": { - "response_time": { - "default": 1.0, - "title": "Response time", - "type": "number" - }, - "reward_consume_time": { - "default": 3.0, - "description": "Time of the no-lick period before trial end", - "title": "Reward consume time", - "type": "number" - } - }, - "title": "Response", - "type": "object" - }, - "RewardN": { - "properties": { - "initial_inactive_trials": { - "default": 2, - "description": "Initial N trials of the active side where no bait will be be given.", - "title": "Initial Inactive Trials", - "type": "integer" - } - }, - "title": "RewardN", - "type": "object" - }, - "RewardProbability": { + "RewardProbabilityParameters": { + "description": "Defines the reward probability structure for a dynamic foraging task.\n\nReward probabilities are defined as pairs (p_left, p_right) normalized by\nbase_reward_sum. Pairs are drawn from a family representing a difficulty level:\n\n Family 0: [[8, 1], [6, 1], [3, 1], [1, 1]]\n Family 1: [[8, 1], [1, 1]]\n Family 2: [[1.0, 0.0], [0.9, 0.1], [0.8, 0.2], [0.7, 0.3], [0.6, 0.4], [0.5, 0.5]]\n Family 3: [[6, 1], [3, 1], [1, 1]]", "properties": { "base_reward_sum": { "default": 0.8, - "title": "Sum of p_reward", + "description": "Total reward probability shared between the two sides. Each reward pair is normalized to sum to this value.", + "title": "Base Reward Sum", "type": "number" }, - "family": { - "default": 1, - "title": "Reward family", - "type": "integer" - }, - "pairs_n": { - "default": 1, - "title": "Number of pairs", - "type": "integer" + "reward_pairs": { + "default": [ + [ + 8, + 1 + ] + ], + "description": "List of (left, right) reward ratio pairs to sample from during block transitions. ", + "items": { + "items": { + "type": "number" + }, + "type": "array" + }, + "title": "Reward Pairs", + "type": "array" } }, - "title": "RewardProbability", + "title": "RewardProbabilityParameters", "type": "object" }, "RewardSize": { "properties": { "right_value_volume": { - "default": 3.0, "title": "Right reward size (uL)", "type": "number" }, "left_value_volume": { - "default": 3.0, "title": "Left reward size (uL)", "type": "number" } }, + "required": [ + "right_value_volume", + "left_value_volume" + ], "title": "RewardSize", "type": "object" }, @@ -1744,6 +2025,58 @@ "title": "RigCalibration", "type": "object" }, + "Scalar": { + "description": "A scalar distribution that returns a constant value.\n\nUseful for fixed parameters that don't vary across trials or samples.", + "properties": { + "family": { + "const": "Scalar", + "default": "Scalar", + "title": "Family", + "type": "string" + }, + "distribution_parameters": { + "$ref": "#/$defs/ScalarDistributionParameter", + "default": { + "family": "Scalar", + "value": 0.0 + }, + "description": "Parameters of the distribution" + }, + "truncation_parameters": { + "const": null, + "default": null, + "title": "Truncation Parameters", + "type": "null" + }, + "scaling_parameters": { + "const": null, + "default": null, + "title": "Scaling Parameters", + "type": "null" + } + }, + "title": "Scalar", + "type": "object" + }, + "ScalarDistributionParameter": { + "description": "Parameters for a scalar (constant) distribution.\n\nRepresents a deterministic value that always returns the same number.", + "properties": { + "family": { + "const": "Scalar", + "default": "Scalar", + "title": "Family", + "type": "string" + }, + "value": { + "default": 0, + "description": "The static value of the distribution", + "title": "Value", + "type": "number" + } + }, + "title": "ScalarDistributionParameter", + "type": "object" + }, "ScalingParameters": { "description": "Parameters for scaling and offsetting sampled distribution values.\nScaling is applied as (value * scale + offset).\n\nApplies linear transformation: result = (value * scale) + offset.", "properties": { @@ -1780,14 +2113,14 @@ "Session": { "properties": { "aind_behavior_services_pkg_version": { - "default": "0.13.0", + "default": "0.13.2", "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", "title": "aind_behavior_services package version", "type": "string" }, "version": { - "const": "0.13.0", - "default": "0.13.0", + "const": "0.13.2", + "default": "0.13.2", "title": "Version", "type": "string" }, @@ -2674,13 +3007,13 @@ "type": "integer" }, "container_extension": { - "default": "mp4", + "default": "mkv", "description": "Container extension", "title": "Container Extension", "type": "string" }, "output_arguments": { - "default": "-vf \"scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full\" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author=\"Allen Institute for Neural Dynamics\" -maxrate 700M -bufsize 350M", + "default": "-vf \"scale=out_range=full,setparams=range=full:colorspace=bt709:color_primaries=bt709:color_trc=linear\" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p3 -rc vbr -cq 18 -b:v 0M -metadata author=\"Allen Institute for Neural Dynamics\" -maxrate 700M -bufsize 350M -f matroska -write_crc32 0", "description": "Output arguments", "title": "Output Arguments", "type": "string" @@ -2727,40 +3060,22 @@ "title": "VideoWriterOpenCv", "type": "object" }, - "Warmup": { - "properties": { - "min_trial": { - "default": 50, - "title": "Warmup finish criteria: minimal trials", - "type": "integer" - }, - "max_choice_ratio_bias": { - "default": 0.1, - "title": "Warmup finish criteria: maximal choice ratio bias from 0.5", - "type": "number" - }, - "min_finish_ratio": { - "default": 0.8, - "title": "Warmup finish criteria: minimal finish ratio", - "type": "number" - }, - "windowsize": { - "default": 20, - "title": "Warmup finish criteria: window size to compute the bias and ratio", - "type": "integer" - } - }, - "title": "Warmup", - "type": "object" - }, "WaterValveCalibration": { "description": "Represents a water valve calibration.", "properties": { "date": { + "default": null, "description": "Date of the calibration", - "format": "date-time", - "title": "Date", - "type": "string" + "oneOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Date" }, "measurements": { "default": [], @@ -2929,74 +3244,6 @@ }, "title": "WebCamera", "type": "object" - }, - "aind_behavior_dynamic_foraging__task_logic__AutoWater": { - "properties": { - "auto_water_type": { - "default": "Natural", - "enum": [ - "Natural", - "Both", - "High pro" - ], - "title": "Auto water mode", - "type": "string" - }, - "multiplier": { - "default": 0.8, - "title": "Multiplier for auto reward", - "type": "number" - }, - "unrewarded": { - "default": 200, - "title": "Number of unrewarded trials before auto water", - "type": "integer" - }, - "ignored": { - "default": 100, - "title": "Number of ignored trials before auto water", - "type": "integer" - }, - "include_reward": { - "default": false, - "description": "Include auto water in total rewards.", - "title": "Include Reward", - "type": "boolean" - } - }, - "title": "AutoWater", - "type": "object" - }, - "aind_behavior_dynamic_foraging__task_logic__trial_generators__coupled_trial_generator__AutoWater": { - "properties": { - "auto_water_type": { - "default": "Natural", - "enum": [ - "Natural", - "Both", - "High pro" - ], - "title": "Auto water mode", - "type": "string" - }, - "multiplier": { - "default": 0.8, - "title": "Multiplier for auto reward", - "type": "number" - }, - "unrewarded": { - "default": 200, - "title": "Number of unrewarded trials before auto water", - "type": "integer" - }, - "ignored": { - "default": 100, - "title": "Number of ignored trials before auto water", - "type": "integer" - } - }, - "title": "AutoWater", - "type": "object" } } } \ No newline at end of file diff --git a/src/Extensions/AindBehaviorDynamicForaging.Generated.cs b/src/Extensions/AindBehaviorDynamicForaging.Generated.cs index 7618944..b27a6dd 100644 --- a/src/Extensions/AindBehaviorDynamicForaging.Generated.cs +++ b/src/Extensions/AindBehaviorDynamicForaging.Generated.cs @@ -49,7 +49,7 @@ public partial class AindDynamicForagingRig public AindDynamicForagingRig() { - _aindBehaviorServicesPkgVersion = "0.13.0"; + _aindBehaviorServicesPkgVersion = "0.13.2"; _version = "0.0.2-rc13"; _triggeredCameraController = new CameraControllerSpinnakerCamera(); _harpBehavior = new HarpBehavior(); @@ -584,50 +584,14 @@ public partial class AindDynamicForagingTaskParameters private string _aindBehaviorServicesPkgVersion; - private BlockParameters _blockParameters; - - private RewardProbability _rewardProbability; - - private System.Collections.Generic.List _uncoupledReward; - - private AindDynamicForagingTaskParametersRandomness _randomness; - - private DelayPeriod _delayPeriod; - - private double _rewardDelay; - - private AindBehaviorDynamicForagingTaskLogicAutoWater _autoWater; - - private InterTrialInterval _interTrialInterval; - - private Response _responseTime; - - private AutoBlock _autoBlock; - private RewardSize _rewardSize; - private Warmup _warmup; - - private bool _noResponseTrialAddition; - - private RewardN _rewardN; - - private bool? _lickSpoutRetraction; - private TrialGeneratorSpec _trialGenerator; public AindDynamicForagingTaskParameters() { - _aindBehaviorServicesPkgVersion = "0.13.0"; - _blockParameters = new BlockParameters(); - _rewardProbability = new RewardProbability(); - _randomness = AindDynamicForagingTaskParametersRandomness.Exponential; - _delayPeriod = new DelayPeriod(); - _rewardDelay = 0D; - _responseTime = new Response(); + _aindBehaviorServicesPkgVersion = "0.13.2"; _rewardSize = new RewardSize(); - _noResponseTrialAddition = true; - _lickSpoutRetraction = false; _trialGenerator = new TrialGeneratorSpec(); } @@ -635,21 +599,7 @@ protected AindDynamicForagingTaskParameters(AindDynamicForagingTaskParameters ot { _rngSeed = other._rngSeed; _aindBehaviorServicesPkgVersion = other._aindBehaviorServicesPkgVersion; - _blockParameters = other._blockParameters; - _rewardProbability = other._rewardProbability; - _uncoupledReward = other._uncoupledReward; - _randomness = other._randomness; - _delayPeriod = other._delayPeriod; - _rewardDelay = other._rewardDelay; - _autoWater = other._autoWater; - _interTrialInterval = other._interTrialInterval; - _responseTime = other._responseTime; - _autoBlock = other._autoBlock; _rewardSize = other._rewardSize; - _warmup = other._warmup; - _noResponseTrialAddition = other._noResponseTrialAddition; - _rewardN = other._rewardN; - _lickSpoutRetraction = other._lickSpoutRetraction; _trialGenerator = other._trialGenerator; } @@ -683,172 +633,6 @@ public string AindBehaviorServicesPkgVersion } } - /// - /// Parameters describing block conditions. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("block_parameters")] - [System.ComponentModel.DescriptionAttribute("Parameters describing block conditions.")] - public BlockParameters BlockParameters - { - get - { - return _blockParameters; - } - set - { - _blockParameters = value; - } - } - - /// - /// Parameters describing reward_probability. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("reward_probability")] - [System.ComponentModel.DescriptionAttribute("Parameters describing reward_probability.")] - public RewardProbability RewardProbability - { - get - { - return _rewardProbability; - } - set - { - _rewardProbability = value; - } - } - - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("uncoupled_reward")] - public System.Collections.Generic.List UncoupledReward - { - get - { - return _uncoupledReward; - } - set - { - _uncoupledReward = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("randomness")] - public AindDynamicForagingTaskParametersRandomness Randomness - { - get - { - return _randomness; - } - set - { - _randomness = value; - } - } - - /// - /// Parameters describing delay period. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("delay_period")] - [System.ComponentModel.DescriptionAttribute("Parameters describing delay period.")] - public DelayPeriod DelayPeriod - { - get - { - return _delayPeriod; - } - set - { - _delayPeriod = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("reward_delay")] - public double RewardDelay - { - get - { - return _rewardDelay; - } - set - { - _rewardDelay = value; - } - } - - /// - /// Parameters describing auto water. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("auto_water")] - [System.ComponentModel.DescriptionAttribute("Parameters describing auto water.")] - public AindBehaviorDynamicForagingTaskLogicAutoWater AutoWater - { - get - { - return _autoWater; - } - set - { - _autoWater = value; - } - } - - /// - /// Parameters describing iti. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("inter_trial_interval")] - [System.ComponentModel.DescriptionAttribute("Parameters describing iti.")] - public InterTrialInterval InterTrialInterval - { - get - { - return _interTrialInterval; - } - set - { - _interTrialInterval = value; - } - } - - /// - /// Parameters describing response time. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("response_time")] - [System.ComponentModel.DescriptionAttribute("Parameters describing response time.")] - public Response ResponseTime - { - get - { - return _responseTime; - } - set - { - _responseTime = value; - } - } - - /// - /// Parameters describing auto advancement to next block. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("auto_block")] - [System.ComponentModel.DescriptionAttribute("Parameters describing auto advancement to next block.")] - public AutoBlock AutoBlock - { - get - { - return _autoBlock; - } - set - { - _autoBlock = value; - } - } - /// /// Parameters describing reward size. /// @@ -867,72 +651,6 @@ public RewardSize RewardSize } } - /// - /// Parameters describing warmup. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("warmup")] - [System.ComponentModel.DescriptionAttribute("Parameters describing warmup.")] - public Warmup Warmup - { - get - { - return _warmup; - } - set - { - _warmup = value; - } - } - - /// - /// Add one trial to the block length on both lickspouts. - /// - [Newtonsoft.Json.JsonPropertyAttribute("no_response_trial_addition")] - [System.ComponentModel.DescriptionAttribute("Add one trial to the block length on both lickspouts.")] - public bool NoResponseTrialAddition - { - get - { - return _noResponseTrialAddition; - } - set - { - _noResponseTrialAddition = value; - } - } - - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("reward_n")] - public RewardN RewardN - { - get - { - return _rewardN; - } - set - { - _rewardN = value; - } - } - - /// - /// Lick spout retraction enabled. - /// - [Newtonsoft.Json.JsonPropertyAttribute("lick_spout_retraction")] - [System.ComponentModel.DescriptionAttribute("Lick spout retraction enabled.")] - public bool? LickSpoutRetraction - { - get - { - return _lickSpoutRetraction; - } - set - { - _lickSpoutRetraction = value; - } - } - /// /// Trial generator model for generating trials in the task. /// @@ -965,21 +683,7 @@ protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { stringBuilder.Append("RngSeed = " + _rngSeed + ", "); stringBuilder.Append("AindBehaviorServicesPkgVersion = " + _aindBehaviorServicesPkgVersion + ", "); - stringBuilder.Append("BlockParameters = " + _blockParameters + ", "); - stringBuilder.Append("RewardProbability = " + _rewardProbability + ", "); - stringBuilder.Append("UncoupledReward = " + _uncoupledReward + ", "); - stringBuilder.Append("Randomness = " + _randomness + ", "); - stringBuilder.Append("DelayPeriod = " + _delayPeriod + ", "); - stringBuilder.Append("RewardDelay = " + _rewardDelay + ", "); - stringBuilder.Append("AutoWater = " + _autoWater + ", "); - stringBuilder.Append("InterTrialInterval = " + _interTrialInterval + ", "); - stringBuilder.Append("ResponseTime = " + _responseTime + ", "); - stringBuilder.Append("AutoBlock = " + _autoBlock + ", "); stringBuilder.Append("RewardSize = " + _rewardSize + ", "); - stringBuilder.Append("Warmup = " + _warmup + ", "); - stringBuilder.Append("NoResponseTrialAddition = " + _noResponseTrialAddition + ", "); - stringBuilder.Append("RewardN = " + _rewardN + ", "); - stringBuilder.Append("LickSpoutRetraction = " + _lickSpoutRetraction + ", "); stringBuilder.Append("TrialGenerator = " + _trialGenerator); return true; } @@ -1356,104 +1060,6 @@ public override string ToString() } - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] - [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class AutoBlock - { - - private AutoBlockAdvancedBlockAuto _advancedBlockAuto; - - private double _switchThr; - - private int _pointsInARow; - - public AutoBlock() - { - _advancedBlockAuto = AutoBlockAdvancedBlockAuto.Now; - _switchThr = 0.5D; - _pointsInARow = 5; - } - - protected AutoBlock(AutoBlock other) - { - _advancedBlockAuto = other._advancedBlockAuto; - _switchThr = other._switchThr; - _pointsInARow = other._pointsInARow; - } - - [Newtonsoft.Json.JsonPropertyAttribute("advanced_block_auto")] - public AutoBlockAdvancedBlockAuto AdvancedBlockAuto - { - get - { - return _advancedBlockAuto; - } - set - { - _advancedBlockAuto = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("switch_thr")] - public double SwitchThr - { - get - { - return _switchThr; - } - set - { - _switchThr = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("points_in_a_row")] - public int PointsInARow - { - get - { - return _pointsInARow; - } - set - { - _pointsInARow = value; - } - } - - public System.IObservable Generate() - { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new AutoBlock(this))); - } - - public System.IObservable Generate(System.IObservable source) - { - return System.Reactive.Linq.Observable.Select(source, _ => new AutoBlock(this)); - } - - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) - { - stringBuilder.Append("AdvancedBlockAuto = " + _advancedBlockAuto + ", "); - stringBuilder.Append("SwitchThr = " + _switchThr + ", "); - stringBuilder.Append("PointsInARow = " + _pointsInARow); - return true; - } - - public override string ToString() - { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) - { - stringBuilder.Append(" "); - } - stringBuilder.Append("}"); - return stringBuilder.ToString(); - } - } - - /// /// Motor axis available /// @@ -1721,104 +1327,105 @@ public override string ToString() } + /// + /// Parameters controlling when behavior is considered stable enough to switch blocks. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters controlling when behavior is considered stable enough to switch blocks" + + ".")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class BlockParameters + public partial class BehaviorStabilityParameters { - private int _min; + private BehaviorStabilityParametersBehaviorEvaluationMode _behaviorEvaluationMode; - private int _max; + private double _behaviorStabilityFraction; - private int _beta; + private int _minConsecutiveStableTrials; - private int _minReward; - - public BlockParameters() + public BehaviorStabilityParameters() { - _min = 20; - _max = 60; - _beta = 20; - _minReward = 1; + _behaviorEvaluationMode = BehaviorStabilityParametersBehaviorEvaluationMode.End; + _behaviorStabilityFraction = 0.5D; + _minConsecutiveStableTrials = 5; } - protected BlockParameters(BlockParameters other) + protected BehaviorStabilityParameters(BehaviorStabilityParameters other) { - _min = other._min; - _max = other._max; - _beta = other._beta; - _minReward = other._minReward; + _behaviorEvaluationMode = other._behaviorEvaluationMode; + _behaviorStabilityFraction = other._behaviorStabilityFraction; + _minConsecutiveStableTrials = other._minConsecutiveStableTrials; } - [Newtonsoft.Json.JsonPropertyAttribute("min")] - public int Min + /// + /// When to evaluate stability — at the end of the block (end) or at any point during the block (anytime). + /// + [Newtonsoft.Json.JsonPropertyAttribute("behavior_evaluation_mode")] + [System.ComponentModel.DescriptionAttribute("When to evaluate stability — at the end of the block (end) or at any point during" + + " the block (anytime).")] + public BehaviorStabilityParametersBehaviorEvaluationMode BehaviorEvaluationMode { get { - return _min; + return _behaviorEvaluationMode; } set { - _min = value; + _behaviorEvaluationMode = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("max")] - public int Max + /// + /// Fraction scaling reward-probability difference for behavior. + /// + [Newtonsoft.Json.JsonPropertyAttribute("behavior_stability_fraction")] + [System.ComponentModel.DescriptionAttribute("Fraction scaling reward-probability difference for behavior.")] + public double BehaviorStabilityFraction { get { - return _max; - } - set - { - _max = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("beta")] - public int Beta - { - get - { - return _beta; + return _behaviorStabilityFraction; } set { - _beta = value; + _behaviorStabilityFraction = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("min_reward")] - public int MinReward + /// + /// Minimum number of consecutive trials satisfying the behavioral stability fraction. + /// + [Newtonsoft.Json.JsonPropertyAttribute("min_consecutive_stable_trials")] + [System.ComponentModel.DescriptionAttribute("Minimum number of consecutive trials satisfying the behavioral stability fraction" + + ".")] + public int MinConsecutiveStableTrials { get { - return _minReward; + return _minConsecutiveStableTrials; } set { - _minReward = value; + _minConsecutiveStableTrials = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BlockParameters(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BehaviorStabilityParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new BlockParameters(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new BehaviorStabilityParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("Min = " + _min + ", "); - stringBuilder.Append("Max = " + _max + ", "); - stringBuilder.Append("Beta = " + _beta + ", "); - stringBuilder.Append("MinReward = " + _minReward); + stringBuilder.Append("BehaviorEvaluationMode = " + _behaviorEvaluationMode + ", "); + stringBuilder.Append("BehaviorStabilityFraction = " + _behaviorStabilityFraction + ", "); + stringBuilder.Append("MinConsecutiveStableTrials = " + _minConsecutiveStableTrials); return true; } @@ -1837,246 +1444,211 @@ public override string ToString() } + /// + /// A beta probability distribution. + /// + ///Continuous distribution bounded between 0 and 1. Commonly used + ///for modeling probabilities and proportions. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A beta probability distribution.\n\nContinuous distribution bounded between 0 and 1" + + ". Commonly used\nfor modeling probabilities and proportions.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class CameraControllerSpinnakerCamera + public partial class BetaDistribution : Distribution { - private string _deviceType; - - private BaseModel _calibration; - - private System.Collections.Generic.Dictionary _cameras; + private BetaDistributionParameters _distributionParameters; - private int? _frameRate; + private TruncationParameters _truncationParameters; - public CameraControllerSpinnakerCamera() - { - _deviceType = "CameraController"; - _cameras = new System.Collections.Generic.Dictionary(); - _frameRate = 30; - } + private ScalingParameters _scalingParameters; - protected CameraControllerSpinnakerCamera(CameraControllerSpinnakerCamera other) + public BetaDistribution() { - _deviceType = other._deviceType; - _calibration = other._calibration; - _cameras = other._cameras; - _frameRate = other._frameRate; + _distributionParameters = new BetaDistributionParameters(); } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + protected BetaDistribution(BetaDistribution other) : + base(other) { - get - { - return _deviceType; - } - set - { - _deviceType = value; - } + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } /// - /// Calibration for the device. + /// Parameters of the distribution /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public BetaDistributionParameters DistributionParameters { get { - return _calibration; + return _distributionParameters; } set { - _calibration = value; + _distributionParameters = value; } } /// - /// Cameras to be instantiated + /// Truncation parameters of the distribution /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("cameras", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Cameras to be instantiated")] - public System.Collections.Generic.Dictionary Cameras + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters { get { - return _cameras; + return _truncationParameters; } set { - _cameras = value; + _truncationParameters = value; } } /// - /// Frame rate of the trigger to all cameras + /// Scaling parameters of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("frame_rate")] - [System.ComponentModel.DescriptionAttribute("Frame rate of the trigger to all cameras")] - public int? FrameRate + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { get { - return _frameRate; + return _scalingParameters; } set { - _frameRate = value; + _scalingParameters = value; } } - public System.IObservable Generate() - { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CameraControllerSpinnakerCamera(this))); - } - - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Select(source, _ => new CameraControllerSpinnakerCamera(this)); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BetaDistribution(this))); } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + public System.IObservable Generate(System.IObservable source) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("Cameras = " + _cameras + ", "); - stringBuilder.Append("FrameRate = " + _frameRate); - return true; + return System.Reactive.Linq.Observable.Select(source, _ => new BetaDistribution(this)); } - public override string ToString() + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) + if (base.PrintMembers(stringBuilder)) { - stringBuilder.Append(" "); + stringBuilder.Append(", "); } - stringBuilder.Append("}"); - return stringBuilder.ToString(); + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; } } + /// + /// Parameters for a beta distribution. + /// + ///Defined by alpha and beta shape parameters. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a beta distribution.\n\nDefined by alpha and beta shape parameters.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class CameraControllerWebCamera + public partial class BetaDistributionParameters { - private string _deviceType; - - private BaseModel _calibration; - - private System.Collections.Generic.Dictionary _cameras; + private string _family; - private int? _frameRate; + private double _alpha; - public CameraControllerWebCamera() - { - _deviceType = "CameraController"; - _cameras = new System.Collections.Generic.Dictionary(); - _frameRate = 30; - } + private double _beta; - protected CameraControllerWebCamera(CameraControllerWebCamera other) + public BetaDistributionParameters() { - _deviceType = other._deviceType; - _calibration = other._calibration; - _cameras = other._cameras; - _frameRate = other._frameRate; + _family = "Beta"; + _alpha = 5D; + _beta = 5D; } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + protected BetaDistributionParameters(BetaDistributionParameters other) { - get - { - return _deviceType; - } - set - { - _deviceType = value; - } + _family = other._family; + _alpha = other._alpha; + _beta = other._beta; } - /// - /// Calibration for the device. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _calibration; + return _family; } set { - _calibration = value; + _family = value; } } /// - /// Cameras to be instantiated + /// Alpha parameter of the distribution /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("cameras", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Cameras to be instantiated")] - public System.Collections.Generic.Dictionary Cameras + [Newtonsoft.Json.JsonPropertyAttribute("alpha")] + [System.ComponentModel.DescriptionAttribute("Alpha parameter of the distribution")] + public double Alpha { get { - return _cameras; + return _alpha; } set { - _cameras = value; + _alpha = value; } } /// - /// Frame rate of the trigger to all cameras + /// Beta parameter of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("frame_rate")] - [System.ComponentModel.DescriptionAttribute("Frame rate of the trigger to all cameras")] - public int? FrameRate + [Newtonsoft.Json.JsonPropertyAttribute("beta")] + [System.ComponentModel.DescriptionAttribute("Beta parameter of the distribution")] + public double Beta { get { - return _frameRate; + return _beta; } set { - _frameRate = value; + _beta = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CameraControllerWebCamera(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BetaDistributionParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new CameraControllerWebCamera(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new BetaDistributionParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("Cameras = " + _cameras + ", "); - stringBuilder.Append("FrameRate = " + _frameRate); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Alpha = " + _alpha + ", "); + stringBuilder.Append("Beta = " + _beta); return true; } @@ -2095,414 +1667,355 @@ public override string ToString() } + /// + /// A binomial probability distribution. + /// + ///Models the number of successes in a fixed number of independent + ///Bernoulli trials with constant success probability. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A binomial probability distribution.\n\nModels the number of successes in a fixed n" + + "umber of independent\nBernoulli trials with constant success probability.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class ConnectedClockOutput + public partial class BinomialDistribution : Distribution { - private string _targetDevice; + private BinomialDistributionParameters _distributionParameters; - private int _outputChannel; + private TruncationParameters _truncationParameters; - public ConnectedClockOutput() + private ScalingParameters _scalingParameters; + + public BinomialDistribution() { + _distributionParameters = new BinomialDistributionParameters(); } - protected ConnectedClockOutput(ConnectedClockOutput other) + protected BinomialDistribution(BinomialDistribution other) : + base(other) { - _targetDevice = other._targetDevice; - _outputChannel = other._outputChannel; + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } /// - /// Optional device name to provide user additional information + /// Parameters of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("target_device")] - [System.ComponentModel.DescriptionAttribute("Optional device name to provide user additional information")] - public string TargetDevice + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public BinomialDistributionParameters DistributionParameters { get { - return _targetDevice; + return _distributionParameters; } set { - _targetDevice = value; + _distributionParameters = value; } } /// - /// Output channel + /// Truncation parameters of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("output_channel", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Output channel")] - public int OutputChannel + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters { get { - return _outputChannel; + return _truncationParameters; } set { - _outputChannel = value; + _truncationParameters = value; } } - public System.IObservable Generate() + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ConnectedClockOutput(this))); + get + { + return _scalingParameters; + } + set + { + _scalingParameters = value; + } } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Select(source, _ => new ConnectedClockOutput(this)); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BinomialDistribution(this))); } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + public System.IObservable Generate(System.IObservable source) { - stringBuilder.Append("TargetDevice = " + _targetDevice + ", "); - stringBuilder.Append("OutputChannel = " + _outputChannel); - return true; + return System.Reactive.Linq.Observable.Select(source, _ => new BinomialDistribution(this)); } - public override string ToString() + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) + if (base.PrintMembers(stringBuilder)) { - stringBuilder.Append(" "); + stringBuilder.Append(", "); } - stringBuilder.Append("}"); - return stringBuilder.ToString(); + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; } } + /// + /// Parameters for a binomial distribution. + /// + ///Defined by number of trials (n) and success probability (p). + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a binomial distribution.\n\nDefined by number of trials (n) and succ" + + "ess probability (p).")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class CoupledTrialGeneratorSpec : TrialGeneratorSpec + public partial class BinomialDistributionParameters { - private object _iti; - - private object _quiescentPeriod; - - private double _responseTime; - - private double _rewardConsumeTime; - - private object _blockParameters; - - private int _minReward; - - private AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater _autoWater; - - private CoupledTrialGeneratorSpecBehaviorEvaluationMode _behaviorEvaluationMode; - - private double _switchThr; - - private int _pointsInARow; - - private Warmup _warmup; - - private bool _noResponseTrialAddition; - - private int _kernelSize; + private string _family; - private RewardProbability _rewardProbabilitySpecs; + private int _n; - private System.Collections.Generic.List _rewardFamily; + private double _p; - public CoupledTrialGeneratorSpec() + public BinomialDistributionParameters() { - _iti = new object(); - _quiescentPeriod = new object(); - _responseTime = 1D; - _rewardConsumeTime = 3D; - _blockParameters = new object(); - _minReward = 1; - _behaviorEvaluationMode = CoupledTrialGeneratorSpecBehaviorEvaluationMode.Ignore; - _switchThr = 0.5D; - _pointsInARow = 5; - _noResponseTrialAddition = true; - _rewardProbabilitySpecs = new RewardProbability(); - _rewardFamily = new System.Collections.Generic.List(); + _family = "Binomial"; + _n = 1; + _p = 0.5D; } - protected CoupledTrialGeneratorSpec(CoupledTrialGeneratorSpec other) : - base(other) + protected BinomialDistributionParameters(BinomialDistributionParameters other) { - _iti = other._iti; - _quiescentPeriod = other._quiescentPeriod; - _responseTime = other._responseTime; - _rewardConsumeTime = other._rewardConsumeTime; - _blockParameters = other._blockParameters; - _minReward = other._minReward; - _autoWater = other._autoWater; - _behaviorEvaluationMode = other._behaviorEvaluationMode; - _switchThr = other._switchThr; - _pointsInARow = other._pointsInARow; - _warmup = other._warmup; - _noResponseTrialAddition = other._noResponseTrialAddition; - _kernelSize = other._kernelSize; - _rewardProbabilitySpecs = other._rewardProbabilitySpecs; - _rewardFamily = other._rewardFamily; + _family = other._family; + _n = other._n; + _p = other._p; } - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("iti")] - public object Iti + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _iti; + return _family; } set { - _iti = value; + _family = value; } } - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("quiescent_period")] - public object QuiescentPeriod + /// + /// Number of trials + /// + [Newtonsoft.Json.JsonPropertyAttribute("n")] + [System.ComponentModel.DescriptionAttribute("Number of trials")] + public int N { get { - return _quiescentPeriod; + return _n; } set { - _quiescentPeriod = value; + _n = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("response_time")] - public double ResponseTime + /// + /// Probability of success + /// + [Newtonsoft.Json.JsonPropertyAttribute("p")] + [System.ComponentModel.DescriptionAttribute("Probability of success")] + public double P { get { - return _responseTime; + return _p; } set { - _responseTime = value; + _p = value; } } - /// - /// Time of the no-lick period before trial end - /// - [Newtonsoft.Json.JsonPropertyAttribute("reward_consume_time")] - [System.ComponentModel.DescriptionAttribute("Time of the no-lick period before trial end")] - public double RewardConsumeTime + public System.IObservable Generate() { - get - { - return _rewardConsumeTime; - } - set - { - _rewardConsumeTime = value; - } + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BinomialDistributionParameters(this))); } - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("block_parameters")] - public object BlockParameters + public System.IObservable Generate(System.IObservable source) { - get - { - return _blockParameters; - } - set - { - _blockParameters = value; - } + return System.Reactive.Linq.Observable.Select(source, _ => new BinomialDistributionParameters(this)); } - [Newtonsoft.Json.JsonPropertyAttribute("min_reward")] - public int MinReward + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - get - { - return _minReward; - } - set - { - _minReward = value; - } + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("N = " + _n + ", "); + stringBuilder.Append("P = " + _p); + return true; } - /// - /// Parameters describing auto water. - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("auto_water")] - [System.ComponentModel.DescriptionAttribute("Parameters describing auto water.")] - public AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater AutoWater + public override string ToString() { - get - { - return _autoWater; - } - set + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) { - _autoWater = value; + stringBuilder.Append(" "); } + stringBuilder.Append("}"); + return stringBuilder.ToString(); } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class CameraControllerSpinnakerCamera + { - [Newtonsoft.Json.JsonPropertyAttribute("behavior_evaluation_mode")] - public CoupledTrialGeneratorSpecBehaviorEvaluationMode BehaviorEvaluationMode + private string _deviceType; + + private BaseModel _calibration; + + private System.Collections.Generic.Dictionary _cameras; + + private int? _frameRate; + + public CameraControllerSpinnakerCamera() { - get - { - return _behaviorEvaluationMode; - } - set - { - _behaviorEvaluationMode = value; - } + _deviceType = "CameraController"; + _cameras = new System.Collections.Generic.Dictionary(); + _frameRate = 30; } - [Newtonsoft.Json.JsonPropertyAttribute("switch_thr")] - public double SwitchThr + protected CameraControllerSpinnakerCamera(CameraControllerSpinnakerCamera other) { - get - { - return _switchThr; - } - set - { - _switchThr = value; - } + _deviceType = other._deviceType; + _calibration = other._calibration; + _cameras = other._cameras; + _frameRate = other._frameRate; } - [Newtonsoft.Json.JsonPropertyAttribute("points_in_a_row")] - public int PointsInARow + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType { get { - return _pointsInARow; + return _deviceType; } set { - _pointsInARow = value; + _deviceType = value; } } /// - /// Parameters describing warmup. + /// Calibration for the device. /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("warmup")] - [System.ComponentModel.DescriptionAttribute("Parameters describing warmup.")] - public Warmup Warmup + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration { get { - return _warmup; + return _calibration; } set { - _warmup = value; + _calibration = value; } } /// - /// Add one trial to the block length on both lickspouts. + /// Cameras to be instantiated /// - [Newtonsoft.Json.JsonPropertyAttribute("no_response_trial_addition")] - [System.ComponentModel.DescriptionAttribute("Add one trial to the block length on both lickspouts.")] - public bool NoResponseTrialAddition - { - get - { - return _noResponseTrialAddition; - } - set - { - _noResponseTrialAddition = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("kernel_size", Required=Newtonsoft.Json.Required.Always)] - public int KernelSize + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("cameras", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Cameras to be instantiated")] + public System.Collections.Generic.Dictionary Cameras { get { - return _kernelSize; + return _cameras; } set { - _kernelSize = value; + _cameras = value; } } - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("reward_probability_specs")] - public RewardProbability RewardProbabilitySpecs + /// + /// Frame rate of the trigger to all cameras + /// + [Newtonsoft.Json.JsonPropertyAttribute("frame_rate")] + [System.ComponentModel.DescriptionAttribute("Frame rate of the trigger to all cameras")] + public int? FrameRate { get { - return _rewardProbabilitySpecs; + return _frameRate; } set { - _rewardProbabilitySpecs = value; + _frameRate = value; } } - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("reward_family")] - public System.Collections.Generic.List RewardFamily + public System.IObservable Generate() { - get - { - return _rewardFamily; - } - set - { - _rewardFamily = value; - } + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CameraControllerSpinnakerCamera(this))); } - public System.IObservable Generate() + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CoupledTrialGeneratorSpec(this))); + return System.Reactive.Linq.Observable.Select(source, _ => new CameraControllerSpinnakerCamera(this)); } - public System.IObservable Generate(System.IObservable source) + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - return System.Reactive.Linq.Observable.Select(source, _ => new CoupledTrialGeneratorSpec(this)); + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("Cameras = " + _cameras + ", "); + stringBuilder.Append("FrameRate = " + _frameRate); + return true; } - protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + public override string ToString() { - if (base.PrintMembers(stringBuilder)) + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) { - stringBuilder.Append(", "); + stringBuilder.Append(" "); } - stringBuilder.Append("Iti = " + _iti + ", "); - stringBuilder.Append("QuiescentPeriod = " + _quiescentPeriod + ", "); - stringBuilder.Append("ResponseTime = " + _responseTime + ", "); - stringBuilder.Append("RewardConsumeTime = " + _rewardConsumeTime + ", "); - stringBuilder.Append("BlockParameters = " + _blockParameters + ", "); - stringBuilder.Append("MinReward = " + _minReward + ", "); - stringBuilder.Append("AutoWater = " + _autoWater + ", "); - stringBuilder.Append("BehaviorEvaluationMode = " + _behaviorEvaluationMode + ", "); - stringBuilder.Append("SwitchThr = " + _switchThr + ", "); - stringBuilder.Append("PointsInARow = " + _pointsInARow + ", "); - stringBuilder.Append("Warmup = " + _warmup + ", "); - stringBuilder.Append("NoResponseTrialAddition = " + _noResponseTrialAddition + ", "); - stringBuilder.Append("KernelSize = " + _kernelSize + ", "); - stringBuilder.Append("RewardProbabilitySpecs = " + _rewardProbabilitySpecs + ", "); - stringBuilder.Append("RewardFamily = " + _rewardFamily); - return true; + stringBuilder.Append("}"); + return stringBuilder.ToString(); } } @@ -2510,83 +2023,114 @@ protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class DelayPeriod + public partial class CameraControllerWebCamera { - private double _min; + private string _deviceType; - private double _max; + private BaseModel _calibration; - private double _beta; + private System.Collections.Generic.Dictionary _cameras; + + private int? _frameRate; - public DelayPeriod() + public CameraControllerWebCamera() { - _min = 0D; - _max = 1D; - _beta = 1D; + _deviceType = "CameraController"; + _cameras = new System.Collections.Generic.Dictionary(); + _frameRate = 30; } - protected DelayPeriod(DelayPeriod other) + protected CameraControllerWebCamera(CameraControllerWebCamera other) { - _min = other._min; - _max = other._max; - _beta = other._beta; + _deviceType = other._deviceType; + _calibration = other._calibration; + _cameras = other._cameras; + _frameRate = other._frameRate; } - [Newtonsoft.Json.JsonPropertyAttribute("min")] - public double Min + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType { get { - return _min; + return _deviceType; } set { - _min = value; + _deviceType = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("max")] - public double Max + /// + /// Calibration for the device. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration { get { - return _max; + return _calibration; } set { - _max = value; + _calibration = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("beta")] - public double Beta + /// + /// Cameras to be instantiated + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("cameras", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Cameras to be instantiated")] + public System.Collections.Generic.Dictionary Cameras { get { - return _beta; + return _cameras; } set { - _beta = value; + _cameras = value; + } + } + + /// + /// Frame rate of the trigger to all cameras + /// + [Newtonsoft.Json.JsonPropertyAttribute("frame_rate")] + [System.ComponentModel.DescriptionAttribute("Frame rate of the trigger to all cameras")] + public int? FrameRate + { + get + { + return _frameRate; + } + set + { + _frameRate = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new DelayPeriod(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CameraControllerWebCamera(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new DelayPeriod(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new CameraControllerWebCamera(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("Min = " + _min + ", "); - stringBuilder.Append("Max = " + _max + ", "); - stringBuilder.Append("Beta = " + _beta); + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("Cameras = " + _cameras + ", "); + stringBuilder.Append("FrameRate = " + _frameRate); return true; } @@ -2605,138 +2149,74 @@ public override string ToString() } - /// - /// A calibrated sound card for the dynamic foraging rig. This is a subclass of the HarpSoundCard that includes the sound card calibration. - /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("A calibrated sound card for the dynamic foraging rig. This is a subclass of the H" + - "arpSoundCard that includes the sound card calibration.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class DynamicForagingSoundCard + public partial class ConnectedClockOutput { - private string _deviceType; - - private SoundCardCalibration _calibration; - - private int _whoAmI; - - private string _serialNumber; - - private string _portName; - - public DynamicForagingSoundCard() - { - _deviceType = "SoundCard"; - _calibration = new SoundCardCalibration(); - _whoAmI = 1280; - } - - protected DynamicForagingSoundCard(DynamicForagingSoundCard other) - { - _deviceType = other._deviceType; - _calibration = other._calibration; - _whoAmI = other._whoAmI; - _serialNumber = other._serialNumber; - _portName = other._portName; - } + private string _targetDevice; - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType - { - get - { - return _deviceType; - } - set - { - _deviceType = value; - } - } + private int _outputChannel; - /// - /// Sound card calibration - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Sound card calibration")] - public SoundCardCalibration Calibration + public ConnectedClockOutput() { - get - { - return _calibration; - } - set - { - _calibration = value; - } } - [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] - public int WhoAmI + protected ConnectedClockOutput(ConnectedClockOutput other) { - get - { - return _whoAmI; - } - set - { - _whoAmI = value; - } + _targetDevice = other._targetDevice; + _outputChannel = other._outputChannel; } /// - /// Device serial number + /// Optional device name to provide user additional information /// - [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] - [System.ComponentModel.DescriptionAttribute("Device serial number")] - public string SerialNumber + [Newtonsoft.Json.JsonPropertyAttribute("target_device")] + [System.ComponentModel.DescriptionAttribute("Optional device name to provide user additional information")] + public string TargetDevice { get { - return _serialNumber; + return _targetDevice; } set { - _serialNumber = value; + _targetDevice = value; } } /// - /// Device port name + /// Output channel /// - [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Device port name")] - public string PortName + [Newtonsoft.Json.JsonPropertyAttribute("output_channel", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Output channel")] + public int OutputChannel { get { - return _portName; + return _outputChannel; } set { - _portName = value; + _outputChannel = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new DynamicForagingSoundCard(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ConnectedClockOutput(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new DynamicForagingSoundCard(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new ConnectedClockOutput(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); - stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); - stringBuilder.Append("PortName = " + _portName); + stringBuilder.Append("TargetDevice = " + _targetDevice + ", "); + stringBuilder.Append("OutputChannel = " + _outputChannel); return true; } @@ -2756,124 +2236,146 @@ public override string ToString() /// - /// An exponential probability distribution. - /// - ///Models time between events in a Poisson process. Commonly used - ///for wait times and inter-event intervals. + /// Defines the conditions under which a foraging session should terminate. /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("An exponential probability distribution.\n\nModels time between events in a Poisson" + - " process. Commonly used\nfor wait times and inter-event intervals.")] + [System.ComponentModel.DescriptionAttribute("Defines the conditions under which a foraging session should terminate.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class ExponentialDistribution + public partial class CoupledTrialGenerationEndConditions { - private string _family; + private int _ignoreWin; - private ExponentialDistributionParameters _distributionParameters; + private double _ignoreRatioThreshold; - private TruncationParameters _truncationParameters; + private int _maxTrial; - private ScalingParameters _scalingParameters; + private double _maxTime; - public ExponentialDistribution() + private double _minTime; + + public CoupledTrialGenerationEndConditions() { - _family = "Exponential"; - _distributionParameters = new ExponentialDistributionParameters(); + _ignoreWin = 30; + _ignoreRatioThreshold = 0.8D; + _maxTrial = 1000; + _maxTime = 4500D; + _minTime = 1800D; } - protected ExponentialDistribution(ExponentialDistribution other) + protected CoupledTrialGenerationEndConditions(CoupledTrialGenerationEndConditions other) { - _family = other._family; - _distributionParameters = other._distributionParameters; - _truncationParameters = other._truncationParameters; - _scalingParameters = other._scalingParameters; + _ignoreWin = other._ignoreWin; + _ignoreRatioThreshold = other._ignoreRatioThreshold; + _maxTrial = other._maxTrial; + _maxTime = other._maxTime; + _minTime = other._minTime; } - [Newtonsoft.Json.JsonPropertyAttribute("family")] - public string Family + /// + /// Number of recent trials to check for ignored responses. + /// + [Newtonsoft.Json.JsonPropertyAttribute("ignore_win")] + [System.ComponentModel.DescriptionAttribute("Number of recent trials to check for ignored responses.")] + public int IgnoreWin { get { - return _family; + return _ignoreWin; } set { - _family = value; + _ignoreWin = value; } } /// - /// Parameters of the distribution + /// Maximum fraction of ignored trials within the window before the session is ended. /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] - [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] - public ExponentialDistributionParameters DistributionParameters + [Newtonsoft.Json.JsonPropertyAttribute("ignore_ratio_threshold")] + [System.ComponentModel.DescriptionAttribute("Maximum fraction of ignored trials within the window before the session is ended." + + "")] + public double IgnoreRatioThreshold { get { - return _distributionParameters; + return _ignoreRatioThreshold; } set { - _distributionParameters = value; + _ignoreRatioThreshold = value; } } /// - /// Truncation parameters of the distribution + /// Maximum number of trials allowed in a session. /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] - [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] - public TruncationParameters TruncationParameters + [Newtonsoft.Json.JsonPropertyAttribute("max_trial")] + [System.ComponentModel.DescriptionAttribute("Maximum number of trials allowed in a session.")] + public int MaxTrial { get { - return _truncationParameters; + return _maxTrial; } set { - _truncationParameters = value; + _maxTrial = value; } } /// - /// Scaling parameters of the distribution + /// Maximum session duration (sec). /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] - [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] - public ScalingParameters ScalingParameters + [Newtonsoft.Json.JsonPropertyAttribute("max_time")] + [System.ComponentModel.DescriptionAttribute("Maximum session duration (sec).")] + public double MaxTime { get { - return _scalingParameters; + return _maxTime; } set { - _scalingParameters = value; + _maxTime = value; } } - public System.IObservable Generate() + /// + /// Minimum session duration (sec) + /// + [Newtonsoft.Json.JsonPropertyAttribute("min_time")] + [System.ComponentModel.DescriptionAttribute("Minimum session duration (sec)")] + public double MinTime { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ExponentialDistribution(this))); + get + { + return _minTime; + } + set + { + _minTime = value; + } } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Select(source, _ => new ExponentialDistribution(this)); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CoupledTrialGenerationEndConditions(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new CoupledTrialGenerationEndConditions(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("Family = " + _family + ", "); - stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); - stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); - stringBuilder.Append("ScalingParameters = " + _scalingParameters); + stringBuilder.Append("IgnoreWin = " + _ignoreWin + ", "); + stringBuilder.Append("IgnoreRatioThreshold = " + _ignoreRatioThreshold + ", "); + stringBuilder.Append("MaxTrial = " + _maxTrial + ", "); + stringBuilder.Append("MaxTime = " + _maxTime + ", "); + stringBuilder.Append("MinTime = " + _minTime); return true; } @@ -2892,225 +2394,350 @@ public override string ToString() } - /// - /// Parameters for an exponential distribution. - /// - ///Defined by the rate parameter (inverse of mean). - /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("Parameters for an exponential distribution.\n\nDefined by the rate parameter (inver" + - "se of mean).")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class ExponentialDistributionParameters + public partial class CoupledTrialGeneratorSpec : TrialGeneratorSpec { - private string _family; + private Distribution _quiescentDuration; - private double _rate; + private double _responseDuration; - public ExponentialDistributionParameters() + private double _rewardConsumptionDuration; + + private Distribution _interTrialIntervalDuration; + + private Distribution _blockLen; + + private int _minBlockReward; + + private int _kernelSize; + + private RewardProbabilityParameters _rewardProbabilityParameters; + + private bool _isBaiting; + + private CoupledTrialGenerationEndConditions _trialGenerationEndParameters; + + private BehaviorStabilityParameters _behaviorStabilityParameters; + + private bool _extendBlockOnNoResponse; + + public CoupledTrialGeneratorSpec() { - _family = "Exponential"; - _rate = 0D; + _quiescentDuration = new Distribution(); + _responseDuration = 1D; + _rewardConsumptionDuration = 3D; + _interTrialIntervalDuration = new Distribution(); + _blockLen = new Distribution(); + _minBlockReward = 1; + _kernelSize = 2; + _rewardProbabilityParameters = new RewardProbabilityParameters(); + _isBaiting = false; + _trialGenerationEndParameters = new CoupledTrialGenerationEndConditions(); + _behaviorStabilityParameters = new BehaviorStabilityParameters(); + _extendBlockOnNoResponse = true; } - protected ExponentialDistributionParameters(ExponentialDistributionParameters other) + protected CoupledTrialGeneratorSpec(CoupledTrialGeneratorSpec other) : + base(other) { - _family = other._family; - _rate = other._rate; + _quiescentDuration = other._quiescentDuration; + _responseDuration = other._responseDuration; + _rewardConsumptionDuration = other._rewardConsumptionDuration; + _interTrialIntervalDuration = other._interTrialIntervalDuration; + _blockLen = other._blockLen; + _minBlockReward = other._minBlockReward; + _kernelSize = other._kernelSize; + _rewardProbabilityParameters = other._rewardProbabilityParameters; + _isBaiting = other._isBaiting; + _trialGenerationEndParameters = other._trialGenerationEndParameters; + _behaviorStabilityParameters = other._behaviorStabilityParameters; + _extendBlockOnNoResponse = other._extendBlockOnNoResponse; } - [Newtonsoft.Json.JsonPropertyAttribute("family")] - public string Family + /// + /// Distribution describing the quiescence period before trial starts (in seconds). Each lick resets the timer. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("quiescent_duration")] + [System.ComponentModel.DescriptionAttribute("Distribution describing the quiescence period before trial starts (in seconds). E" + + "ach lick resets the timer.")] + public Distribution QuiescentDuration { get { - return _family; + return _quiescentDuration; } set { - _family = value; + _quiescentDuration = value; } } /// - /// Rate parameter of the distribution + /// Duration after go cue for animal response. /// - [Newtonsoft.Json.JsonPropertyAttribute("rate")] - [System.ComponentModel.DescriptionAttribute("Rate parameter of the distribution")] - public double Rate + [Newtonsoft.Json.JsonPropertyAttribute("response_duration")] + [System.ComponentModel.DescriptionAttribute("Duration after go cue for animal response.")] + public double ResponseDuration { get { - return _rate; + return _responseDuration; } set { - _rate = value; + _responseDuration = value; } } - public System.IObservable Generate() - { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ExponentialDistributionParameters(this))); - } - - public System.IObservable Generate(System.IObservable source) + /// + /// Duration of reward consumption before transition to ITI (in seconds). + /// + [Newtonsoft.Json.JsonPropertyAttribute("reward_consumption_duration")] + [System.ComponentModel.DescriptionAttribute("Duration of reward consumption before transition to ITI (in seconds).")] + public double RewardConsumptionDuration { - return System.Reactive.Linq.Observable.Select(source, _ => new ExponentialDistributionParameters(this)); + get + { + return _rewardConsumptionDuration; + } + set + { + _rewardConsumptionDuration = value; + } } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + /// + /// Distribution describing the inter-trial interval (in seconds). + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("inter_trial_interval_duration")] + [System.ComponentModel.DescriptionAttribute("Distribution describing the inter-trial interval (in seconds).")] + public Distribution InterTrialIntervalDuration { - stringBuilder.Append("Family = " + _family + ", "); - stringBuilder.Append("Rate = " + _rate); - return true; + get + { + return _interTrialIntervalDuration; + } + set + { + _interTrialIntervalDuration = value; + } } - public override string ToString() + /// + /// Distribution describing block length. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("block_len")] + [System.ComponentModel.DescriptionAttribute("Distribution describing block length.")] + public Distribution BlockLen { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) + get { - stringBuilder.Append(" "); + return _blockLen; + } + set + { + _blockLen = value; } - stringBuilder.Append("}"); - return stringBuilder.ToString(); } - } - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] - [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class HarpBehavior - { - - private string _deviceType; - - private BaseModel _calibration; - - private int _whoAmI; - - private string _serialNumber; - - private string _portName; - public HarpBehavior() + [Newtonsoft.Json.JsonPropertyAttribute("min_block_reward")] + public int MinBlockReward { - _deviceType = "Behavior"; - _whoAmI = 1216; + get + { + return _minBlockReward; + } + set + { + _minBlockReward = value; + } } - protected HarpBehavior(HarpBehavior other) + /// + /// Kernel to evaluate choice fraction. + /// + [Newtonsoft.Json.JsonPropertyAttribute("kernel_size")] + [System.ComponentModel.DescriptionAttribute("Kernel to evaluate choice fraction.")] + public int KernelSize { - _deviceType = other._deviceType; - _calibration = other._calibration; - _whoAmI = other._whoAmI; - _serialNumber = other._serialNumber; - _portName = other._portName; + get + { + return _kernelSize; + } + set + { + _kernelSize = value; + } } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + /// + /// Parameters defining the reward probability structure. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("reward_probability_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters defining the reward probability structure.")] + public RewardProbabilityParameters RewardProbabilityParameters { get { - return _deviceType; + return _rewardProbabilityParameters; } set { - _deviceType = value; + _rewardProbabilityParameters = value; } } /// - /// Calibration for the device. + /// Whether uncollected rewards carry over to the next trial. /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("is_baiting")] + [System.ComponentModel.DescriptionAttribute("Whether uncollected rewards carry over to the next trial.")] + public bool IsBaiting { get { - return _calibration; + return _isBaiting; } set { - _calibration = value; + _isBaiting = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] - public int WhoAmI + /// + /// Conditions to end trial generation. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("trial_generation_end_parameters")] + [System.ComponentModel.DescriptionAttribute("Conditions to end trial generation.")] + public CoupledTrialGenerationEndConditions TrialGenerationEndParameters { get { - return _whoAmI; + return _trialGenerationEndParameters; } set { - _whoAmI = value; + _trialGenerationEndParameters = value; } } /// - /// Device serial number + /// Parameters controlling behavior-dependent block switching. If None, block switches rely only on length and reward criteria. /// - [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] - [System.ComponentModel.DescriptionAttribute("Device serial number")] - public string SerialNumber + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("behavior_stability_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters controlling behavior-dependent block switching. If None, block switche" + + "s rely only on length and reward criteria.")] + public BehaviorStabilityParameters BehaviorStabilityParameters { get { - return _serialNumber; + return _behaviorStabilityParameters; } set { - _serialNumber = value; + _behaviorStabilityParameters = value; } } /// - /// Device port name + /// Whether to extend the minimum block length by one trial when the animal does not respond. /// - [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Device port name")] - public string PortName + [Newtonsoft.Json.JsonPropertyAttribute("extend_block_on_no_response")] + [System.ComponentModel.DescriptionAttribute("Whether to extend the minimum block length by one trial when the animal does not " + + "respond.")] + public bool ExtendBlockOnNoResponse { get { - return _portName; + return _extendBlockOnNoResponse; } set { - _portName = value; + _extendBlockOnNoResponse = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpBehavior(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new CoupledTrialGeneratorSpec(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new HarpBehavior(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new CoupledTrialGeneratorSpec(this)); } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); - stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); - stringBuilder.Append("PortName = " + _portName); + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("QuiescentDuration = " + _quiescentDuration + ", "); + stringBuilder.Append("ResponseDuration = " + _responseDuration + ", "); + stringBuilder.Append("RewardConsumptionDuration = " + _rewardConsumptionDuration + ", "); + stringBuilder.Append("InterTrialIntervalDuration = " + _interTrialIntervalDuration + ", "); + stringBuilder.Append("BlockLen = " + _blockLen + ", "); + stringBuilder.Append("MinBlockReward = " + _minBlockReward + ", "); + stringBuilder.Append("KernelSize = " + _kernelSize + ", "); + stringBuilder.Append("RewardProbabilityParameters = " + _rewardProbabilityParameters + ", "); + stringBuilder.Append("IsBaiting = " + _isBaiting + ", "); + stringBuilder.Append("TrialGenerationEndParameters = " + _trialGenerationEndParameters + ", "); + stringBuilder.Append("BehaviorStabilityParameters = " + _behaviorStabilityParameters + ", "); + stringBuilder.Append("ExtendBlockOnNoResponse = " + _extendBlockOnNoResponse); return true; } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "family")] + [JsonInheritanceAttribute("Scalar", typeof(Scalar))] + [JsonInheritanceAttribute("Beta", typeof(BetaDistribution))] + [JsonInheritanceAttribute("Binomial", typeof(BinomialDistribution))] + [JsonInheritanceAttribute("Exponential", typeof(ExponentialDistribution))] + [JsonInheritanceAttribute("Normal", typeof(NormalDistribution))] + [JsonInheritanceAttribute("LogNormal", typeof(LogNormalDistribution))] + [JsonInheritanceAttribute("Uniform", typeof(UniformDistribution))] + [JsonInheritanceAttribute("Poisson", typeof(PoissonDistribution))] + [JsonInheritanceAttribute("Gamma", typeof(GammaDistribution))] + [JsonInheritanceAttribute("Pdf", typeof(PdfDistribution))] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class Distribution + { + + public Distribution() + { + } + + protected Distribution(Distribution other) + { + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Distribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new Distribution(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + return false; + } public override string ToString() { @@ -3127,15 +2754,20 @@ public override string ToString() } + /// + /// A calibrated sound card for the dynamic foraging rig. This is a subclass of the HarpSoundCard that includes the sound card calibration. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A calibrated sound card for the dynamic foraging rig. This is a subclass of the H" + + "arpSoundCard that includes the sound card calibration.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class HarpEnvironmentSensor + public partial class DynamicForagingSoundCard { private string _deviceType; - private BaseModel _calibration; + private SoundCardCalibration _calibration; private int _whoAmI; @@ -3143,13 +2775,14 @@ public partial class HarpEnvironmentSensor private string _portName; - public HarpEnvironmentSensor() + public DynamicForagingSoundCard() { - _deviceType = "EnvironmentSensor"; - _whoAmI = 1405; + _deviceType = "SoundCard"; + _calibration = new SoundCardCalibration(); + _whoAmI = 1280; } - protected HarpEnvironmentSensor(HarpEnvironmentSensor other) + protected DynamicForagingSoundCard(DynamicForagingSoundCard other) { _deviceType = other._deviceType; _calibration = other._calibration; @@ -3172,12 +2805,12 @@ public string DeviceType } /// - /// Calibration for the device. + /// Sound card calibration /// [System.Xml.Serialization.XmlIgnoreAttribute()] [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [System.ComponentModel.DescriptionAttribute("Sound card calibration")] + public SoundCardCalibration Calibration { get { @@ -3236,14 +2869,14 @@ public string PortName } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpEnvironmentSensor(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new DynamicForagingSoundCard(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new HarpEnvironmentSensor(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new DynamicForagingSoundCard(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) @@ -3271,47 +2904,1053 @@ public override string ToString() } + /// + /// An exponential probability distribution. + /// + ///Models time between events in a Poisson process. Commonly used + ///for wait times and inter-event intervals. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("An exponential probability distribution.\n\nModels time between events in a Poisson" + + " process. Commonly used\nfor wait times and inter-event intervals.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class HarpLicketySplit + public partial class ExponentialDistribution : Distribution { - private string _deviceType; - - private BaseModel _calibration; - - private int _whoAmI; + private ExponentialDistributionParameters _distributionParameters; - private string _serialNumber; + private TruncationParameters _truncationParameters; - private string _portName; + private ScalingParameters _scalingParameters; - public HarpLicketySplit() + public ExponentialDistribution() { - _deviceType = "LicketySplit"; - _whoAmI = 1400; + _distributionParameters = new ExponentialDistributionParameters(); } - protected HarpLicketySplit(HarpLicketySplit other) + protected ExponentialDistribution(ExponentialDistribution other) : + base(other) { - _deviceType = other._deviceType; - _calibration = other._calibration; - _whoAmI = other._whoAmI; - _serialNumber = other._serialNumber; - _portName = other._portName; + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public ExponentialDistributionParameters DistributionParameters { get { - return _deviceType; + return _distributionParameters; } set { - _deviceType = value; + _distributionParameters = value; + } + } + + /// + /// Truncation parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters + { + get + { + return _truncationParameters; + } + set + { + _truncationParameters = value; + } + } + + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters + { + get + { + return _scalingParameters; + } + set + { + _scalingParameters = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ExponentialDistribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new ExponentialDistribution(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; + } + } + + + /// + /// Parameters for an exponential distribution. + /// + ///Defined by the rate parameter (inverse of mean). + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for an exponential distribution.\n\nDefined by the rate parameter (inver" + + "se of mean).")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class ExponentialDistributionParameters + { + + private string _family; + + private double _rate; + + public ExponentialDistributionParameters() + { + _family = "Exponential"; + _rate = 0D; + } + + protected ExponentialDistributionParameters(ExponentialDistributionParameters other) + { + _family = other._family; + _rate = other._rate; + } + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family + { + get + { + return _family; + } + set + { + _family = value; + } + } + + /// + /// Rate parameter of the distribution + /// + [Newtonsoft.Json.JsonPropertyAttribute("rate")] + [System.ComponentModel.DescriptionAttribute("Rate parameter of the distribution")] + public double Rate + { + get + { + return _rate; + } + set + { + _rate = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ExponentialDistributionParameters(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new ExponentialDistributionParameters(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Rate = " + _rate); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + /// + /// A gamma probability distribution. + /// + ///Generalizes the exponential distribution. Used for modeling + ///positive continuous variables with right-skewed distributions. + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A gamma probability distribution.\n\nGeneralizes the exponential distribution. Used" + + " for modeling\npositive continuous variables with right-skewed distributions.")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class GammaDistribution : Distribution + { + + private GammaDistributionParameters _distributionParameters; + + private TruncationParameters _truncationParameters; + + private ScalingParameters _scalingParameters; + + public GammaDistribution() + { + _distributionParameters = new GammaDistributionParameters(); + } + + protected GammaDistribution(GammaDistribution other) : + base(other) + { + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; + } + + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public GammaDistributionParameters DistributionParameters + { + get + { + return _distributionParameters; + } + set + { + _distributionParameters = value; + } + } + + /// + /// Truncation parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters + { + get + { + return _truncationParameters; + } + set + { + _truncationParameters = value; + } + } + + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters + { + get + { + return _scalingParameters; + } + set + { + _scalingParameters = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new GammaDistribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new GammaDistribution(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; + } + } + + + /// + /// Parameters for a gamma distribution. + /// + ///Defined by shape (k) and rate (θ⁻¹) parameters. + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a gamma distribution.\n\nDefined by shape (k) and rate (θ⁻¹) paramet" + + "ers.")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class GammaDistributionParameters + { + + private string _family; + + private double _shape; + + private double _rate; + + public GammaDistributionParameters() + { + _family = "Gamma"; + _shape = 1D; + _rate = 1D; + } + + protected GammaDistributionParameters(GammaDistributionParameters other) + { + _family = other._family; + _shape = other._shape; + _rate = other._rate; + } + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family + { + get + { + return _family; + } + set + { + _family = value; + } + } + + /// + /// Shape parameter of the distribution + /// + [Newtonsoft.Json.JsonPropertyAttribute("shape")] + [System.ComponentModel.DescriptionAttribute("Shape parameter of the distribution")] + public double Shape + { + get + { + return _shape; + } + set + { + _shape = value; + } + } + + /// + /// Rate parameter of the distribution + /// + [Newtonsoft.Json.JsonPropertyAttribute("rate")] + [System.ComponentModel.DescriptionAttribute("Rate parameter of the distribution")] + public double Rate + { + get + { + return _rate; + } + set + { + _rate = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new GammaDistributionParameters(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new GammaDistributionParameters(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Shape = " + _shape + ", "); + stringBuilder.Append("Rate = " + _rate); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class HarpBehavior + { + + private string _deviceType; + + private BaseModel _calibration; + + private int _whoAmI; + + private string _serialNumber; + + private string _portName; + + public HarpBehavior() + { + _deviceType = "Behavior"; + _whoAmI = 1216; + } + + protected HarpBehavior(HarpBehavior other) + { + _deviceType = other._deviceType; + _calibration = other._calibration; + _whoAmI = other._whoAmI; + _serialNumber = other._serialNumber; + _portName = other._portName; + } + + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType + { + get + { + return _deviceType; + } + set + { + _deviceType = value; + } + } + + /// + /// Calibration for the device. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration + { + get + { + return _calibration; + } + set + { + _calibration = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] + public int WhoAmI + { + get + { + return _whoAmI; + } + set + { + _whoAmI = value; + } + } + + /// + /// Device serial number + /// + [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] + [System.ComponentModel.DescriptionAttribute("Device serial number")] + public string SerialNumber + { + get + { + return _serialNumber; + } + set + { + _serialNumber = value; + } + } + + /// + /// Device port name + /// + [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Device port name")] + public string PortName + { + get + { + return _portName; + } + set + { + _portName = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpBehavior(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new HarpBehavior(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); + stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); + stringBuilder.Append("PortName = " + _portName); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class HarpEnvironmentSensor + { + + private string _deviceType; + + private BaseModel _calibration; + + private int _whoAmI; + + private string _serialNumber; + + private string _portName; + + public HarpEnvironmentSensor() + { + _deviceType = "EnvironmentSensor"; + _whoAmI = 1405; + } + + protected HarpEnvironmentSensor(HarpEnvironmentSensor other) + { + _deviceType = other._deviceType; + _calibration = other._calibration; + _whoAmI = other._whoAmI; + _serialNumber = other._serialNumber; + _portName = other._portName; + } + + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType + { + get + { + return _deviceType; + } + set + { + _deviceType = value; + } + } + + /// + /// Calibration for the device. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration + { + get + { + return _calibration; + } + set + { + _calibration = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] + public int WhoAmI + { + get + { + return _whoAmI; + } + set + { + _whoAmI = value; + } + } + + /// + /// Device serial number + /// + [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] + [System.ComponentModel.DescriptionAttribute("Device serial number")] + public string SerialNumber + { + get + { + return _serialNumber; + } + set + { + _serialNumber = value; + } + } + + /// + /// Device port name + /// + [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Device port name")] + public string PortName + { + get + { + return _portName; + } + set + { + _portName = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpEnvironmentSensor(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new HarpEnvironmentSensor(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); + stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); + stringBuilder.Append("PortName = " + _portName); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class HarpLicketySplit + { + + private string _deviceType; + + private BaseModel _calibration; + + private int _whoAmI; + + private string _serialNumber; + + private string _portName; + + public HarpLicketySplit() + { + _deviceType = "LicketySplit"; + _whoAmI = 1400; + } + + protected HarpLicketySplit(HarpLicketySplit other) + { + _deviceType = other._deviceType; + _calibration = other._calibration; + _whoAmI = other._whoAmI; + _serialNumber = other._serialNumber; + _portName = other._portName; + } + + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType + { + get + { + return _deviceType; + } + set + { + _deviceType = value; + } + } + + /// + /// Calibration for the device. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration + { + get + { + return _calibration; + } + set + { + _calibration = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] + public int WhoAmI + { + get + { + return _whoAmI; + } + set + { + _whoAmI = value; + } + } + + /// + /// Device serial number + /// + [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] + [System.ComponentModel.DescriptionAttribute("Device serial number")] + public string SerialNumber + { + get + { + return _serialNumber; + } + set + { + _serialNumber = value; + } + } + + /// + /// Device port name + /// + [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Device port name")] + public string PortName + { + get + { + return _portName; + } + set + { + _portName = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpLicketySplit(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new HarpLicketySplit(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); + stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); + stringBuilder.Append("PortName = " + _portName); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class HarpSniffDetector + { + + private string _deviceType; + + private BaseModel _calibration; + + private int _whoAmI; + + private string _serialNumber; + + private string _portName; + + public HarpSniffDetector() + { + _deviceType = "SniffDetector"; + _whoAmI = 1401; + } + + protected HarpSniffDetector(HarpSniffDetector other) + { + _deviceType = other._deviceType; + _calibration = other._calibration; + _whoAmI = other._whoAmI; + _serialNumber = other._serialNumber; + _portName = other._portName; + } + + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType + { + get + { + return _deviceType; + } + set + { + _deviceType = value; + } + } + + /// + /// Calibration for the device. + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration + { + get + { + return _calibration; + } + set + { + _calibration = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] + public int WhoAmI + { + get + { + return _whoAmI; + } + set + { + _whoAmI = value; + } + } + + /// + /// Device serial number + /// + [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] + [System.ComponentModel.DescriptionAttribute("Device serial number")] + public string SerialNumber + { + get + { + return _serialNumber; + } + set + { + _serialNumber = value; + } + } + + /// + /// Device port name + /// + [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Device port name")] + public string PortName + { + get + { + return _portName; + } + set + { + _portName = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpSniffDetector(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new HarpSniffDetector(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); + stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); + stringBuilder.Append("PortName = " + _portName); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class HarpWhiteRabbit + { + + private string _deviceType; + + private BaseModel _calibration; + + private int _whoAmI; + + private string _serialNumber; + + private string _portName; + + private System.Collections.Generic.List _connectedClockOutputs; + + public HarpWhiteRabbit() + { + _deviceType = "WhiteRabbit"; + _whoAmI = 1404; + _connectedClockOutputs = new System.Collections.Generic.List(); + } + + protected HarpWhiteRabbit(HarpWhiteRabbit other) + { + _deviceType = other._deviceType; + _calibration = other._calibration; + _whoAmI = other._whoAmI; + _serialNumber = other._serialNumber; + _portName = other._portName; + _connectedClockOutputs = other._connectedClockOutputs; + } + + [Newtonsoft.Json.JsonPropertyAttribute("device_type")] + public string DeviceType + { + get + { + return _deviceType; + } + set + { + _deviceType = value; } } @@ -3319,84 +3958,360 @@ public string DeviceType /// Calibration for the device. /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("calibration")] + [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] + public BaseModel Calibration + { + get + { + return _calibration; + } + set + { + _calibration = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] + public int WhoAmI + { + get + { + return _whoAmI; + } + set + { + _whoAmI = value; + } + } + + /// + /// Device serial number + /// + [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] + [System.ComponentModel.DescriptionAttribute("Device serial number")] + public string SerialNumber + { + get + { + return _serialNumber; + } + set + { + _serialNumber = value; + } + } + + /// + /// Device port name + /// + [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Device port name")] + public string PortName + { + get + { + return _portName; + } + set + { + _portName = value; + } + } + + /// + /// Connected clock outputs + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("connected_clock_outputs")] + [System.ComponentModel.DescriptionAttribute("Connected clock outputs")] + public System.Collections.Generic.List ConnectedClockOutputs + { + get + { + return _connectedClockOutputs; + } + set + { + _connectedClockOutputs = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpWhiteRabbit(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new HarpWhiteRabbit(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("DeviceType = " + _deviceType + ", "); + stringBuilder.Append("Calibration = " + _calibration + ", "); + stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); + stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); + stringBuilder.Append("PortName = " + _portName + ", "); + stringBuilder.Append("ConnectedClockOutputs = " + _connectedClockOutputs); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class IntegrationTestTrialGeneratorSpec : TrialGeneratorSpec + { + + public IntegrationTestTrialGeneratorSpec() + { + } + + protected IntegrationTestTrialGeneratorSpec(IntegrationTestTrialGeneratorSpec other) : + base(other) + { + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new IntegrationTestTrialGeneratorSpec(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new IntegrationTestTrialGeneratorSpec(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + return base.PrintMembers(stringBuilder); + } + } + + + /// + /// A log-normal probability distribution. + /// + ///Distribution where the logarithm of the variable is normally distributed. + ///Always produces positive values and is right-skewed. + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A log-normal probability distribution.\n\nDistribution where the logarithm of the v" + + "ariable is normally distributed.\nAlways produces positive values and is right-sk" + + "ewed.")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class LogNormalDistribution : Distribution + { + + private LogNormalDistributionParameters _distributionParameters; + + private TruncationParameters _truncationParameters; + + private ScalingParameters _scalingParameters; + + public LogNormalDistribution() + { + _distributionParameters = new LogNormalDistributionParameters(); + } + + protected LogNormalDistribution(LogNormalDistribution other) : + base(other) + { + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; + } + + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public LogNormalDistributionParameters DistributionParameters + { + get + { + return _distributionParameters; + } + set + { + _distributionParameters = value; + } + } + + /// + /// Truncation parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters + { + get + { + return _truncationParameters; + } + set + { + _truncationParameters = value; + } + } + + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { get { - return _calibration; + return _scalingParameters; } set { - _calibration = value; + _scalingParameters = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] - public int WhoAmI + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new LogNormalDistribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new LogNormalDistribution(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; + } + } + + + /// + /// Parameters for a log-normal distribution. + /// + ///Defined by the mean and standard deviation of the underlying normal distribution. + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a log-normal distribution.\n\nDefined by the mean and standard devia" + + "tion of the underlying normal distribution.")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class LogNormalDistributionParameters + { + + private string _family; + + private double _mean; + + private double _std; + + public LogNormalDistributionParameters() + { + _family = "LogNormal"; + _mean = 0D; + _std = 0D; + } + + protected LogNormalDistributionParameters(LogNormalDistributionParameters other) + { + _family = other._family; + _mean = other._mean; + _std = other._std; + } + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _whoAmI; + return _family; } set { - _whoAmI = value; + _family = value; } } /// - /// Device serial number + /// Mean of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] - [System.ComponentModel.DescriptionAttribute("Device serial number")] - public string SerialNumber + [Newtonsoft.Json.JsonPropertyAttribute("mean")] + [System.ComponentModel.DescriptionAttribute("Mean of the distribution")] + public double Mean { get { - return _serialNumber; + return _mean; } set { - _serialNumber = value; + _mean = value; } } /// - /// Device port name + /// Standard deviation of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Device port name")] - public string PortName + [Newtonsoft.Json.JsonPropertyAttribute("std")] + [System.ComponentModel.DescriptionAttribute("Standard deviation of the distribution")] + public double Std { get { - return _portName; + return _std; } set { - _portName = value; + _std = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpLicketySplit(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new LogNormalDistributionParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new HarpLicketySplit(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new LogNormalDistributionParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); - stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); - stringBuilder.Append("PortName = " + _portName); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Mean = " + _mean + ", "); + stringBuilder.Append("Std = " + _std); return true; } @@ -3415,132 +4330,238 @@ public override string ToString() } + /// + /// Represents a position in the manipulator coordinate system + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Represents a position in the manipulator coordinate system")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class HarpSniffDetector + public partial class ManipulatorPosition { - private string _deviceType; + private double _x; - private BaseModel _calibration; + private double _y1; - private int _whoAmI; + private double _y2; - private string _serialNumber; + private double _z; - private string _portName; + public ManipulatorPosition() + { + } - public HarpSniffDetector() + protected ManipulatorPosition(ManipulatorPosition other) { - _deviceType = "SniffDetector"; - _whoAmI = 1401; + _x = other._x; + _y1 = other._y1; + _y2 = other._y2; + _z = other._z; } - protected HarpSniffDetector(HarpSniffDetector other) + [Newtonsoft.Json.JsonPropertyAttribute("x", Required=Newtonsoft.Json.Required.Always)] + public double X { - _deviceType = other._deviceType; - _calibration = other._calibration; - _whoAmI = other._whoAmI; - _serialNumber = other._serialNumber; - _portName = other._portName; + get + { + return _x; + } + set + { + _x = value; + } } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + [Newtonsoft.Json.JsonPropertyAttribute("y1", Required=Newtonsoft.Json.Required.Always)] + public double Y1 { get { - return _deviceType; + return _y1; } set { - _deviceType = value; + _y1 = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("y2", Required=Newtonsoft.Json.Required.Always)] + public double Y2 + { + get + { + return _y2; + } + set + { + _y2 = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("z", Required=Newtonsoft.Json.Required.Always)] + public double Z + { + get + { + return _z; + } + set + { + _z = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ManipulatorPosition(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new ManipulatorPosition(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + stringBuilder.Append("X = " + _x + ", "); + stringBuilder.Append("Y1 = " + _y1 + ", "); + stringBuilder.Append("Y2 = " + _y2 + ", "); + stringBuilder.Append("Z = " + _z); + return true; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } + } + + + /// + /// Input for water valve calibration class + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Input for water valve calibration class")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class Measurement + { + + private double _valveOpenInterval; + + private double _valveOpenTime; + + private System.Collections.Generic.List _waterWeight; + + private int _repeatCount; + + public Measurement() + { + _waterWeight = new System.Collections.Generic.List(); + } + + protected Measurement(Measurement other) + { + _valveOpenInterval = other._valveOpenInterval; + _valveOpenTime = other._valveOpenTime; + _waterWeight = other._waterWeight; + _repeatCount = other._repeatCount; } /// - /// Calibration for the device. + /// Time between two consecutive valve openings (s) /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("valve_open_interval", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Time between two consecutive valve openings (s)")] + public double ValveOpenInterval { get { - return _calibration; + return _valveOpenInterval; } set { - _calibration = value; + _valveOpenInterval = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] - public int WhoAmI + /// + /// Valve open interval (s) + /// + [Newtonsoft.Json.JsonPropertyAttribute("valve_open_time", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Valve open interval (s)")] + public double ValveOpenTime { get { - return _whoAmI; + return _valveOpenTime; } set { - _whoAmI = value; + _valveOpenTime = value; } } /// - /// Device serial number + /// Weight of water delivered (g) /// - [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] - [System.ComponentModel.DescriptionAttribute("Device serial number")] - public string SerialNumber + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("water_weight", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Weight of water delivered (g)")] + public System.Collections.Generic.List WaterWeight { get { - return _serialNumber; + return _waterWeight; } set { - _serialNumber = value; + _waterWeight = value; } } /// - /// Device port name + /// Number of times the valve opened. /// - [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Device port name")] - public string PortName + [Newtonsoft.Json.JsonPropertyAttribute("repeat_count", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Number of times the valve opened.")] + public int RepeatCount { get { - return _portName; + return _repeatCount; } set { - _portName = value; + _repeatCount = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpSniffDetector(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Measurement(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new HarpSniffDetector(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new Measurement(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); - stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); - stringBuilder.Append("PortName = " + _portName); + stringBuilder.Append("ValveOpenInterval = " + _valveOpenInterval + ", "); + stringBuilder.Append("ValveOpenTime = " + _valveOpenTime + ", "); + stringBuilder.Append("WaterWeight = " + _waterWeight + ", "); + stringBuilder.Append("RepeatCount = " + _repeatCount); return true; } @@ -3559,155 +4580,249 @@ public override string ToString() } + /// + /// Microstep resolution available + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] - [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class HarpWhiteRabbit + public enum MicrostepResolution { - private string _deviceType; + [System.Runtime.Serialization.EnumMemberAttribute(Value="0")] + Microstep8 = 0, - private BaseModel _calibration; + [System.Runtime.Serialization.EnumMemberAttribute(Value="1")] + Microstep16 = 1, - private int _whoAmI; + [System.Runtime.Serialization.EnumMemberAttribute(Value="2")] + Microstep32 = 2, - private string _serialNumber; + [System.Runtime.Serialization.EnumMemberAttribute(Value="3")] + Microstep64 = 3, + } + + + /// + /// Motor operation mode + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + public enum MotorOperationMode + { - private string _portName; + [System.Runtime.Serialization.EnumMemberAttribute(Value="0")] + Quiet = 0, - private System.Collections.Generic.List _connectedClockOutputs; + [System.Runtime.Serialization.EnumMemberAttribute(Value="1")] + Dynamic = 1, + } + + + /// + /// A normal (Gaussian) probability distribution. + /// + ///Bell-shaped distribution symmetric around the mean, commonly used + ///for modeling naturally occurring random variables. + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A normal (Gaussian) probability distribution.\n\nBell-shaped distribution symmetric" + + " around the mean, commonly used\nfor modeling naturally occurring random variable" + + "s.")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class NormalDistribution : Distribution + { - public HarpWhiteRabbit() + private NormalDistributionParameters _distributionParameters; + + private TruncationParameters _truncationParameters; + + private ScalingParameters _scalingParameters; + + public NormalDistribution() { - _deviceType = "WhiteRabbit"; - _whoAmI = 1404; - _connectedClockOutputs = new System.Collections.Generic.List(); + _distributionParameters = new NormalDistributionParameters(); } - protected HarpWhiteRabbit(HarpWhiteRabbit other) + protected NormalDistribution(NormalDistribution other) : + base(other) { - _deviceType = other._deviceType; - _calibration = other._calibration; - _whoAmI = other._whoAmI; - _serialNumber = other._serialNumber; - _portName = other._portName; - _connectedClockOutputs = other._connectedClockOutputs; + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } - [Newtonsoft.Json.JsonPropertyAttribute("device_type")] - public string DeviceType + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public NormalDistributionParameters DistributionParameters { get { - return _deviceType; + return _distributionParameters; } set { - _deviceType = value; + _distributionParameters = value; } } /// - /// Calibration for the device. + /// Truncation parameters of the distribution /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("calibration")] - [System.ComponentModel.DescriptionAttribute("Calibration for the device.")] - public BaseModel Calibration + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters { get { - return _calibration; + return _truncationParameters; } set { - _calibration = value; + _truncationParameters = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("who_am_i")] - public int WhoAmI + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { get { - return _whoAmI; + return _scalingParameters; } set { - _whoAmI = value; + _scalingParameters = value; } } - /// - /// Device serial number - /// - [Newtonsoft.Json.JsonPropertyAttribute("serial_number")] - [System.ComponentModel.DescriptionAttribute("Device serial number")] - public string SerialNumber + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new NormalDistribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new NormalDistribution(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; + } + } + + + /// + /// Parameters for a normal (Gaussian) distribution. + /// + ///Defined by mean (center) and standard deviation (spread). + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a normal (Gaussian) distribution.\n\nDefined by mean (center) and st" + + "andard deviation (spread).")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class NormalDistributionParameters + { + + private string _family; + + private double _mean; + + private double _std; + + public NormalDistributionParameters() + { + _family = "Normal"; + _mean = 0D; + _std = 0D; + } + + protected NormalDistributionParameters(NormalDistributionParameters other) + { + _family = other._family; + _mean = other._mean; + _std = other._std; + } + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _serialNumber; + return _family; } set { - _serialNumber = value; + _family = value; } } /// - /// Device port name + /// Mean of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("port_name", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Device port name")] - public string PortName + [Newtonsoft.Json.JsonPropertyAttribute("mean")] + [System.ComponentModel.DescriptionAttribute("Mean of the distribution")] + public double Mean { get { - return _portName; + return _mean; } set { - _portName = value; + _mean = value; } } /// - /// Connected clock outputs + /// Standard deviation of the distribution /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("connected_clock_outputs")] - [System.ComponentModel.DescriptionAttribute("Connected clock outputs")] - public System.Collections.Generic.List ConnectedClockOutputs + [Newtonsoft.Json.JsonPropertyAttribute("std")] + [System.ComponentModel.DescriptionAttribute("Standard deviation of the distribution")] + public double Std { get { - return _connectedClockOutputs; + return _std; } set { - _connectedClockOutputs = value; + _std = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new HarpWhiteRabbit(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new NormalDistributionParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new HarpWhiteRabbit(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new NormalDistributionParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("DeviceType = " + _deviceType + ", "); - stringBuilder.Append("Calibration = " + _calibration + ", "); - stringBuilder.Append("WhoAmI = " + _whoAmI + ", "); - stringBuilder.Append("SerialNumber = " + _serialNumber + ", "); - stringBuilder.Append("PortName = " + _portName + ", "); - stringBuilder.Append("ConnectedClockOutputs = " + _connectedClockOutputs); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Mean = " + _mean + ", "); + stringBuilder.Append("Std = " + _std); return true; } @@ -3726,252 +4841,217 @@ public override string ToString() } + /// + /// A custom probability density function distribution. + /// + ///Allows defining arbitrary discrete distributions by specifying + ///probability values and their corresponding indices. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A custom probability density function distribution.\n\nAllows defining arbitrary di" + + "screte distributions by specifying\nprobability values and their corresponding in" + + "dices.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class IntegrationTestTrialGeneratorSpec : TrialGeneratorSpec - { - - public IntegrationTestTrialGeneratorSpec() - { - } - - protected IntegrationTestTrialGeneratorSpec(IntegrationTestTrialGeneratorSpec other) : - base(other) - { - } - - public System.IObservable Generate() - { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new IntegrationTestTrialGeneratorSpec(this))); - } - - public System.IObservable Generate(System.IObservable source) - { - return System.Reactive.Linq.Observable.Select(source, _ => new IntegrationTestTrialGeneratorSpec(this)); - } - - protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) - { - return base.PrintMembers(stringBuilder); - } - } - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] - [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class InterTrialInterval + public partial class PdfDistribution : Distribution { - private double _min; - - private double _max; - - private double _beta; + private PdfDistributionParameters _distributionParameters; - private double _increase; + private TruncationParameters _truncationParameters; - public InterTrialInterval() - { - _min = 1D; - _max = 8D; - _beta = 2D; - _increase = 0D; - } + private ScalingParameters _scalingParameters; - protected InterTrialInterval(InterTrialInterval other) + public PdfDistribution() { - _min = other._min; - _max = other._max; - _beta = other._beta; - _increase = other._increase; + _distributionParameters = new PdfDistributionParameters(); } - [Newtonsoft.Json.JsonPropertyAttribute("min")] - public double Min + protected PdfDistribution(PdfDistribution other) : + base(other) { - get - { - return _min; - } - set - { - _min = value; - } + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } - [Newtonsoft.Json.JsonPropertyAttribute("max")] - public double Max + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public PdfDistributionParameters DistributionParameters { get { - return _max; + return _distributionParameters; } set { - _max = value; + _distributionParameters = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("beta")] - public double Beta + /// + /// Truncation parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters { get { - return _beta; + return _truncationParameters; } set { - _beta = value; + _truncationParameters = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("increase")] - public double Increase + /// + /// Scaling parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { get { - return _increase; + return _scalingParameters; } set { - _increase = value; + _scalingParameters = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new InterTrialInterval(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new PdfDistribution(this))); } - public System.IObservable Generate(System.IObservable source) - { - return System.Reactive.Linq.Observable.Select(source, _ => new InterTrialInterval(this)); - } - - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + public System.IObservable Generate(System.IObservable source) { - stringBuilder.Append("Min = " + _min + ", "); - stringBuilder.Append("Max = " + _max + ", "); - stringBuilder.Append("Beta = " + _beta + ", "); - stringBuilder.Append("Increase = " + _increase); - return true; + return System.Reactive.Linq.Observable.Select(source, _ => new PdfDistribution(this)); } - public override string ToString() + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) + if (base.PrintMembers(stringBuilder)) { - stringBuilder.Append(" "); + stringBuilder.Append(", "); } - stringBuilder.Append("}"); - return stringBuilder.ToString(); + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; } } /// - /// Represents a position in the manipulator coordinate system + /// Parameters for a custom probability density function distribution. + /// + ///Defined by explicit probability values and their corresponding indices. + ///Probabilities are automatically normalized to sum to 1. /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("Represents a position in the manipulator coordinate system")] + [System.ComponentModel.DescriptionAttribute("Parameters for a custom probability density function distribution.\n\nDefined by ex" + + "plicit probability values and their corresponding indices.\nProbabilities are aut" + + "omatically normalized to sum to 1.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class ManipulatorPosition + public partial class PdfDistributionParameters { - private double _x; - - private double _y1; - - private double _y2; + private string _family; - private double _z; + private System.Collections.Generic.List _pdf; - public ManipulatorPosition() - { - } + private System.Collections.Generic.List _index; - protected ManipulatorPosition(ManipulatorPosition other) + public PdfDistributionParameters() { - _x = other._x; - _y1 = other._y1; - _y2 = other._y2; - _z = other._z; + _family = "Pdf"; + _pdf = new System.Collections.Generic.List(); + _index = new System.Collections.Generic.List(); } - [Newtonsoft.Json.JsonPropertyAttribute("x", Required=Newtonsoft.Json.Required.Always)] - public double X + protected PdfDistributionParameters(PdfDistributionParameters other) { - get - { - return _x; - } - set - { - _x = value; - } + _family = other._family; + _pdf = other._pdf; + _index = other._index; } - [Newtonsoft.Json.JsonPropertyAttribute("y1", Required=Newtonsoft.Json.Required.Always)] - public double Y1 + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _y1; + return _family; } set { - _y1 = value; + _family = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("y2", Required=Newtonsoft.Json.Required.Always)] - public double Y2 + /// + /// The probability density function + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("pdf")] + [System.ComponentModel.DescriptionAttribute("The probability density function")] + public System.Collections.Generic.List Pdf { get { - return _y2; + return _pdf; } set { - _y2 = value; + _pdf = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("z", Required=Newtonsoft.Json.Required.Always)] - public double Z + /// + /// The index of the probability density function + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("index")] + [System.ComponentModel.DescriptionAttribute("The index of the probability density function")] + public System.Collections.Generic.List Index { get { - return _z; + return _index; } set { - _z = value; + _index = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ManipulatorPosition(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new PdfDistributionParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new ManipulatorPosition(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new PdfDistributionParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("X = " + _x + ", "); - stringBuilder.Append("Y1 = " + _y1 + ", "); - stringBuilder.Append("Y2 = " + _y2 + ", "); - stringBuilder.Append("Z = " + _z); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Pdf = " + _pdf + ", "); + stringBuilder.Append("Index = " + _index); return true; } @@ -3991,121 +5071,190 @@ public override string ToString() /// - /// Input for water valve calibration class + /// A Poisson probability distribution. + /// + ///Models the number of events occurring in a fixed interval of time or space + ///when events occur independently at a constant rate. /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("Input for water valve calibration class")] + [System.ComponentModel.DescriptionAttribute("A Poisson probability distribution.\n\nModels the number of events occurring in a f" + + "ixed interval of time or space\nwhen events occur independently at a constant rat" + + "e.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class Measurement + public partial class PoissonDistribution : Distribution { - private double _valveOpenInterval; - - private double _valveOpenTime; + private PoissonDistributionParameters _distributionParameters; - private System.Collections.Generic.List _waterWeight; + private TruncationParameters _truncationParameters; - private int _repeatCount; + private ScalingParameters _scalingParameters; - public Measurement() + public PoissonDistribution() { - _waterWeight = new System.Collections.Generic.List(); + _distributionParameters = new PoissonDistributionParameters(); } - protected Measurement(Measurement other) + protected PoissonDistribution(PoissonDistribution other) : + base(other) { - _valveOpenInterval = other._valveOpenInterval; - _valveOpenTime = other._valveOpenTime; - _waterWeight = other._waterWeight; - _repeatCount = other._repeatCount; + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } /// - /// Time between two consecutive valve openings (s) + /// Parameters of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("valve_open_interval", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Time between two consecutive valve openings (s)")] - public double ValveOpenInterval + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public PoissonDistributionParameters DistributionParameters { get { - return _valveOpenInterval; + return _distributionParameters; } set { - _valveOpenInterval = value; + _distributionParameters = value; } } /// - /// Valve open interval (s) + /// Truncation parameters of the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("valve_open_time", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Valve open interval (s)")] - public double ValveOpenTime + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + [System.ComponentModel.DescriptionAttribute("Truncation parameters of the distribution")] + public TruncationParameters TruncationParameters { get { - return _valveOpenTime; + return _truncationParameters; } set { - _valveOpenTime = value; + _truncationParameters = value; } } /// - /// Weight of water delivered (g) + /// Scaling parameters of the distribution /// [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("water_weight", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Weight of water delivered (g)")] - public System.Collections.Generic.List WaterWeight + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + [System.ComponentModel.DescriptionAttribute("Scaling parameters of the distribution")] + public ScalingParameters ScalingParameters { get { - return _waterWeight; + return _scalingParameters; + } + set + { + _scalingParameters = value; + } + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new PoissonDistribution(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new PoissonDistribution(this)); + } + + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; + } + } + + + /// + /// Parameters for a Poisson distribution. + /// + ///Defined by the rate parameter (average number of events). + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Parameters for a Poisson distribution.\n\nDefined by the rate parameter (average nu" + + "mber of events).")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class PoissonDistributionParameters + { + + private string _family; + + private double _rate; + + public PoissonDistributionParameters() + { + _family = "Poisson"; + _rate = 1D; + } + + protected PoissonDistributionParameters(PoissonDistributionParameters other) + { + _family = other._family; + _rate = other._rate; + } + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family + { + get + { + return _family; } set { - _waterWeight = value; + _family = value; } } /// - /// Number of times the valve opened. + /// Rate parameter of the Poisson process that generates the distribution /// - [Newtonsoft.Json.JsonPropertyAttribute("repeat_count", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Number of times the valve opened.")] - public int RepeatCount + [Newtonsoft.Json.JsonPropertyAttribute("rate")] + [System.ComponentModel.DescriptionAttribute("Rate parameter of the Poisson process that generates the distribution")] + public double Rate { get { - return _repeatCount; + return _rate; } set { - _repeatCount = value; + _rate = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Measurement(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new PoissonDistributionParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new Measurement(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new PoissonDistributionParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("ValveOpenInterval = " + _valveOpenInterval + ", "); - stringBuilder.Append("ValveOpenTime = " + _valveOpenTime + ", "); - stringBuilder.Append("WaterWeight = " + _waterWeight + ", "); - stringBuilder.Append("RepeatCount = " + _repeatCount); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Rate = " + _rate); return true; } @@ -4124,42 +5273,6 @@ public override string ToString() } - /// - /// Microstep resolution available - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - public enum MicrostepResolution - { - - [System.Runtime.Serialization.EnumMemberAttribute(Value="0")] - Microstep8 = 0, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="1")] - Microstep16 = 1, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="2")] - Microstep32 = 2, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="3")] - Microstep64 = 3, - } - - - /// - /// Motor operation mode - /// - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - public enum MotorOperationMode - { - - [System.Runtime.Serialization.EnumMemberAttribute(Value="0")] - Quiet = 0, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="1")] - Dynamic = 1, - } - - /// /// Represents a rectangle defined by its top-left corner, width, and height. /// @@ -4296,72 +5409,99 @@ public override string ToString() } + /// + /// Defines the reward probability structure for a dynamic foraging task. + /// + ///Reward probabilities are defined as pairs (p_left, p_right) normalized by + ///base_reward_sum. Pairs are drawn from a family representing a difficulty level: + /// + /// Family 0: [[8, 1], [6, 1], [3, 1], [1, 1]] + /// Family 1: [[8, 1], [1, 1]] + /// Family 2: [[1.0, 0.0], [0.9, 0.1], [0.8, 0.2], [0.7, 0.3], [0.6, 0.4], [0.5, 0.5]] + /// Family 3: [[6, 1], [3, 1], [1, 1]] + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute(@"Defines the reward probability structure for a dynamic foraging task. + + Reward probabilities are defined as pairs (p_left, p_right) normalized by + base_reward_sum. Pairs are drawn from a family representing a difficulty level: + + Family 0: [[8, 1], [6, 1], [3, 1], [1, 1]] + Family 1: [[8, 1], [1, 1]] + Family 2: [[1.0, 0.0], [0.9, 0.1], [0.8, 0.2], [0.7, 0.3], [0.6, 0.4], [0.5, 0.5]] + Family 3: [[6, 1], [3, 1], [1, 1]]")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class Response + public partial class RewardProbabilityParameters { - private double _responseTime; + private double _baseRewardSum; - private double _rewardConsumeTime; + private System.Collections.Generic.List> _rewardPairs; - public Response() + public RewardProbabilityParameters() { - _responseTime = 1D; - _rewardConsumeTime = 3D; + _baseRewardSum = 0.8D; + _rewardPairs = new System.Collections.Generic.List>(); } - protected Response(Response other) + protected RewardProbabilityParameters(RewardProbabilityParameters other) { - _responseTime = other._responseTime; - _rewardConsumeTime = other._rewardConsumeTime; + _baseRewardSum = other._baseRewardSum; + _rewardPairs = other._rewardPairs; } - [Newtonsoft.Json.JsonPropertyAttribute("response_time")] - public double ResponseTime + /// + /// Total reward probability shared between the two sides. Each reward pair is normalized to sum to this value. + /// + [Newtonsoft.Json.JsonPropertyAttribute("base_reward_sum")] + [System.ComponentModel.DescriptionAttribute("Total reward probability shared between the two sides. Each reward pair is normal" + + "ized to sum to this value.")] + public double BaseRewardSum { get { - return _responseTime; + return _baseRewardSum; } set { - _responseTime = value; + _baseRewardSum = value; } } /// - /// Time of the no-lick period before trial end + /// List of (left, right) reward ratio pairs to sample from during block transitions. /// - [Newtonsoft.Json.JsonPropertyAttribute("reward_consume_time")] - [System.ComponentModel.DescriptionAttribute("Time of the no-lick period before trial end")] - public double RewardConsumeTime + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("reward_pairs")] + [System.ComponentModel.DescriptionAttribute("List of (left, right) reward ratio pairs to sample from during block transitions." + + " ")] + public System.Collections.Generic.List> RewardPairs { get { - return _rewardConsumeTime; + return _rewardPairs; } set { - _rewardConsumeTime = value; + _rewardPairs = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Response(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RewardProbabilityParameters(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new Response(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new RewardProbabilityParameters(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("ResponseTime = " + _responseTime + ", "); - stringBuilder.Append("RewardConsumeTime = " + _rewardConsumeTime); + stringBuilder.Append("BaseRewardSum = " + _baseRewardSum + ", "); + stringBuilder.Append("RewardPairs = " + _rewardPairs); return true; } @@ -4383,51 +5523,63 @@ public override string ToString() [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class RewardN + public partial class RewardSize { - private int _initialInactiveTrials; + private double _rightValueVolume; + + private double _leftValueVolume; - public RewardN() + public RewardSize() { - _initialInactiveTrials = 2; } - protected RewardN(RewardN other) + protected RewardSize(RewardSize other) { - _initialInactiveTrials = other._initialInactiveTrials; + _rightValueVolume = other._rightValueVolume; + _leftValueVolume = other._leftValueVolume; } - /// - /// Initial N trials of the active side where no bait will be be given. - /// - [Newtonsoft.Json.JsonPropertyAttribute("initial_inactive_trials")] - [System.ComponentModel.DescriptionAttribute("Initial N trials of the active side where no bait will be be given.")] - public int InitialInactiveTrials + [Newtonsoft.Json.JsonPropertyAttribute("right_value_volume", Required=Newtonsoft.Json.Required.Always)] + public double RightValueVolume + { + get + { + return _rightValueVolume; + } + set + { + _rightValueVolume = value; + } + } + + [Newtonsoft.Json.JsonPropertyAttribute("left_value_volume", Required=Newtonsoft.Json.Required.Always)] + public double LeftValueVolume { get { - return _initialInactiveTrials; + return _leftValueVolume; } set { - _initialInactiveTrials = value; + _leftValueVolume = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RewardN(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RewardSize(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new RewardN(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new RewardSize(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("InitialInactiveTrials = " + _initialInactiveTrials); + stringBuilder.Append("RightValueVolume = " + _rightValueVolume + ", "); + stringBuilder.Append("LeftValueVolume = " + _leftValueVolume); return true; } @@ -4446,86 +5598,83 @@ public override string ToString() } + /// + /// Container class for calibration models. In a future release these will be moved to the respective devices + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("Container class for calibration models. In a future release these will be moved t" + + "o the respective devices")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class RewardProbability + public partial class RigCalibration { - private double _baseRewardSum; - - private int _family; - - private int _pairsN; + private WaterValveCalibration _waterValveLeft; - public RewardProbability() - { - _baseRewardSum = 0.8D; - _family = 1; - _pairsN = 1; - } + private WaterValveCalibration _waterValveRight; - protected RewardProbability(RewardProbability other) + public RigCalibration() { - _baseRewardSum = other._baseRewardSum; - _family = other._family; - _pairsN = other._pairsN; + _waterValveLeft = new WaterValveCalibration(); + _waterValveRight = new WaterValveCalibration(); } - [Newtonsoft.Json.JsonPropertyAttribute("base_reward_sum")] - public double BaseRewardSum + protected RigCalibration(RigCalibration other) { - get - { - return _baseRewardSum; - } - set - { - _baseRewardSum = value; - } + _waterValveLeft = other._waterValveLeft; + _waterValveRight = other._waterValveRight; } - [Newtonsoft.Json.JsonPropertyAttribute("family")] - public int Family + /// + /// Left water valve calibration + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("water_valve_left", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Left water valve calibration")] + public WaterValveCalibration WaterValveLeft { get { - return _family; + return _waterValveLeft; } set { - _family = value; + _waterValveLeft = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("pairs_n")] - public int PairsN + /// + /// Right water valve calibration + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("water_valve_right", Required=Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DescriptionAttribute("Right water valve calibration")] + public WaterValveCalibration WaterValveRight { get { - return _pairsN; + return _waterValveRight; } set { - _pairsN = value; + _waterValveRight = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RewardProbability(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RigCalibration(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new RewardProbability(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new RigCalibration(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("BaseRewardSum = " + _baseRewardSum + ", "); - stringBuilder.Append("Family = " + _family + ", "); - stringBuilder.Append("PairsN = " + _pairsN); + stringBuilder.Append("WaterValveLeft = " + _waterValveLeft + ", "); + stringBuilder.Append("WaterValveRight = " + _waterValveRight); return true; } @@ -4544,163 +5693,181 @@ public override string ToString() } + /// + /// A scalar distribution that returns a constant value. + /// + ///Useful for fixed parameters that don't vary across trials or samples. + /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DescriptionAttribute("A scalar distribution that returns a constant value.\n\nUseful for fixed parameters" + + " that don\'t vary across trials or samples.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class RewardSize + public partial class Scalar : Distribution { - private double _rightValueVolume; + private ScalarDistributionParameter _distributionParameters; - private double _leftValueVolume; + private TruncationParameters2 _truncationParameters; - public RewardSize() + private ScalingParameters2 _scalingParameters; + + public Scalar() { - _rightValueVolume = 3D; - _leftValueVolume = 3D; + _distributionParameters = new ScalarDistributionParameter(); } - protected RewardSize(RewardSize other) + protected Scalar(Scalar other) : + base(other) { - _rightValueVolume = other._rightValueVolume; - _leftValueVolume = other._leftValueVolume; + _distributionParameters = other._distributionParameters; + _truncationParameters = other._truncationParameters; + _scalingParameters = other._scalingParameters; } - [Newtonsoft.Json.JsonPropertyAttribute("right_value_volume")] - public double RightValueVolume + /// + /// Parameters of the distribution + /// + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("distribution_parameters")] + [System.ComponentModel.DescriptionAttribute("Parameters of the distribution")] + public ScalarDistributionParameter DistributionParameters { get { - return _rightValueVolume; + return _distributionParameters; } set { - _rightValueVolume = value; + _distributionParameters = value; } } - [Newtonsoft.Json.JsonPropertyAttribute("left_value_volume")] - public double LeftValueVolume + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("truncation_parameters")] + public TruncationParameters2 TruncationParameters { get { - return _leftValueVolume; + return _truncationParameters; } set { - _leftValueVolume = value; + _truncationParameters = value; } } - public System.IObservable Generate() + [System.Xml.Serialization.XmlIgnoreAttribute()] + [Newtonsoft.Json.JsonPropertyAttribute("scaling_parameters")] + public ScalingParameters2 ScalingParameters { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RewardSize(this))); + get + { + return _scalingParameters; + } + set + { + _scalingParameters = value; + } } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Select(source, _ => new RewardSize(this)); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Scalar(this))); } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + public System.IObservable Generate(System.IObservable source) { - stringBuilder.Append("RightValueVolume = " + _rightValueVolume + ", "); - stringBuilder.Append("LeftValueVolume = " + _leftValueVolume); - return true; + return System.Reactive.Linq.Observable.Select(source, _ => new Scalar(this)); } - public override string ToString() + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) + if (base.PrintMembers(stringBuilder)) { - stringBuilder.Append(" "); + stringBuilder.Append(", "); } - stringBuilder.Append("}"); - return stringBuilder.ToString(); + stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); + stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); + stringBuilder.Append("ScalingParameters = " + _scalingParameters); + return true; } } /// - /// Container class for calibration models. In a future release these will be moved to the respective devices + /// Parameters for a scalar (constant) distribution. + /// + ///Represents a deterministic value that always returns the same number. /// [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [System.ComponentModel.DescriptionAttribute("Container class for calibration models. In a future release these will be moved t" + - "o the respective devices")] + [System.ComponentModel.DescriptionAttribute("Parameters for a scalar (constant) distribution.\n\nRepresents a deterministic valu" + + "e that always returns the same number.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class RigCalibration + public partial class ScalarDistributionParameter { - private WaterValveCalibration _waterValveLeft; + private string _family; - private WaterValveCalibration _waterValveRight; + private double _value; - public RigCalibration() + public ScalarDistributionParameter() { - _waterValveLeft = new WaterValveCalibration(); - _waterValveRight = new WaterValveCalibration(); + _family = "Scalar"; + _value = 0D; } - protected RigCalibration(RigCalibration other) + protected ScalarDistributionParameter(ScalarDistributionParameter other) { - _waterValveLeft = other._waterValveLeft; - _waterValveRight = other._waterValveRight; + _family = other._family; + _value = other._value; } - - /// - /// Left water valve calibration - /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("water_valve_left", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Left water valve calibration")] - public WaterValveCalibration WaterValveLeft + + [Newtonsoft.Json.JsonPropertyAttribute("family")] + public string Family { get { - return _waterValveLeft; + return _family; } set { - _waterValveLeft = value; + _family = value; } } /// - /// Right water valve calibration + /// The static value of the distribution /// - [System.Xml.Serialization.XmlIgnoreAttribute()] - [Newtonsoft.Json.JsonPropertyAttribute("water_valve_right", Required=Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DescriptionAttribute("Right water valve calibration")] - public WaterValveCalibration WaterValveRight + [Newtonsoft.Json.JsonPropertyAttribute("value")] + [System.ComponentModel.DescriptionAttribute("The static value of the distribution")] + public double Value { get { - return _waterValveRight; + return _value; } set { - _waterValveRight = value; + _value = value; } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new RigCalibration(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ScalarDistributionParameter(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new RigCalibration(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new ScalarDistributionParameter(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("WaterValveLeft = " + _waterValveLeft + ", "); - stringBuilder.Append("WaterValveRight = " + _waterValveRight); + stringBuilder.Append("Family = " + _family + ", "); + stringBuilder.Append("Value = " + _value); return true; } @@ -4846,8 +6013,8 @@ public partial class Session public Session() { - _aindBehaviorServicesPkgVersion = "0.13.0"; - _version = "0.13.0"; + _aindBehaviorServicesPkgVersion = "0.13.2"; + _version = "0.13.2"; _experimenter = new System.Collections.Generic.List(); _allowDirtyRepo = false; _skipHardwareValidation = false; @@ -6668,11 +7835,9 @@ public override string ToString() "obability of being sampled.")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class UniformDistribution + public partial class UniformDistribution : Distribution { - private string _family; - private UniformDistributionParameters _distributionParameters; private TruncationParameters _truncationParameters; @@ -6681,31 +7846,17 @@ public partial class UniformDistribution public UniformDistribution() { - _family = "Uniform"; _distributionParameters = new UniformDistributionParameters(); } - protected UniformDistribution(UniformDistribution other) + protected UniformDistribution(UniformDistribution other) : + base(other) { - _family = other._family; _distributionParameters = other._distributionParameters; _truncationParameters = other._truncationParameters; _scalingParameters = other._scalingParameters; } - [Newtonsoft.Json.JsonPropertyAttribute("family")] - public string Family - { - get - { - return _family; - } - set - { - _family = value; - } - } - /// /// Parameters of the distribution /// @@ -6770,27 +7921,17 @@ public System.IObservable Generate(System.IObserva return System.Reactive.Linq.Observable.Select(source, _ => new UniformDistribution(this)); } - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("Family = " + _family + ", "); + if (base.PrintMembers(stringBuilder)) + { + stringBuilder.Append(", "); + } stringBuilder.Append("DistributionParameters = " + _distributionParameters + ", "); stringBuilder.Append("TruncationParameters = " + _truncationParameters + ", "); stringBuilder.Append("ScalingParameters = " + _scalingParameters); return true; } - - public override string ToString() - { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) - { - stringBuilder.Append(" "); - } - stringBuilder.Append("}"); - return stringBuilder.ToString(); - } } @@ -6979,8 +8120,8 @@ public partial class VideoWriterFfmpeg : VideoWriter public VideoWriterFfmpeg() { _frameRate = 30; - _containerExtension = "mp4"; - _outputArguments = "-vf \"scale=out_color_matrix=bt709:out_range=full,format=bgr24,scale=out_range=full\" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p4 -rc vbr -cq 12 -b:v 0M -metadata author=\"Allen Institute for Neural Dynamics\" -maxrate 700M -bufsize 350M"; + _containerExtension = "mkv"; + _outputArguments = "-vf \"scale=out_range=full,setparams=range=full:colorspace=bt709:color_primaries=bt709:color_trc=linear\" -c:v h264_nvenc -pix_fmt yuv420p -color_range full -colorspace bt709 -color_trc linear -tune hq -preset p3 -rc vbr -cq 18 -b:v 0M -metadata author=\"Allen Institute for Neural Dynamics\" -maxrate 700M -bufsize 350M -f matroska -write_crc32 0"; _inputArguments = "-colorspace bt709 -color_primaries bt709 -color_range full -color_trc linear"; } @@ -7192,122 +8333,6 @@ protected override bool PrintMembers(System.Text.StringBuilder stringBuilder) } - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] - [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class Warmup - { - - private int _minTrial; - - private double _maxChoiceRatioBias; - - private double _minFinishRatio; - - private int _windowsize; - - public Warmup() - { - _minTrial = 50; - _maxChoiceRatioBias = 0.1D; - _minFinishRatio = 0.8D; - _windowsize = 20; - } - - protected Warmup(Warmup other) - { - _minTrial = other._minTrial; - _maxChoiceRatioBias = other._maxChoiceRatioBias; - _minFinishRatio = other._minFinishRatio; - _windowsize = other._windowsize; - } - - [Newtonsoft.Json.JsonPropertyAttribute("min_trial")] - public int MinTrial - { - get - { - return _minTrial; - } - set - { - _minTrial = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("max_choice_ratio_bias")] - public double MaxChoiceRatioBias - { - get - { - return _maxChoiceRatioBias; - } - set - { - _maxChoiceRatioBias = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("min_finish_ratio")] - public double MinFinishRatio - { - get - { - return _minFinishRatio; - } - set - { - _minFinishRatio = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("windowsize")] - public int Windowsize - { - get - { - return _windowsize; - } - set - { - _windowsize = value; - } - } - - public System.IObservable Generate() - { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Warmup(this))); - } - - public System.IObservable Generate(System.IObservable source) - { - return System.Reactive.Linq.Observable.Select(source, _ => new Warmup(this)); - } - - protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) - { - stringBuilder.Append("MinTrial = " + _minTrial + ", "); - stringBuilder.Append("MaxChoiceRatioBias = " + _maxChoiceRatioBias + ", "); - stringBuilder.Append("MinFinishRatio = " + _minFinishRatio + ", "); - stringBuilder.Append("Windowsize = " + _windowsize); - return true; - } - - public override string ToString() - { - System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); - stringBuilder.Append(GetType().Name); - stringBuilder.Append(" { "); - if (PrintMembers(stringBuilder)) - { - stringBuilder.Append(" "); - } - stringBuilder.Append("}"); - return stringBuilder.ToString(); - } - } - - /// /// Represents a water valve calibration. /// @@ -7318,7 +8343,7 @@ public override string ToString() public partial class WaterValveCalibration { - private System.DateTimeOffset _date; + private System.DateTimeOffset? _date; private System.Collections.Generic.List _measurements; @@ -7354,7 +8379,7 @@ protected WaterValveCalibration(WaterValveCalibration other) [System.Xml.Serialization.XmlIgnoreAttribute()] [Newtonsoft.Json.JsonPropertyAttribute("date")] [System.ComponentModel.DescriptionAttribute("Date of the calibration")] - public System.DateTimeOffset Date + public System.DateTimeOffset? Date { get { @@ -7366,22 +8391,6 @@ public System.DateTimeOffset Date } } - [Newtonsoft.Json.JsonIgnoreAttribute()] - [System.ComponentModel.BrowsableAttribute(false)] - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.Xml.Serialization.XmlElementAttribute("Date")] - public string DateXml - { - get - { - return _date.ToString("o"); - } - set - { - _date = System.DateTimeOffset.Parse(value); - } - } - /// /// List of measurements /// @@ -7791,126 +8800,33 @@ public override string ToString() [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "type")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class AindBehaviorDynamicForagingTaskLogicAutoWater + public partial class Anonymous { - private AindBehaviorDynamicForagingTaskLogicAutoWaterAutoWaterType _autoWaterType; - - private double _multiplier; - - private int _unrewarded; - - private int _ignored; - - private bool _includeReward; - - public AindBehaviorDynamicForagingTaskLogicAutoWater() - { - _autoWaterType = AindBehaviorDynamicForagingTaskLogicAutoWaterAutoWaterType.Natural; - _multiplier = 0.8D; - _unrewarded = 200; - _ignored = 100; - _includeReward = false; - } - - protected AindBehaviorDynamicForagingTaskLogicAutoWater(AindBehaviorDynamicForagingTaskLogicAutoWater other) - { - _autoWaterType = other._autoWaterType; - _multiplier = other._multiplier; - _unrewarded = other._unrewarded; - _ignored = other._ignored; - _includeReward = other._includeReward; - } - - [Newtonsoft.Json.JsonPropertyAttribute("auto_water_type")] - public AindBehaviorDynamicForagingTaskLogicAutoWaterAutoWaterType AutoWaterType - { - get - { - return _autoWaterType; - } - set - { - _autoWaterType = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("multiplier")] - public double Multiplier - { - get - { - return _multiplier; - } - set - { - _multiplier = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("unrewarded")] - public int Unrewarded - { - get - { - return _unrewarded; - } - set - { - _unrewarded = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("ignored")] - public int Ignored + public Anonymous() { - get - { - return _ignored; - } - set - { - _ignored = value; - } } - /// - /// Include auto water in total rewards. - /// - [Newtonsoft.Json.JsonPropertyAttribute("include_reward")] - [System.ComponentModel.DescriptionAttribute("Include auto water in total rewards.")] - public bool IncludeReward + protected Anonymous(Anonymous other) { - get - { - return _includeReward; - } - set - { - _includeReward = value; - } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new AindBehaviorDynamicForagingTaskLogicAutoWater(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Anonymous(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new AindBehaviorDynamicForagingTaskLogicAutoWater(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new Anonymous(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("AutoWaterType = " + _autoWaterType + ", "); - stringBuilder.Append("Multiplier = " + _multiplier + ", "); - stringBuilder.Append("Unrewarded = " + _unrewarded + ", "); - stringBuilder.Append("Ignored = " + _ignored + ", "); - stringBuilder.Append("IncludeReward = " + _includeReward); - return true; + return false; } public override string ToString() @@ -7929,104 +8845,33 @@ public override string ToString() [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "family")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater + public partial class InterTrialIntervalDuration { - private AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWaterAutoWaterType _autoWaterType; - - private double _multiplier; - - private int _unrewarded; - - private int _ignored; - - public AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater() - { - _autoWaterType = AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWaterAutoWaterType.Natural; - _multiplier = 0.8D; - _unrewarded = 200; - _ignored = 100; - } - - protected AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater(AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater other) - { - _autoWaterType = other._autoWaterType; - _multiplier = other._multiplier; - _unrewarded = other._unrewarded; - _ignored = other._ignored; - } - - [Newtonsoft.Json.JsonPropertyAttribute("auto_water_type")] - public AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWaterAutoWaterType AutoWaterType - { - get - { - return _autoWaterType; - } - set - { - _autoWaterType = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("multiplier")] - public double Multiplier - { - get - { - return _multiplier; - } - set - { - _multiplier = value; - } - } - - [Newtonsoft.Json.JsonPropertyAttribute("unrewarded")] - public int Unrewarded + public InterTrialIntervalDuration() { - get - { - return _unrewarded; - } - set - { - _unrewarded = value; - } } - [Newtonsoft.Json.JsonPropertyAttribute("ignored")] - public int Ignored + protected InterTrialIntervalDuration(InterTrialIntervalDuration other) { - get - { - return _ignored; - } - set - { - _ignored = value; - } } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new InterTrialIntervalDuration(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWater(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new InterTrialIntervalDuration(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) { - stringBuilder.Append("AutoWaterType = " + _autoWaterType + ", "); - stringBuilder.Append("Multiplier = " + _multiplier + ", "); - stringBuilder.Append("Unrewarded = " + _unrewarded + ", "); - stringBuilder.Append("Ignored = " + _ignored); - return true; + return false; } public override string ToString() @@ -8045,28 +8890,28 @@ public override string ToString() [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "type")] + [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "family")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] [Bonsai.CombinatorAttribute(MethodName="Generate")] - public partial class Anonymous + public partial class BlockLen { - public Anonymous() + public BlockLen() { } - protected Anonymous(Anonymous other) + protected BlockLen(BlockLen other) { } - public System.IObservable Generate() + public System.IObservable Generate() { - return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new Anonymous(this))); + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new BlockLen(this))); } - public System.IObservable Generate(System.IObservable source) + public System.IObservable Generate(System.IObservable source) { - return System.Reactive.Linq.Observable.Select(source, _ => new Anonymous(this)); + return System.Reactive.Linq.Observable.Select(source, _ => new BlockLen(this)); } protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) @@ -8091,43 +8936,102 @@ public override string ToString() [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum AindDynamicForagingTaskParametersRandomness + public enum BehaviorStabilityParametersBehaviorEvaluationMode { - [System.Runtime.Serialization.EnumMemberAttribute(Value="Exponential")] - Exponential = 0, + [System.Runtime.Serialization.EnumMemberAttribute(Value="end")] + End = 0, - [System.Runtime.Serialization.EnumMemberAttribute(Value="Even")] - Even = 1, + [System.Runtime.Serialization.EnumMemberAttribute(Value="anytime")] + Anytime = 1, } [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum AutoBlockAdvancedBlockAuto + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class TruncationParameters2 { - [System.Runtime.Serialization.EnumMemberAttribute(Value="now")] - Now = 0, + public TruncationParameters2() + { + } + + protected TruncationParameters2(TruncationParameters2 other) + { + } + + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new TruncationParameters2(this))); + } + + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new TruncationParameters2(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + return false; + } - [System.Runtime.Serialization.EnumMemberAttribute(Value="once")] - Once = 1, + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } } [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum CoupledTrialGeneratorSpecBehaviorEvaluationMode + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Source)] + [Bonsai.CombinatorAttribute(MethodName="Generate")] + public partial class ScalingParameters2 { - [System.Runtime.Serialization.EnumMemberAttribute(Value="ignore")] - Ignore = 0, + public ScalingParameters2() + { + } + + protected ScalingParameters2(ScalingParameters2 other) + { + } - [System.Runtime.Serialization.EnumMemberAttribute(Value="end")] - End = 1, + public System.IObservable Generate() + { + return System.Reactive.Linq.Observable.Defer(() => System.Reactive.Linq.Observable.Return(new ScalingParameters2(this))); + } - [System.Runtime.Serialization.EnumMemberAttribute(Value="anytime")] - Anytime = 2, + public System.IObservable Generate(System.IObservable source) + { + return System.Reactive.Linq.Observable.Select(source, _ => new ScalingParameters2(this)); + } + + protected virtual bool PrintMembers(System.Text.StringBuilder stringBuilder) + { + return false; + } + + public override string ToString() + { + System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); + stringBuilder.Append(GetType().Name); + stringBuilder.Append(" { "); + if (PrintMembers(stringBuilder)) + { + stringBuilder.Append(" "); + } + stringBuilder.Append("}"); + return stringBuilder.ToString(); + } } @@ -8170,38 +9074,6 @@ public enum WaveformType } - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum AindBehaviorDynamicForagingTaskLogicAutoWaterAutoWaterType - { - - [System.Runtime.Serialization.EnumMemberAttribute(Value="Natural")] - Natural = 0, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="Both")] - Both = 1, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="High pro")] - HighPro = 2, - } - - - [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum AindBehaviorDynamicForagingTaskLogicTrialGeneratorsCoupledTrialGeneratorAutoWaterAutoWaterType - { - - [System.Runtime.Serialization.EnumMemberAttribute(Value="Natural")] - Natural = 0, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="Both")] - Both = 1, - - [System.Runtime.Serialization.EnumMemberAttribute(Value="High pro")] - HighPro = 2, - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.9.0.0 (Newtonsoft.Json v13.0.0.0)")] [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = true)] internal class JsonInheritanceAttribute : System.Attribute @@ -8339,6 +9211,55 @@ private string GetSubtypeDiscriminator(System.Type objectType) } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DefaultPropertyAttribute("Type")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Combinator)] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + public partial class MatchDistribution : Bonsai.Expressions.SingleArgumentExpressionBuilder + { + + public Bonsai.Expressions.TypeMapping Type { get; set; } + + public override System.Linq.Expressions.Expression Build(System.Collections.Generic.IEnumerable arguments) + { + var typeMapping = Type; + var returnType = typeMapping != null ? typeMapping.GetType().GetGenericArguments()[0] : typeof(Distribution); + return System.Linq.Expressions.Expression.Call( + typeof(MatchDistribution), + "Process", + new System.Type[] { returnType }, + System.Linq.Enumerable.Single(arguments)); + } + + + private static System.IObservable Process(System.IObservable source) + where TResult : Distribution + { + return System.Reactive.Linq.Observable.Create(observer => + { + var sourceObserver = System.Reactive.Observer.Create( + value => + { + var match = value as TResult; + if (match != null) observer.OnNext(match); + }, + observer.OnError, + observer.OnCompleted); + return System.ObservableExtensions.SubscribeSafe(source, sourceObserver); + }); + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] [System.ComponentModel.DefaultPropertyAttribute("Type")] [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Combinator)] @@ -8461,6 +9382,84 @@ private static System.IObservable Process(System.IObservable arguments) + { + var typeMapping = Type; + var returnType = typeMapping != null ? typeMapping.GetType().GetGenericArguments()[0] : typeof(InterTrialIntervalDuration); + return System.Linq.Expressions.Expression.Call( + typeof(MatchInterTrialIntervalDuration), + "Process", + new System.Type[] { returnType }, + System.Linq.Enumerable.Single(arguments)); + } + + + private static System.IObservable Process(System.IObservable source) + where TResult : InterTrialIntervalDuration + { + return System.Reactive.Linq.Observable.Create(observer => + { + var sourceObserver = System.Reactive.Observer.Create( + value => + { + var match = value as TResult; + if (match != null) observer.OnNext(match); + }, + observer.OnError, + observer.OnCompleted); + return System.ObservableExtensions.SubscribeSafe(source, sourceObserver); + }); + } + } + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Bonsai.Sgen", "0.7.2.0 (Newtonsoft.Json v13.0.0.0)")] + [System.ComponentModel.DefaultPropertyAttribute("Type")] + [Bonsai.WorkflowElementCategoryAttribute(Bonsai.ElementCategory.Combinator)] + public partial class MatchBlockLen : Bonsai.Expressions.SingleArgumentExpressionBuilder + { + + public Bonsai.Expressions.TypeMapping Type { get; set; } + + public override System.Linq.Expressions.Expression Build(System.Collections.Generic.IEnumerable arguments) + { + var typeMapping = Type; + var returnType = typeMapping != null ? typeMapping.GetType().GetGenericArguments()[0] : typeof(BlockLen); + return System.Linq.Expressions.Expression.Call( + typeof(MatchBlockLen), + "Process", + new System.Type[] { returnType }, + System.Linq.Enumerable.Single(arguments)); + } + + + private static System.IObservable Process(System.IObservable source) + where TResult : BlockLen + { + return System.Reactive.Linq.Observable.Create(observer => + { + var sourceObserver = System.Reactive.Observer.Create( + value => + { + var match = value as TResult; + if (match != null) observer.OnNext(match); + }, + observer.OnError, + observer.OnCompleted); + return System.ObservableExtensions.SubscribeSafe(source, sourceObserver); + }); + } + } + + /// /// Serializes a sequence of data model objects into JSON strings. /// @@ -8509,11 +9508,6 @@ public System.IObservable Process(System.IObservable(source); } - public System.IObservable Process(System.IObservable source) - { - return Process(source); - } - public System.IObservable Process(System.IObservable source) { return Process(source); @@ -8524,9 +9518,29 @@ public System.IObservable Process(System.IObservable source) return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } public System.IObservable Process(System.IObservable source) @@ -8544,14 +9558,19 @@ public System.IObservable Process(System.IObservable(source); } + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + public System.IObservable Process(System.IObservable source) { return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } public System.IObservable Process(System.IObservable source) @@ -8569,6 +9588,16 @@ public System.IObservable Process(System.IObservable(source); } + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + public System.IObservable Process(System.IObservable source) { return Process(source); @@ -8599,9 +9628,14 @@ public System.IObservable Process(System.IObservable(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } public System.IObservable Process(System.IObservable source) @@ -8614,24 +9648,44 @@ public System.IObservable Process(System.IObservable source return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } public System.IObservable Process(System.IObservable source) @@ -8644,6 +9698,16 @@ public System.IObservable Process(System.IObservable sou return Process(source); } + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + public System.IObservable Process(System.IObservable source) { return Process(source); @@ -8714,11 +9778,6 @@ public System.IObservable Process(System.IObservable return Process(source); } - public System.IObservable Process(System.IObservable source) - { - return Process(source); - } - public System.IObservable Process(System.IObservable source) { return Process(source); @@ -8734,19 +9793,29 @@ public System.IObservable Process(System.IObservable source) return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) + { + return Process(source); + } + + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); } - public System.IObservable Process(System.IObservable source) + public System.IObservable Process(System.IObservable source) { - return Process(source); + return Process(source); + } + + public System.IObservable Process(System.IObservable source) + { + return Process(source); } } @@ -8764,33 +9833,46 @@ public System.IObservable Process(System.IObservable source) [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] @@ -8805,13 +9887,14 @@ public System.IObservable Process(System.IObservable source) [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] - [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] + [System.Xml.Serialization.XmlIncludeAttribute(typeof(Bonsai.Expressions.TypeMapping))] public partial class DeserializeFromJson : Bonsai.Expressions.SingleArgumentExpressionBuilder { diff --git a/src/Extensions/OperationControl.bonsai b/src/Extensions/OperationControl.bonsai index ba64c3d..445e470 100644 --- a/src/Extensions/OperationControl.bonsai +++ b/src/Extensions/OperationControl.bonsai @@ -1050,7 +1050,7 @@ - 0 + 96000 @@ -1196,7 +1196,7 @@ - 0 + 96000 diff --git a/src/Extensions/SpinnakerCameraControllerSaturationVisualizer.bonsai b/src/Extensions/SpinnakerCameraControllerSaturationVisualizer.bonsai index 41a522b..064bdaa 100644 --- a/src/Extensions/SpinnakerCameraControllerSaturationVisualizer.bonsai +++ b/src/Extensions/SpinnakerCameraControllerSaturationVisualizer.bonsai @@ -36,9 +36,7 @@ SelectedControllerCamera - - - + SelectedControllerCamera @@ -120,9 +118,7 @@ 254 1 - - - + false diff --git a/src/Extensions/TaskEngine.bonsai b/src/Extensions/TaskEngine.bonsai index 19e816e..3043982 100644 --- a/src/Extensions/TaskEngine.bonsai +++ b/src/Extensions/TaskEngine.bonsai @@ -5,9 +5,9 @@ xmlns:p1="clr-namespace:AindDynamicForagingDataSchema;assembly=Extensions" xmlns:py="clr-namespace:Bonsai.Scripting.Python;assembly=Bonsai.Scripting.Python" xmlns:p2="clr-namespace:;assembly=Extensions" + xmlns:scr="clr-namespace:Bonsai.Scripting.Expressions;assembly=Bonsai.Scripting.Expressions" xmlns:p3="clr-namespace:AllenNeuralDynamics.Core;assembly=AllenNeuralDynamics.Core" xmlns:harp="clr-namespace:Bonsai.Harp;assembly=Bonsai.Harp" - xmlns:scr="clr-namespace:Bonsai.Scripting.Expressions;assembly=Bonsai.Scripting.Expressions" xmlns="https://bonsai-rx.org/2018/workflow"> @@ -18,6 +18,13 @@ ThisTrial + + ThisTrial + + + + GlobalTrial + @@ -56,12 +63,94 @@ trial_generator + + SampleNextTrial + + + + + + + + trial_generator + + + + + next + true + + + + + + + + + + + + + + + + + - ThisTrial + GlobalAutoWaterState + + + SampledGlobalAutoWaterState + + + + + + + + + ResetGlobalAutoWaterState + + + + Source1 + + + GlobalAutoWaterState + + + + + + + 1 + + + + Item2 + + + Reset + it.Reset() + + + GlobalAutoWaterState + + + + + + + + + + + + + - - GlobalTrial + ThisTrial ThisTrial @@ -1037,6 +1126,11 @@ + + + 1 + + Item2 @@ -1044,6 +1138,9 @@ Reset it.Reset() + + GlobalAutoWaterState + @@ -1052,6 +1149,8 @@ + + @@ -1209,24 +1308,31 @@ - - - + + - + + - + + - + - + + + + + + + diff --git a/src/Extensions/Visualizers.bonsai b/src/Extensions/Visualizers.bonsai index e5fe0d1..fdf11fe 100644 --- a/src/Extensions/Visualizers.bonsai +++ b/src/Extensions/Visualizers.bonsai @@ -7,203 +7,247 @@ xmlns:gui="clr-namespace:Bonsai.Gui;assembly=Bonsai.Gui" xmlns:p3="clr-namespace:AllenNeuralDynamics.Core.Design;assembly=AllenNeuralDynamics.Core.Design" xmlns:scr="clr-namespace:Bonsai.Scripting.Expressions;assembly=Bonsai.Scripting.Expressions" + xmlns:ui="clr-namespace:Bonsai.Design;assembly=Bonsai.Design" xmlns="https://bonsai-rx.org/2018/workflow"> - - Source1 + + + 0 + - - GlobalTrialOutcome - - - 16 - - - - SoftwareEvent - - - IsRightLickEvent - - + + TrialPlots - - Source1 + + GlobalTrialOutcome - - Value + + 16 - - - - - - - - - - - LickRight - - - - IsRightLickEvent - - - - - - Source1 + + + SoftwareEvent + + + IsRightLickEvent + + + + + + Source1 + + + Value + + + + + + + + - - Value + + + LickRight + + + + IsRightLickEvent + + + + + + Source1 + + + Value + + + + + + + + + + + + + + LickLeft + + + + GiveRewardRight + + + + + + Source1 + + + + + + + + + + + WaterRight + + + + GiveRewardRight + + + + + Source1 + + + + + + + + + + + WaterLeft + + + + + + + 16 + 3600 + + + QuiscentPeriod + Gold + 0.3 + + + ResponsePeriod + SandyBrown + 0.3 + + + RewardConsumptionPeriod + RosyBrown + 0.3 + + + ItiPeriod + Green + 0.3 + + + + + LickLeft + Red + 0.9 + 6 + Down + + + LickRight + Blue + 0.1 + 6 + Up + + + IsRightTriggerQuickRetract + DarkCyan + 0.5 + 6 + Plus + + + DeliverSecondaryReinforcer + Sienna + 0.5 + 6 + Plus + + + WaterRight + Blue + 0.2 + 6 + Circle + + + WaterLeft + Red + 0.8 + 6 + Circle + + + + 5 + + + + true + true + 1 + 2 + + + + - + + + + + + + + + + + + + + + + + + + - - - LickLeft - - - - - - - 16 - 30 - - - QuiscentPeriod - Gold - 0.3 - - - ResponsePeriod - SandyBrown - 0.3 - - - RewardConsumptionPeriod - WhiteSmoke - 0.3 - - - ItiPeriod - Green - 0.3 - - - - - LickLeft - Red - 0.9 - 6 - Down - - - LickRight - Blue - 0.1 - 6 - Up - - - IsRightTriggerQuickRetract - DarkCyan - 0.5 - 6 - Plus - - - DeliverSecondaryReinforcer - Sienna - 0.5 - 6 - Plus - - - GiveRewardRight - DarkViolet - 0.5 - 6 - Circle - - - QuiscentPeriod - 5 - - - - - true - true - 1 - 2 - - - - - - GlobalTrial - - - 2 - 16 - - - - - true - true - 1 - 1 - - - - - - - - DynamicForaging - true - true - 2 - 1 - - - Percent - 0.7 - - - Percent - 0.3 - - - - - TriggeredCamerasStream - - - + + + LauncherControl @@ -211,9 +255,7 @@ - - - + ExperimentState @@ -232,9 +274,7 @@ StartExperimentToggleButton - - - + End true @@ -244,9 +284,7 @@ EndExperimentButton - - - + LauncherControl true @@ -321,303 +359,546 @@ - + + true + true + - - GiveWaterUI + + true + true + 2 + 1 + + + + + + + + true + true + 1 + 2 + + + + + + + + + + + ManualOverrides - - Left - true - true - 💧◀ - - - TriggerLeft + + GiveWaterUI - - Source1 + + Left + true + true + 💧◀ - - - false - + + TriggerLeft + + + + Source1 + + + + false + + + + GiveRewardRight + + + + + + + + + + + + + Right + true + true + 💧▶ - - GiveRewardRight + + TriggerRight + + + + Source1 + + + + true + + + + GiveRewardRight + + + + + + + + + + + + + ManualWater + true + true + 2 + 1 + + + Percent + 0.5 + + + Percent + 0.5 + + + + - + + + + + - - Right + + Give water true true - 💧▶ + Give water - - TriggerRight + + + ForceAutoWater - - Source1 + + GlobalAutoWaterState - - - true - + + !it.IsLeft - - GiveRewardRight + + + + - - - - - - - - - - - - ManualWater - true - true - 1 - 1 - - - Percent - 0.5 - - - Percent - 0.5 - - - - - - - - - - - - - - - - - - - - - ForceAutoWater - - - - GlobalAutoWaterState - - - !it.IsLeft - - - - - - - - SetLeft - true - true - 🎣◀ - - - UpdateGlobalState - - - - Source1 + + SetLeft + true + true + 🎣◀ + + UpdateGlobalState + + + + Source1 + + + GlobalAutoWaterState + + + + + + Item2 + + + + + + it.SetLeft() + + + GlobalAutoWaterState + + + + + + + + + + + + + + + GlobalAutoWaterState - - + + !it.IsRight - - Item2 + + + + + + + SetRight + true + true + 🎣▶ - - + + UpdateGlobalState + + + + Source1 + + + GlobalAutoWaterState + + + + + + Item2 + + + + + + it.SetRight() + + + GlobalAutoWaterState + + + + + + + + + + + + + + + + + GlobalAutoWaterState - it.SetLeft() + it.HasValue - - - 1 - + + + + - - GlobalAutoWaterState + + Reset + false + true + + + + UpdateGlobalState + + + + Source1 + + + GlobalAutoWaterState + + + + + + Item2 + + + + + + it.Reset() + + + GlobalAutoWaterState + + + + + + + + + + + + + + + + + ForceAutoWater + true + true + 3 + 1 + + + - - + + - - - + + + + + + + + + + + + + + - - GlobalAutoWaterState - - - !it.IsRight - - - - - - - - SetRight + + Arm water true true - 🎣▶ + Arm water - - UpdateGlobalState + + + OffsetControl - - Source1 - - - GlobalAutoWaterState + + + 0.05 + - + + 1 + - - Item2 + + BumpSize - - + + ManipulatorBiasTracker - - it.SetRight() + + ManipulatorBiasTracker 1 - - GlobalAutoWaterState + + - - - - - - - - - - - - - - - - - GlobalAutoWaterState - - - it.HasValue - - - - - - - - Reset - true - true - - - - UpdateGlobalState - - - - Source1 + + + + + + - - GlobalAutoWaterState + + true + true + 0.15 - - + + + Left + true + true + ◀️ - - Item2 + + BumpLeft + + + + Source1 + + + BumpSize + + + + + + Item2 + + + + -1 + + + + ManualSpoutDelta + + + + + + + + + + + + - - + + + Right + true + true + - - it.Reset() + + BumpRight + + + + Source1 + + + BumpSize + + + + + + Item2 + + + ManualSpoutDelta + + + + + + + + + + + - - - 1 - + + + true + true + 2 + 1 + + + - - GlobalAutoWaterState + + + true + true + Microsoft Sans Serif, 22.125pt + 1 + 2 + + + - - - - - - + + + + + + + + + + + + + + + + + + + + Spout offset + true + true + Spout offset + + - ForceAutoWater + Manual Control true true - 3 - 1 + Microsoft Sans Serif, 36pt + 1 + 3 @@ -628,77 +909,107 @@ - + - + - + - + - - - - - - + + true + true + 1 + 2 + + + + + + + true + true + 2 + 1 + + + Percent + 0.75 + + + Percent + 0.25 + + + + + + + + GlobalTrial + + + 2 + 16 + + true true + - - - - + + + + - + - - - + + + - - + + - + - - - + + + - - - - - - - - - - - - - + + + + + DynamicForaging + true + + + + + \ No newline at end of file diff --git a/src/aind_behavior_dynamic_foraging/task_logic/__init__.py b/src/aind_behavior_dynamic_foraging/task_logic/__init__.py index f3b2e8f..2820d1f 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/__init__.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/__init__.py @@ -1,4 +1,4 @@ -from typing import Literal, Optional +from typing import Literal from aind_behavior_services.task import Task, TaskParameters from pydantic import BaseModel, Field @@ -10,76 +10,10 @@ from . import trial_models as trial_models from .trial_generators import IntegrationTestTrialGeneratorSpec, TrialGeneratorSpec -RANDOMNESSES = Literal["Exponential", "Even"] -AUTO_WATER_MODES = Literal["Natural", "Both", "High pro"] - - -class BlockParameters(BaseModel): - # Block length - min: int = Field(default=20, title="Block length (min)") - max: int = Field(default=60, title="Block length (max)") - beta: int = Field(default=20, title="Block length (beta)") - min_reward: int = Field(default=1, title="Minimal rewards in a block to switch") - - -class RewardProbability(BaseModel): - base_reward_sum: float = Field(default=0.8, title="Sum of p_reward") - family: int = Field(default=1, title="Reward family") # Should be explicit here - pairs_n: int = Field(default=1, title="Number of pairs") # Should be explicit here - - -class DelayPeriod(BaseModel): - min: float = Field(default=0.0, title="Delay period (min) ") - max: float = Field(default=1.0, title="Delay period (max) ") - beta: float = Field(default=1.0, title="Delay period (beta)") - - -class AutoWater(BaseModel): - auto_water_type: AUTO_WATER_MODES = Field(default="Natural", title="Auto water mode") - multiplier: float = Field(default=0.8, title="Multiplier for auto reward") - unrewarded: int = Field(default=200, title="Number of unrewarded trials before auto water") - ignored: int = Field(default=100, title="Number of ignored trials before auto water") - include_reward: bool = Field(default=False, description="Include auto water in total rewards.") - - -class InterTrialInterval(BaseModel): - min: float = Field(default=1.0, title="ITI (min)") - max: float = Field(default=8.0, title="ITI (max)") - beta: float = Field(default=2.0, title="ITI (beta)") - increase: float = Field(default=0.0, title="ITI increase") # TODO: not implemented in the GUI?? - - -class Response(BaseModel): - response_time: float = Field(default=1.0, title="Response time") - reward_consume_time: float = Field( - default=3.0, title="Reward consume time", description="Time of the no-lick period before trial end" - ) - - -class AutoBlock(BaseModel): - advanced_block_auto: Literal["now", "once"] = Field(default="now", title="Auto block mode") - switch_thr: float = Field(default=0.5, title="Switch threshold for auto block") - points_in_a_row: int = Field(default=5, title="Points in a row for auto block") - class RewardSize(BaseModel): - right_value_volume: float = Field(default=3.00, title="Right reward size (uL)") - left_value_volume: float = Field(default=3.00, title="Left reward size (uL)") - - -class Warmup(BaseModel): - min_trial: int = Field(default=50, title="Warmup finish criteria: minimal trials") - max_choice_ratio_bias: float = Field( - default=0.1, title="Warmup finish criteria: maximal choice ratio bias from 0.5" - ) - min_finish_ratio: float = Field(default=0.8, title="Warmup finish criteria: minimal finish ratio") - windowsize: int = Field(default=20, title="Warmup finish criteria: window size to compute the bias and ratio") - - -class RewardN(BaseModel): - initial_inactive_trials: int = Field( - default=2, description="Initial N trials of the active side where no bait will be be given." - ) + right_value_volume: float = Field(title="Right reward size (uL)") + left_value_volume: float = Field(title="Left reward size (uL)") # ==================== MAIN TASK LOGIC CLASSES ==================== @@ -94,33 +28,9 @@ class AindDynamicForagingTaskParameters(TaskParameters): and numerical updaters for dynamic parameter modification. """ - block_parameters: BlockParameters = Field( - default=BlockParameters(), description="Parameters describing block conditions." - ) - reward_probability: RewardProbability = Field( - default=RewardProbability(), description="Parameters describing reward_probability." - ) - uncoupled_reward: Optional[list[float]] = Field( - default=[0.1, 0.3, 0.7], title="Uncoupled reward", min_length=3, max_length=3 - ) # For uncoupled tasks only - randomness: RANDOMNESSES = Field(default="Exponential", title="Randomness mode") - delay_period: DelayPeriod = Field(default=DelayPeriod(), description="Parameters describing delay period.") - reward_delay: float = Field(default=0, title="Reward delay (sec)") - auto_water: Optional[AutoWater] = Field(default=None, description="Parameters describing auto water.") - inter_trial_interval: InterTrialInterval = Field( - default_factory=InterTrialInterval, validate_default=True, description="Parameters describing iti." - ) - response_time: Response = Field(default=Response(), description="Parameters describing response time.") - auto_block: Optional[AutoBlock] = Field( - default=None, description="Parameters describing auto advancement to next block." - ) - reward_size: RewardSize = Field(default=RewardSize(), description="Parameters describing reward size.") - warmup: Optional[Warmup] = Field(default=None, description="Parameters describing warmup.") - no_response_trial_addition: bool = Field( - default=True, description="Add one trial to the block length on both lickspouts." + reward_size: RewardSize = Field( + default=RewardSize(left_value_volume=3, right_value_volume=3), description="Parameters describing reward size." ) - reward_n: Optional[RewardN] = Field(default=None) - lick_spout_retraction: Optional[bool] = Field(default=False, description="Lick spout retraction enabled.") trial_generator: TrialGeneratorSpec = Field( default=IntegrationTestTrialGeneratorSpec(), description="Trial generator model for generating trials in the task.", diff --git a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/_base.py b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/_base.py index 9406f7c..2405daa 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/_base.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/_base.py @@ -22,5 +22,5 @@ class ITrialGenerator(Protocol): def next(self) -> Trial | None: """Return the next trial to run. Return None if there are no more trials to run.""" - def update(self, outcome: TrialOutcome) -> None: + def update(self, outcome: TrialOutcome | str) -> None: """Update the trial generator with the outcome of the previous trial.""" 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 new file mode 100644 index 0000000..1010f42 --- /dev/null +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/block_based_trial_generator.py @@ -0,0 +1,257 @@ +import logging +import random +from abc import ABC, abstractmethod +from typing import Literal, Optional, Union + +import numpy as np +from aind_behavior_services.task.distributions import ( + Distribution, + ExponentialDistribution, + ExponentialDistributionParameters, + TruncationParameters, + UniformDistribution, +) +from aind_behavior_services.task.distributions_utils import draw_sample +from pydantic import BaseModel, Field + +from ..trial_models import Trial +from ._base import BaseTrialGeneratorSpecModel, ITrialGenerator + +logger = logging.getLogger(__name__) + + +class RewardProbabilityParameters(BaseModel): + """Defines the reward probability structure for a dynamic foraging task. + + Reward probabilities are defined as pairs (p_left, p_right) normalized by + base_reward_sum. Pairs are drawn from a family representing a difficulty level: + + Family 0: [[8, 1], [6, 1], [3, 1], [1, 1]] + Family 1: [[8, 1], [1, 1]] + Family 2: [[1.0, 0.0], [0.9, 0.1], [0.8, 0.2], [0.7, 0.3], [0.6, 0.4], [0.5, 0.5]] + Family 3: [[6, 1], [3, 1], [1, 1]] + + """ + + base_reward_sum: float = Field( + default=0.8, + description="Total reward probability shared between the two sides. Each reward pair is normalized to sum to this value.", + ) + reward_pairs: list[list[float, float]] = Field( + default=[[8, 1]], + description="List of (left, right) reward ratio pairs to sample from during block transitions. ", + ) + + +class Block(BaseModel): + p_right_reward: float = Field(ge=0, le=1, description="Reward probability for right side during block.") + p_left_reward: float = Field(ge=0, le=1, description="Reward probability for left side during block.") + min_length: int = Field(ge=0, description="Minimum number of trials in block.") + + +class BlockBasedTrialGeneratorSpec(BaseTrialGeneratorSpecModel): + type: Literal["BlockBasedTrialGenerator"] = "BlockBasedTrialGenerator" + + quiescent_duration: Distribution = Field( + default=ExponentialDistribution( + distribution_parameters=ExponentialDistributionParameters(rate=1), + truncation_parameters=TruncationParameters(min=0, max=1), + ), + description="Distribution describing the quiescence period before trial starts (in seconds). Each lick resets the timer.", + ) + + response_duration: float = Field(default=1.0, ge=0, description="Duration after go cue for animal response.") + + reward_consumption_duration: float = Field( + default=3.0, + ge=0, + description="Duration of reward consumption before transition to ITI (in seconds).", + ) + + inter_trial_interval_duration: Distribution = Field( + default=ExponentialDistribution( + distribution_parameters=ExponentialDistributionParameters(rate=1 / 2), + truncation_parameters=TruncationParameters(min=1, max=8), + ), + description="Distribution describing the inter-trial interval (in seconds).", + ) + + block_len: Distribution = Field( + default=ExponentialDistribution( + distribution_parameters=ExponentialDistributionParameters(rate=1 / 20), + truncation_parameters=TruncationParameters(min=20, max=60), + ), + description="Distribution describing block length.", + ) + + min_block_reward: int = Field(default=1, ge=0, title="Minimal rewards in a block to switch") + + kernel_size: int = Field(default=2, description="Kernel to evaluate choice fraction.") + reward_probability_parameters: RewardProbabilityParameters = Field( + default=RewardProbabilityParameters(), description="Parameters defining the reward probability structure." + ) + + is_baiting: bool = Field(default=False, description="Whether uncollected rewards carry over to the next trial.") + + def create_generator(self) -> "BlockBasedTrialGenerator": + return BlockBasedTrialGenerator(self) + + +class BlockBasedTrialGenerator(ITrialGenerator, ABC): + """Abstract trial generator for block-based dynamic foraging tasks. + + Manages block transitions, baiting logic, and trial generation. Subclasses + must implement `_are_end_conditions_met` to define session termination logic. + + Attributes: + spec: The specification used to configure this generator. + is_right_choice_history: Record of whether each trial was a right choice. + None indicates no choice was made (e.g. missed trial). + reward_history: Record of whether each trial resulted in a reward. + block_history: Record of all completed blocks. + block: The currently active block. + trials_in_block: Number of trials elapsed in the current block. + is_left_baited: Whether the left port currently has a baited reward. + is_right_baited: Whether the right port currently has a baited reward. + """ + + def __init__(self, spec: BlockBasedTrialGeneratorSpec) -> None: + """Initializes the generator and generates the first block. + + Args: + spec: The BlockBasedTrialGeneratorSpec defining task parameters. + """ + + self.spec = spec + self.is_right_choice_history: list[bool | None] = [] + self.reward_history: list[bool] = [] + self.block_history: list[Block] = [] + self.block: Block = self._generate_next_block( + reward_pairs=self.spec.reward_probability_parameters.reward_pairs, + base_reward_sum=self.spec.reward_probability_parameters.base_reward_sum, + block_len=self.spec.block_len, + ) + self.trials_in_block = 0 + self.is_left_baited: bool = False + self.is_right_baited: bool = False + + def next(self) -> Trial | None: + """Generates the next trial in the session. + + Checks end conditions, samples timing parameters, and applies baiting + logic if enabled. Returns None if the session should end. + + Returns: + The next Trial, or None if end conditions are met. + """ + logger.info("Generating next trial.") + + # check end conditions + if self._are_end_conditions_met(): + logger.info("Trial generator end conditions met.") + return + + # determine iti and quiescent period duration + iti = draw_sample(self.spec.inter_trial_interval_duration) + quiescent = draw_sample(self.spec.quiescent_duration) + + p_reward_left = self.block.p_left_reward + p_reward_right = self.block.p_right_reward + + if self.spec.is_baiting: + random_numbers = np.random.random(2) + + is_left_baited = self.block.p_left_reward > random_numbers[0] or self.is_left_baited + logger.debug(f"Left baited: {is_left_baited}") + p_reward_left = 1 if is_left_baited else p_reward_left + + is_right_baited = self.block.p_right_reward > random_numbers[1] or self.is_right_baited + logger.debug(f"Right baited: {is_left_baited}") + p_reward_right = 1 if is_right_baited else p_reward_right + + return Trial( + p_reward_left=p_reward_left, + p_reward_right=p_reward_right, + reward_consumption_duration=self.spec.reward_consumption_duration, + response_deadline_duration=self.spec.response_duration, + quiescence_period_duration=quiescent, + inter_trial_interval_duration=iti, + ) + + @abstractmethod + def _are_end_conditions_met(self) -> bool: + """Checks whether the session should end. + + Returns: + True if end conditions are met and no further trials should be + generated, False otherwise. + """ + pass + + def _generate_next_block( + self, + reward_pairs: list[list[float, float]], + base_reward_sum: float, + block_len: Union[UniformDistribution, ExponentialDistribution], + current_block: Optional[None] = None, + ) -> Block: + """Generates the next block, avoiding repeating the current block's side bias. + + Normalizes reward pairs by base_reward_sum, mirrors them to create a full + pool, optionally excludes the current block's probabilities and high-reward + side, then randomly samples the next block. + + Args: + reward_pairs: List of (left, right) reward ratio pairs to draw from. + base_reward_sum: Total reward probability to normalize each pair to. + block_len: Distribution from which to sample the next block length. + current_block: The currently active block, used to avoid repeating the + same reward probabilities or high-reward side. Defaults to None. + + Returns: + A new Block with sampled reward probabilities and length. + """ + + logger.info("Generating next block.") + + # determine candidate reward pairs + reward_prob = np.array(reward_pairs, dtype=float) + reward_prob /= reward_prob.sum(axis=1, keepdims=True) + reward_prob *= float(base_reward_sum) + logger.info(f"Candidate reward pairs normalized and scaled: {reward_prob.tolist()}") + + # create pool including all reward probabiliteis and mirrored pairs + reward_prob_pool = np.vstack([reward_prob, np.fliplr(reward_prob)]) + + if current_block: # exclude previous block if history exists + logger.info("Excluding previous block reward probability.") + last_block_reward_prob = [current_block.p_right_reward, current_block.p_left_reward] + + # remove blocks identical to last block + reward_prob_pool = reward_prob_pool[np.any(reward_prob_pool != last_block_reward_prob, axis=1)] + logger.debug(f"Pool after removing identical to last block: {reward_prob_pool.tolist()}") + + # remove blocks with same high-reward side (if last block had a clear high side) + if last_block_reward_prob[0] != last_block_reward_prob[1]: + high_side_last = last_block_reward_prob[0] > last_block_reward_prob[1] + high_side_pool = reward_prob_pool[:, 0] > reward_prob_pool[:, 1] + reward_prob_pool = reward_prob_pool[high_side_pool != high_side_last] + logger.debug(f"Pool after removing same high-reward side: {reward_prob_pool.tolist()}") + + # remove duplicates + reward_prob_pool = np.unique(reward_prob_pool, axis=0) + logger.debug(f"Final reward probability pool after removing duplicates: {reward_prob_pool.tolist()}") + + # randomly pick next block reward probability + p_right_reward, p_left_reward = reward_prob_pool[random.choice(range(reward_prob_pool.shape[0]))] + logger.info(f"Selected next block reward probabilities: right={p_right_reward}, left={p_left_reward}") + + # randomly pick block length + next_block_len = round(draw_sample(block_len)) + logger.info(f"Selected next block length: {next_block_len}") + + return Block( + p_right_reward=p_right_reward, + p_left_reward=p_left_reward, + min_length=next_block_len, + ) diff --git a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/composite_trial_generator.py b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/composite_trial_generator.py index e736e78..a7bca03 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/composite_trial_generator.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/composite_trial_generator.py @@ -62,7 +62,7 @@ def next(self) -> Trial | None: # Finally, return None if all generators got consumed return None - def update(self, outcome: TrialOutcome) -> None: + def update(self, outcome: TrialOutcome | str) -> None: """ Update the current active generator with the trial outcome. diff --git a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/coupled_trial_generator.py b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/coupled_trial_generator.py index 65dde50..93c37db 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/coupled_trial_generator.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/coupled_trial_generator.py @@ -1,250 +1,250 @@ -import random -from typing import Literal, Optional, Union +import logging +from datetime import datetime, timedelta +from typing import Literal, Optional import numpy as np -from aind_behavior_services.task.distributions import ( - DistributionFamily, - ExponentialDistribution, - ExponentialDistributionParameters, - TruncationParameters, - UniformDistribution, -) from pydantic import BaseModel, Field -from ..trial_models import Trial, TrialOutcome -from ._base import BaseTrialGeneratorSpecModel, ITrialGenerator +from ..trial_models import TrialOutcome +from .block_based_trial_generator import ( + BlockBasedTrialGenerator, + BlockBasedTrialGeneratorSpec, +) + +logger = logging.getLogger(__name__) -AutoWaterModes = Literal["Natural", "Both", "High pro"] BlockBehaviorEvaluationMode = Literal[ - "ignore", # do not take behavior into account when switching blocks - "end", # behavior must be stable at end of block to allow switching - "anytime", -] # behavior can be stable anytime in block to allow switching + "end", # behavior stable at end of block to allow switching + "anytime", # behavior stable anytime in block to allow switching +] -class RewardProbability(BaseModel): - base_reward_sum: float = Field(default=0.8, title="Sum of p_reward") - family: int = Field(default=1, title="Reward family") - pairs_n: int = Field(default=1, title="Number of pairs") +class CoupledTrialGenerationEndConditions(BaseModel): + """Defines the conditions under which a foraging session should terminate.""" + ignore_win: int = Field(default=30, ge=0, description="Number of recent trials to check for ignored responses.") + ignore_ratio_threshold: float = Field( + default=0.8, + ge=0, + le=1, + description="Maximum fraction of ignored trials within the window before the session is ended.", + ) + max_trial: int = Field(default=1000, ge=0, description="Maximum number of trials allowed in a session.") + max_time: float = Field(default=75 * 60, description="Maximum session duration (sec).") + min_time: float = Field(default=30 * 60, description="Minimum session duration (sec)") -class AutoWater(BaseModel): - auto_water_type: AutoWaterModes = Field(default="Natural", title="Auto water mode") - multiplier: float = Field(default=0.8, title="Multiplier for auto reward") - unrewarded: int = Field(default=200, title="Number of unrewarded trials before auto water") - ignored: int = Field(default=100, title="Number of ignored trials before auto water") +class BehaviorStabilityParameters(BaseModel): + """Parameters controlling when behavior is considered stable enough to switch blocks.""" -class Warmup(BaseModel): - min_trial: int = Field(default=50, title="Warmup finish criteria: minimal trials") - max_choice_ratio_bias: float = Field( - default=0.1, title="Warmup finish criteria: maximal choice ratio bias from 0.5" + behavior_evaluation_mode: BlockBehaviorEvaluationMode = Field( + default="end", + description="When to evaluate stability — at the end of the block (end) or at any point during the block (anytime).", + validate_default=True, ) - min_finish_ratio: float = Field(default=0.8, title="Warmup finish criteria: minimal finish ratio") - windowsize: int = Field( - default=20, - title="Warmup finish criteria: window size to compute the bias and ratio", + behavior_stability_fraction: float = Field( + default=0.5, + ge=0, + le=1, + description="Fraction scaling reward-probability difference for behavior.", + ) + min_consecutive_stable_trials: int = Field( + default=5, + ge=0, + description="Minimum number of consecutive trials satisfying the behavioral stability fraction.", ) -class Block(BaseModel): - right_reward_prob: float - left_reward_prob: float - min_length: int - - -class CoupledTrialGeneratorSpec(BaseTrialGeneratorSpecModel): +class CoupledTrialGeneratorSpec(BlockBasedTrialGeneratorSpec): type: Literal["CoupledTrialGenerator"] = "CoupledTrialGenerator" - iti: Union[UniformDistribution, ExponentialDistribution] = Field( - default=ExponentialDistribution( - distribution_parameters=ExponentialDistributionParameters(rate=1 / 2), - truncation_parameters=TruncationParameters(min=1, max=8), - ) - ) - quiescent_period: Union[UniformDistribution, ExponentialDistribution] = Field( - default=ExponentialDistribution( - distribution_parameters=ExponentialDistributionParameters(rate=1), - truncation_parameters=TruncationParameters(min=0, max=1), - ) - ) - - response_time: float = Field(default=1.0, title="Response time") - reward_consume_time: float = Field( - default=3.0, - title="Reward consume time", - description="Time of the no-lick period before trial end", - ) - block_parameters: Union[UniformDistribution, ExponentialDistribution] = Field( - default=ExponentialDistribution( - distribution_parameters=ExponentialDistributionParameters(rate=1 / 20), - truncation_parameters=TruncationParameters(min=20, max=60), - ) + trial_generation_end_parameters: CoupledTrialGenerationEndConditions = Field( + default=CoupledTrialGenerationEndConditions(), + description="Conditions to end trial generation.", + validate_default=True, ) - min_reward: int = Field(default=1, title="Minimal rewards in a block to switch") - auto_water: Optional[AutoWater] = Field(default=None, description="Parameters describing auto water.") - behavior_evaluation_mode: BlockBehaviorEvaluationMode = Field( - default="ignore", title="Auto block mode", validate_default=True + behavior_stability_parameters: Optional[BehaviorStabilityParameters] = Field( + default=BehaviorStabilityParameters(), + description="Parameters controlling behavior-dependent block switching. If None, block switches rely only on length and reward criteria.", ) - switch_thr: float = Field(default=0.5, title="Switch threshold for auto block") - points_in_a_row: int = Field(default=5, title="Points in a row for auto block") - warmup: Optional[Warmup] = Field(default=None, description="Parameters describing warmup.") - no_response_trial_addition: bool = Field( + extend_block_on_no_response: bool = Field( default=True, - description="Add one trial to the block length on both lickspouts.", + description="Whether to extend the minimum block length by one trial when the animal does not respond.", ) - kernel_size: int - reward_probability_specs: RewardProbability = Field(default=RewardProbability()) - reward_family: list = [ - [[8, 1], [6, 1], [3, 1], [1, 1]], - [[8, 1], [1, 1]], - [ - [1, 0], - [0.9, 0.1], - [0.8, 0.2], - [0.7, 0.3], - [0.6, 0.4], - [0.5, 0.5], - ], - [[6, 1], [3, 1], [1, 1]], - ] def create_generator(self) -> "CoupledTrialGenerator": return CoupledTrialGenerator(self) -class CoupledTrialGenerator(ITrialGenerator): - def __init__(self, spec: CoupledTrialGeneratorSpec) -> None: - """""" +class CoupledTrialGenerator(BlockBasedTrialGenerator): + """Trial generator for a coupled block-based dynamic foraging task. - self.spec = spec - self.is_right_choice_history: list[bool | None] = [] - self.reward_history: list[bool] = [] - self.block_history: list[Block] = [] - self.block: Block = Block() - self.trials_in_block = 0 + Extends BlockBasedTrialGenerator with session end conditions, baiting state + management, and behavior-dependent block switching. - def next(self) -> Trial | None: + Attributes: + spec: The CoupledTrialGeneratorSpec defining task parameters. + start_time: Timestamp recorded at initialization, used to track elapsed + session time. + """ + + spec: CoupledTrialGeneratorSpec + + def __init__(self, spec: CoupledTrialGeneratorSpec) -> None: + """Initializes the generator and records the session start time. + + Args: + spec: The CoupledTrialGeneratorSpec defining task parameters. """ - generate next trial - :param self: Description - :return: Description - :rtype: Trial | None + super().__init__(spec) + self.start_time = datetime.now() + + def _are_end_conditions_met(self) -> bool: + """Checks whether the session should end. + + Evaluates three termination conditions: excessive ignored trials after + minimum session time, maximum session time exceeded, and maximum trial + count exceeded. + + Returns: + True if any end condition is met, False otherwise. """ - iti = self.evaluate_distribution(self.spec.iti) - quiescent = self.evaluate_distribution(self.spec.quiescent_period) + end_conditions = self.spec.trial_generation_end_parameters + choice_history = self.is_right_choice_history - self.trials_in_block += 1 + time_elapsed = datetime.now() - self.start_time + frac = end_conditions.ignore_ratio_threshold + win = end_conditions.ignore_win - return Trial( - p_reward_left=self.block.left_reward_prob, - p_reward_right=self.block.right_reward_prob, - reward_consumption_duration=self.spec.reward_consume_time, - response_deadline_duration=self.spec.response_time, - quiescence_period_duration=quiescent, - inter_trial_interval_duration=iti, - ) + if ( + time_elapsed > timedelta(seconds=end_conditions.min_time) + and choice_history[-win:].count(None) >= frac * win + ): + logger.debug("Minimum time and ignored trial count exceeded.") + return True - @staticmethod - def evaluate_distribution( - distribution: Union[UniformDistribution, ExponentialDistribution], - ) -> Union[UniformDistribution, ExponentialDistribution]: - if distribution.family == DistributionFamily.EXPONENTIAL: - return ( - np.random.exponential(1 / distribution.distribution_parameters.rate, 1) - + distribution.truncation_parameters.min - ) - elif distribution.family == DistributionFamily.UNIFORM: - return random.uniform( - distribution.distribution_parameters.min, - distribution.distribution_parameters.max, - ) + if timedelta(seconds=end_conditions.max_time) < time_elapsed: + logger.debug("Maximum session time exceeded.") + return True - else: - raise ValueError(f"Distribution {distribution.family} not recognized.") + if end_conditions.max_trial < len(choice_history): + logger.debug("Maximum trial count exceeded.") + return True - def update(self, outcome: TrialOutcome) -> None: - """ - Check if block should switch, generate next block if necessary, and generate next trial + return False + + def update(self, outcome: TrialOutcome | str) -> None: + """Updates generator state from the previous trial outcome and switches block if criteria are met. - :param self: Description - :param outcome: Description - :type outcome: TrialOutcome + Records choice and reward history, manages baiting state, optionally extends + the block on no response, and triggers a block switch if all switch criteria + are satisfied. + + Args: + outcome: The TrialOutcome from the most recently completed trial. """ - self.is_right_choice_history.append[outcome.is_right_choice] - self.reward_history.append[outcome.is_rewarded] + logger.info(f"Updating coupled trial generator with trial outcome of {outcome}") + + if isinstance(outcome, str): + outcome = TrialOutcome.model_validate_json(outcome) + + self.is_right_choice_history.append(outcome.is_right_choice) + self.reward_history.append(outcome.is_rewarded) self.trials_in_block += 1 - switch_block = self.switch_block( + if self.spec.is_baiting: + if outcome.is_right_choice: + logger.debug("Resesting right bait.") + self.is_right_baited = False + elif outcome.is_right_choice is False: + logger.debug("Resesting left bait.") + self.is_left_baited = False + + if self.spec.extend_block_on_no_response and outcome.is_right_choice is None: + logger.info("Extending minimum block length due to ignored trial.") + self.block.min_length += 1 + + switch_block = self._is_block_switch_allowed( trials_in_block=self.trials_in_block, - min_block_reward=self.spec.min_reward, - block_left_rewards=self.reward_history.count(False), - block_right_rewards=self.reward_history.count(True), + min_block_reward=self.spec.min_block_reward, choice_history=self.is_right_choice_history, - right_reward_prob=self.block.right_reward_prob, - left_reward_prob=self.block.left_reward_prob, - beh_eval_mode=self.spec.behavior_evaluation_mode, + p_right_reward=self.block.p_right_reward, + p_left_reward=self.block.p_left_reward, + beh_stability_params=self.spec.behavior_stability_parameters, block_length=self.block.min_length, - points_in_a_row=self.spec.points_in_a_row, - switch_thr=self.spec.switch_thr, kernel_size=self.spec.kernel_size, ) if switch_block: + logger.info("Switching block.") self.trials_in_block = 0 - self.block = self.generate_block( - reward_families=self.spec.reward_family, - reward_family_index=self.spec.reward_probability_specs.family, - reward_pairs_n=self.spec.reward_probability_specs.pairs_n, - base_reward_sum=self.spec.reward_probability_specs.base_reward_sum, - block_history=self.block_history, - block_distribution=self.spec.block_parameters, + self.block = self._generate_next_block( + reward_pairs=self.spec.reward_probability_parameters.reward_pairs, + base_reward_sum=self.spec.reward_probability_parameters.base_reward_sum, + current_block=self.block, + block_len=self.spec.block_len, ) self.block_history.append(self.block) - def is_behavior_stable( + def _is_behavior_stable( self, - choice_history: np.ndarray, - right_reward_prob: float, - left_reward_prob: float, - beh_eval_mode: BlockBehaviorEvaluationMode, + choice_history: list, + p_right_reward: float, + p_left_reward: float, + beh_stability_params: BehaviorStabilityParameters, trials_in_block: int, - points_in_a_row: int = 3, - switch_thr: float = 0.8, kernel_size: int = 2, ) -> Optional[bool]: + """Evaluates whether the animal's choice behavior is stable enough to allow a block switch. + + Computes a sliding-window choice fraction and checks whether it falls within + a threshold derived from the reward probability difference. Stability is + assessed either at the end of the block or at any point, depending on + the evaluation mode. + + Args: + choice_history: Trial history with True for right, False for left, + and None for ignored trials. + p_right_reward: Reward probability for the right port in the current block. + p_left_reward: Reward probability for the left port in the current block. + beh_stability_params: Parameters defining the stability threshold and + evaluation mode. + trials_in_block: Number of trials elapsed in the current block. + kernel_size: Sliding window size for computing choice fraction. + + Returns: + True if behavior is stable or evaluation is skipped, False if behavior + does not meet the stability criterion. + + Raises: + ValueError: If the behavior evaluation mode is not recognized. """ - This function replaces _check_advanced_block_switch. Checks if behavior within block - allows for switching - - choice_history: 1D array with 0: left, 1: right and None: ignored entries. - right_reward_prob: reward probability for right side - left_reward_prob: reward probability for left side - beh_eval_mode: mode to evaluate behavior - trials_in_block: number of trials in current block. In couple trials, both sides have same block length so block length is int. - points_in_a_row: number of consecutive trials above threshold required - switch_thr: fraction threshold to define stable behavior - kernel_size: kernel to evaluate choice fraction - """ + logger.info("Evaluating block behavior.") # do not prohibit block transition if does not rely on behavior or not enough trials to evaluate or reward probs are the same. - if beh_eval_mode == "ignore" or left_reward_prob == right_reward_prob or len(choice_history) < kernel_size: + if not beh_stability_params or p_left_reward == p_right_reward or len(choice_history) < kernel_size: + logger.debug( + "Behavior stability evaluation skipped: " + f"parameters_missing={not bool(beh_stability_params)}, " + f"rewards_equal={p_left_reward == p_right_reward}, " + f"trials_available={len(choice_history)} < kernel_size({kernel_size})" + ) return True # compute fraction of right choices with running average using a sliding window block_history = choice_history[-(trials_in_block + kernel_size - 1) :] block_choice_frac = self.compute_choice_fraction(kernel_size, block_history) + logger.debug(f"Choice fraction of block is {block_choice_frac}.") # margin based on right and left probabilities and scaled by switch threshold. Window for evaluating behavior - delta = abs((left_reward_prob - right_reward_prob) * float(switch_thr)) - threshold = ( - [0, left_reward_prob - delta] if left_reward_prob > right_reward_prob else [left_reward_prob + delta, 1] - ) + delta = abs((p_left_reward - p_right_reward) * float(beh_stability_params.behavior_stability_fraction)) + threshold = [0, p_left_reward - delta] if p_left_reward > p_right_reward else [p_left_reward + delta, 1] + logger.debug(f"Behavior stability threshold applied: {threshold}") # block_choice_fractions above threshold points_above_threshold = np.logical_and( @@ -252,95 +252,112 @@ def is_behavior_stable( block_choice_frac <= threshold[1], ) - # check consecutive pts above threshold - if points_in_a_row <= 0: - return True - - if beh_eval_mode == "end": - # requires consecutive trials ending on the last trial - # check if the current trial occurs at the end of a long enough consecutive run above threshold - if len(points_above_threshold) < points_in_a_row: + # evaluate stability based on mode + min_stable = beh_stability_params.min_consecutive_stable_trials + mode = beh_stability_params.behavior_evaluation_mode + if mode == "end": + # requires consecutive trials at end of trial + logger.info(f"Evaluating last {min_stable} trials for end-of-block stability.") + if len(points_above_threshold) < min_stable: + logger.info("Not enough trials to evaluate stability at block end.") return False - return np.all(points_above_threshold[-points_in_a_row:]) + stable = np.all(points_above_threshold[-min_stable:]) + logger.info(f"Behavior stable at block end: {stable}") + return stable - elif beh_eval_mode == "anytime": + elif mode == "anytime": # allows consecutive trials any time in the behavior + logger.info(f"Evaluating block for stability anytime over {min_stable} consecutive trials.") run_len = 0 - for v in points_above_threshold: + for i, v in enumerate(points_above_threshold): if v: run_len += 1 else: - if run_len >= points_in_a_row: - return True - else: - run_len = 0 - return run_len >= points_in_a_row + run_len = 0 + if run_len >= min_stable: + logger.info(f"Behavior stable at trial index {i}.") + return True + logger.info("Behavior not stable in block anytime evaluation.") + return False else: - raise ValueError(f"Behavior evaluation mode {beh_eval_mode} not recognized.") + raise ValueError(f"Behavior evaluation mode {mode} not recognized.") - def compute_choice_fraction(self, kernel_size: int, choice_history: list[int | None]): - """ - Compute fraction of right choices with running average using a sliding window + @staticmethod + def compute_choice_fraction(kernel_size: int, choice_history: list[int | None]): + """Computes a sliding-window fraction of right choices over the trial history. + + Ignores None (no-response) trials by treating them as NaN in the mean. + + Args: + kernel_size: Number of trials in each sliding window. + choice_history: Trial history with 1 for right, 0 for left, and + None for ignored trials. - :param kernel_size: kernel to evaluate choice fraction - :param choice_history: 1D array with 0: left, 1: right and None: ignored entries. + Returns: + Array of per-window right-choice fractions, of length + len(choice_history) - kernel_size + 1. """ n_windows = len(choice_history) - kernel_size + 1 choice_fraction = np.empty(n_windows, dtype=float) # create empty array to store running averages for i in range(n_windows): - window = choice_history[i : i + kernel_size].astype(float) + window = np.array(choice_history[i : i + kernel_size], dtype=float) choice_fraction[i] = np.nanmean(window) return choice_fraction - def switch_block( + def _is_block_switch_allowed( self, trials_in_block: int, min_block_reward: int, - block_left_rewards: int, - block_right_rewards: int, - choice_history: np.ndarray, - right_reward_prob: float, - left_reward_prob: float, - beh_eval_mode: BlockBehaviorEvaluationMode, + choice_history: list, + p_right_reward: float, + p_left_reward: float, + beh_stability_params: BehaviorStabilityParameters, block_length: int, - points_in_a_row: int = 3, - switch_thr: float = 0.8, kernel_size: int = 2, ) -> bool: + """Determines whether all criteria are met to switch to the next block. + + A block switch requires: the planned block length has been reached, the + minimum reward count has been collected, and behavior meets the stability + criterion. + + Args: + trials_in_block: Number of trials elapsed in the current block. + min_block_reward: Minimum total rewards required before switching. + choice_history: Trial history with True for right, False for left, + and None for ignored trials. + p_right_reward: Reward probability for the right port in the current block. + p_left_reward: Reward probability for the left port in the current block. + beh_stability_params: Parameters defining the behavior stability criterion. + block_length: Planned minimum number of trials in the current block. + kernel_size: Sliding window size for computing choice fraction. + + Returns: + True if all switch criteria are satisfied, False otherwise. """ - trials_in_block: number of trials in block - min_block_reward: minimum reward to allow switching - block_left_rewards: number of left rewarded trials in current block - block_right_rewards: number of left rewarded trials in current block - choice_history: 2D array (rows = sides, columns = trials) with 0: left, 1: right and 2: ignored entries. - right_reward_prob: reward probability for right side - left_reward_prob: reward probability for left side - beh_eval_mode: mode to evaluate behavior - block_length: planned number of trials in current block. In couple trials, both sides have same block length so block length is int. - points_in_a_row: number of consecutive trials above threshold required - switch_thr: fraction threshold to define stable behavior - kernel_size: kernel to evaluate choice fraction - """ + + logger.info("Evaluating block switch.") # has planned block length been reached? block_length_ok = trials_in_block >= block_length + logger.debug(f"Planned block length reached: {block_length_ok}") # is behavior qualified to switch? - behavior_ok = self.is_behavior_stable( + behavior_ok = self._is_behavior_stable( choice_history, - right_reward_prob, - left_reward_prob, - beh_eval_mode, + p_right_reward, + p_left_reward, + beh_stability_params, trials_in_block, - points_in_a_row, - switch_thr, kernel_size, ) + logger.debug(f"Behavior meets stability criteria: {behavior_ok}") # has reward criteria been met? - reward_ok = block_left_rewards + block_right_rewards >= min_block_reward + reward_ok = self.reward_history.count(False) + self.reward_history.count(True) >= min_block_reward + logger.debug(f"Reward criterion satisfied: {reward_ok}") # conditions to switch: # - planned block length reached @@ -348,60 +365,3 @@ def switch_block( # - behavior is stable return block_length_ok and reward_ok and behavior_ok - - def generate_block( - self, - reward_families: list, - reward_family_index: int, - reward_pairs_n: int, - base_reward_sum: float, - block_history: list[Block], - block_distribution: Union[UniformDistribution, ExponentialDistribution], - ) -> Block: - """ - Generate the next block for a coupled task. - - :param reward_families: Description - :param reward_family_index: Description - :param reward_pairs_n: Description - :param base_reward_sum: Description - :param reward_prob_history: Description - :param block_distribution: Description - """ - - # determine candidate reward pairs - reward_pairs = reward_families[reward_family_index][:reward_pairs_n] - reward_prob = np.array(reward_pairs, dtype=float) - reward_prob /= reward_prob.sum(axis=1, keepdims=True) - reward_prob *= float(base_reward_sum) - - # create pool including all reward probabiliteis and mirrored pairs - reward_prob_pool = np.vstack([reward_prob, np.fliplr(reward_prob)]) - - if block_history: # exclude previous block if history exists - reward_prob_history = [[block.right_reward_prob, block.left_reward_prob] for block in block_history] - last_block_reward_prob = reward_prob_history[:, -1] - - # remove blocks identical to last block - reward_prob_pool = reward_prob_pool[np.any(reward_prob_pool != last_block_reward_prob, axis=1)] - - # remove blocks with same high-reward side (if last block had a clear high side) - if last_block_reward_prob[0] != last_block_reward_prob[1]: - high_side_last = last_block_reward_prob[0] > last_block_reward_prob[1] - high_side_pool = reward_prob_pool[:, 0] > reward_prob_pool[:, 1] - reward_prob_pool = reward_prob_pool[high_side_pool != high_side_last] - - # remove duplicates - reward_prob_pool = np.unique(reward_prob_pool, axis=0) - - # randomly pick next block reward probability - right_reward_prob, left_reward_prob = reward_prob_pool[random.choice(range(reward_prob_pool.shape[0]))] - - # randomly pick block length - next_block_len = self.evaluate_distribution(block_distribution) - - return Block( - right_reward_prob=right_reward_prob, - left_reward_prob=left_reward_prob, - min_length=next_block_len, - ) diff --git a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/integration_test_trial_generator.py b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/integration_test_trial_generator.py index 8b204e9..3e04eaa 100644 --- a/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/integration_test_trial_generator.py +++ b/src/aind_behavior_dynamic_foraging/task_logic/trial_generators/integration_test_trial_generator.py @@ -31,37 +31,37 @@ def __init__(self, spec: IntegrationTestTrialGeneratorSpec) -> None: ), # 6: right reward, auto response right Trial( p_reward_left=1.0, p_reward_right=1.0, is_auto_response_right=True - ), # 9: both reward, auto response right, + ), # 7: both reward, auto response right, Trial( p_reward_left=0.0, p_reward_right=0.0, is_auto_response_right=True - ), # 10: no reward, auto response right, + ), # 8: no reward, auto response right, # auto response left Trial( p_reward_left=1.0, p_reward_right=0.0, is_auto_response_right=False - ), # 11: left reward, auto response left, + ), # 9: left reward, auto response left, Trial( p_reward_left=0.0, p_reward_right=1.0, is_auto_response_right=False - ), # 12: right reward, auto response left, + ), # 10: right reward, auto response left, Trial( p_reward_left=0.0, p_reward_right=1.0, is_auto_response_right=False - ), # 13: both reward, auto response left, + ), # 11: both reward, auto response left, Trial( p_reward_left=0.0, p_reward_right=0.0, is_auto_response_right=False - ), # 14: no reward, auto response left, + ), # 12: no reward, auto response left, # fast retract - Trial(enable_fast_retract=True), # 15: enable fast retract + Trial(enable_fast_retract=True), # 13: enable fast retract # secondary reinforcer - # Trial(secondary_reinforcer=SecondaryReinforcer()), # 16: enable secondary reinforcer + # Trial(secondary_reinforcer=SecondaryReinforcer()), # 14: enable secondary reinforcer # no reward consumption duration - Trial(reward_consumption_duration=0), # 17: no reward consumption duration + Trial(reward_consumption_duration=0), # 15: no reward consumption duration # no reward delay - Trial(reward_delay_duration=0), # 18: no reward delay duration + Trial(reward_delay_duration=0), # 16: no reward delay duration # no response deadline duration - Trial(response_deadline_duration=0), # 19: no response deadline duration + Trial(response_deadline_duration=0), # 17: no response deadline duration # no quiescence period duration - Trial(quiescence_period_duration=0), # 20: no quiescence period duration + Trial(quiescence_period_duration=0), # 18: no quiescence period duration # no inter trial interval - Trial(inter_trial_interval_duration=0.5), # 21: no inter trial interval duration + Trial(inter_trial_interval_duration=0.5), # 19: no inter trial interval duration ] def next(self) -> Trial | None: @@ -69,5 +69,5 @@ def next(self) -> Trial | None: return None return self.trial_opts[self._idx] - def update(self, outcome: TrialOutcome) -> None: + def update(self, outcome: TrialOutcome | str) -> None: self._idx += 1 diff --git a/src/main.bonsai b/src/main.bonsai index d2dcf80..fd96806 100644 --- a/src/main.bonsai +++ b/src/main.bonsai @@ -7,7 +7,6 @@ xmlns:p2="clr-namespace:;assembly=Extensions" xmlns:p3="clr-namespace:System.Reactive;assembly=System.Reactive.Core" xmlns:p4="clr-namespace:AllenNeuralDynamics.AindBehaviorServices.DataTypes;assembly=AllenNeuralDynamics.AindBehaviorServices" - xmlns:ui="clr-namespace:Bonsai.Design;assembly=Bonsai.Design" xmlns="https://bonsai-rx.org/2018/workflow"> @@ -214,6 +213,11 @@ + + + 1 + + BiasOffsetBounds @@ -239,6 +243,7 @@ + @@ -349,19 +354,7 @@ - - - 0 - - - - DynamicForaging - true - - - - @@ -375,8 +368,6 @@ - - \ No newline at end of file diff --git a/tests/trial_generators/test_block_based_trial_generator.py b/tests/trial_generators/test_block_based_trial_generator.py new file mode 100644 index 0000000..9d434d9 --- /dev/null +++ b/tests/trial_generators/test_block_based_trial_generator.py @@ -0,0 +1,172 @@ +import logging +import unittest +from unittest.mock import patch + +import numpy as np + +from aind_behavior_dynamic_foraging.task_logic.trial_generators.block_based_trial_generator import ( + Block, + BlockBasedTrialGenerator, + BlockBasedTrialGeneratorSpec, + RewardProbabilityParameters, +) +from aind_behavior_dynamic_foraging.task_logic.trial_models import Trial + +logging.basicConfig(level=logging.DEBUG) + + +class ConcreteBlockBasedTrialGenerator(BlockBasedTrialGenerator): + def _are_end_conditions_met(self) -> bool: + return False + + +class ConcreteBlockBasedTrialGeneratorSpec(BlockBasedTrialGeneratorSpec): + def create_generator(self) -> "ConcreteBlockBasedTrialGenerator": + return ConcreteBlockBasedTrialGenerator(self) + + +class TestBlockBasedTrialGenerator(unittest.TestCase): + def setUp(self): + self.spec = ConcreteBlockBasedTrialGeneratorSpec() + self.generator = self.spec.create_generator() + + #### Test generate_next_block #### + + def test_next_block_differs_from_current(self): + current = self.generator.block + next_block = self.generator._generate_next_block( + reward_pairs=self.spec.reward_probability_parameters.reward_pairs, + base_reward_sum=self.spec.reward_probability_parameters.base_reward_sum, + block_len=self.spec.block_len, + current_block=current, + ) + self.assertNotEqual( + (next_block.p_right_reward, next_block.p_left_reward), + (current.p_right_reward, current.p_left_reward), + ) + + def test_next_block_switches_high_reward_side(self): + current = self.generator.block + next_block = self.generator._generate_next_block( + reward_pairs=self.spec.reward_probability_parameters.reward_pairs, + base_reward_sum=self.spec.reward_probability_parameters.base_reward_sum, + block_len=self.spec.block_len, + current_block=current, + ) + current_high_is_right = current.p_right_reward > current.p_left_reward + next_high_is_right = next_block.p_right_reward > next_block.p_left_reward + self.assertNotEqual(current_high_is_right, next_high_is_right) + + def test_next_block_switches_high_reward_side_multiple_pairs(self): + spec = ConcreteBlockBasedTrialGeneratorSpec( + reward_probability_parameters=RewardProbabilityParameters( + reward_pairs=[[8, 1], [6, 1], [3, 1]], + ) + ) + generator = spec.create_generator() + + current = generator.block + next_block = generator._generate_next_block( + reward_pairs=spec.reward_probability_parameters.reward_pairs, + base_reward_sum=spec.reward_probability_parameters.base_reward_sum, + block_len=spec.block_len, + current_block=current, + ) + + current_high_is_right = current.p_right_reward > current.p_left_reward + next_high_is_right = next_block.p_right_reward > next_block.p_left_reward + self.assertNotEqual(current_high_is_right, next_high_is_right) + + def test_next_block_never_repeats_current_multiple_pairs(self): + spec = ConcreteBlockBasedTrialGeneratorSpec( + reward_probability_parameters=RewardProbabilityParameters( + reward_pairs=[[8, 1], [6, 1], [3, 1]], + ) + ) + generator = spec.create_generator() + + current = generator.block + for _ in range(50): + next_block = generator._generate_next_block( + reward_pairs=spec.reward_probability_parameters.reward_pairs, + base_reward_sum=spec.reward_probability_parameters.base_reward_sum, + block_len=spec.block_len, + current_block=current, + ) + self.assertNotEqual( + (next_block.p_right_reward, next_block.p_left_reward), + (current.p_right_reward, current.p_left_reward), + ) + self.assertNotEqual( + next_block.p_right_reward > next_block.p_left_reward, + current.p_right_reward > current.p_left_reward, + ) + current = next_block + + #### Test next #### + + def test_next_returns_trial(self): + trial = self.generator.next() + self.assertIsInstance(trial, Trial) + + def test_next_returns_correct_reward_probs(self): + trial = self.generator.next() + self.assertEqual(trial.p_reward_left, self.generator.block.p_left_reward) + self.assertEqual(trial.p_reward_right, self.generator.block.p_right_reward) + + #### Test unbaited #### + + def test_baiting_disabled_reward_prob_unchanged(self): + """Without baiting, reward probs should equal block probs exactly.""" + self.generator.block = Block(p_right_reward=0.8, p_left_reward=0.2, min_length=10) + self.generator.is_left_baited = True + self.generator.is_right_baited = True + trial = self.generator.next() + + self.assertEqual(trial.p_reward_right, 0.8) + self.assertEqual(trial.p_reward_left, 0.2) + + +class TestBlockBaseBaitingTrialGenerator(unittest.TestCase): + def setUp(self): + self.spec = ConcreteBlockBasedTrialGeneratorSpec(is_baiting=True) + self.generator = self.spec.create_generator() + + def test_baiting_sets_prob_to_1_when_baited(self): + """If bait is held, reward prob should be 1.0 on that side.""" + self.generator.block = Block(p_right_reward=0.5, p_left_reward=0.5, min_length=10) + self.generator.is_right_baited = True + self.generator.is_left_baited = True + + trial = self.generator.next() + + self.assertEqual(trial.p_reward_right, 1.0) + self.assertEqual(trial.p_reward_left, 1.0) + + def test_baiting_accumulates_when_random_exceeds_prob(self): + """Bait should carry over when random number exceeds reward prob.""" + self.generator.block = Block(p_right_reward=0.5, p_left_reward=0.5, min_length=10) + self.generator.is_right_baited = False + self.generator.is_left_baited = False + + with patch("numpy.random.random", return_value=np.array([0.9, 0.9])): + trial = self.generator.next() + + self.assertEqual(trial.p_reward_right, 0.5) + self.assertEqual(trial.p_reward_left, 0.5) + + def test_baiting_triggers_when_random_below_prob(self): + """Bait should trigger reward prob of 1.0 when random number is below reward prob.""" + self.generator.block = Block(p_right_reward=0.5, p_left_reward=0.5, min_length=10) + self.generator.is_right_baited = False + self.generator.is_left_baited = False + + with patch("numpy.random.random", return_value=np.array([0.1, 0.1])): + trial = self.generator.next() + + self.assertEqual(trial.p_reward_right, 1.0) + self.assertEqual(trial.p_reward_left, 1.0) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/trial_generators/test_composite_trial_generator.py b/tests/trial_generators/test_composite_trial_generator.py index d96bc3f..964039a 100644 --- a/tests/trial_generators/test_composite_trial_generator.py +++ b/tests/trial_generators/test_composite_trial_generator.py @@ -29,7 +29,7 @@ def next(self) -> Trial | None: return None return Trial(p_reward_left=1.0, p_reward_right=1.0) - def update(self, outcome: TrialOutcome) -> None: + def update(self, outcome: TrialOutcome | str) -> None: self.trial_count += 1 diff --git a/tests/trial_generators/test_coupled_trial_generator.py b/tests/trial_generators/test_coupled_trial_generator.py new file mode 100644 index 0000000..97ba04b --- /dev/null +++ b/tests/trial_generators/test_coupled_trial_generator.py @@ -0,0 +1,323 @@ +import logging +import unittest +from datetime import timedelta + +from aind_behavior_dynamic_foraging.task_logic.trial_generators import CoupledTrialGeneratorSpec +from aind_behavior_dynamic_foraging.task_logic.trial_models import Trial, TrialOutcome + +logging.basicConfig(level=logging.DEBUG) + + +class TestCoupledTrialGenerator(unittest.TestCase): + def setUp(self): + self.spec = CoupledTrialGeneratorSpec() + self.generator = self.spec.create_generator() + + ##### Tests _is_behavior_stable ##### + + def test_behavior_stable_end(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = self.generator.block.p_right_reward + left_prob = self.generator.block.p_left_reward + kernel_size = self.generator.spec.kernel_size + min_stable = beh_params.min_consecutive_stable_trials + + high_reward_is_right = right_prob > left_prob + beh_params.behavior_evaluation_mode = "end" + + choices = [not high_reward_is_right] * 10 + [high_reward_is_right] * (min_stable + kernel_size - 1) + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_behavior_not_stable_end(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = self.generator.block.p_right_reward + left_prob = self.generator.block.p_left_reward + kernel_size = self.generator.spec.kernel_size + min_stable = beh_params.min_consecutive_stable_trials + + high_reward_is_right = right_prob > left_prob + beh_params.behavior_evaluation_mode = "end" + + choices = [high_reward_is_right] * 10 + [not high_reward_is_right] * (min_stable + kernel_size - 1) + self.assertFalse( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_behavior_stable_anytime(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = self.generator.block.p_right_reward + left_prob = self.generator.block.p_left_reward + kernel_size = self.generator.spec.kernel_size + min_stable = beh_params.min_consecutive_stable_trials + + high_reward_is_right = right_prob > left_prob + beh_params.behavior_evaluation_mode = "anytime" + + # stable run early, then drifts off — should still pass + choices = [high_reward_is_right] * (min_stable + kernel_size - 1) + [not high_reward_is_right] * 10 + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + # stable at end: wrong side early, correct side at end + choices = [not high_reward_is_right] * 10 + [high_reward_is_right] * (min_stable + kernel_size - 1) + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_alternating_choices_behavior_not_stable(self): + beh_params = self.generator.spec.behavior_stability_parameters + left_prob = 0.7111111111111111 + right_prob = 0.08888888888888889 + kernel_size = self.generator.spec.kernel_size + + choices = [True, False] * 15 + + beh_params.behavior_evaluation_mode = "anytime" + self.assertFalse( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + beh_params.behavior_evaluation_mode = "end" + self.assertFalse( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_alternating_choices_behavior_stable(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = 0.7111111111111111 + left_prob = 0.08888888888888889 + kernel_size = self.generator.spec.kernel_size + + choices = [True, False] * 15 + + beh_params.behavior_evaluation_mode = "anytime" + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + beh_params.behavior_evaluation_mode = "end" + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_behavior_stable_equal_reward_prob(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = 0.5 + left_prob = 0.5 + kernel_size = self.generator.spec.kernel_size + + choices = [True] * 15 + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_behavior_stable_choice_len_less_than_kernel(self): + beh_params = self.generator.spec.behavior_stability_parameters + right_prob = self.generator.block.p_right_reward + left_prob = self.generator.block.p_left_reward + kernel_size = self.generator.spec.kernel_size + + choices = [True] + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + def test_behavior_stable_no_beh_stability_params(self): + spec = CoupledTrialGeneratorSpec(behavior_stability_parameters=None) + generator = spec.create_generator() + + beh_params = generator.spec.behavior_stability_parameters + right_prob = generator.block.p_right_reward + left_prob = generator.block.p_left_reward + kernel_size = generator.spec.kernel_size + + choices = [True] + self.assertTrue( + self.generator._is_behavior_stable(choices, right_prob, left_prob, beh_params, len(choices), kernel_size) + ) + + #### Test _is_block_switch_allowed #### + + def test_block_switch_all_conditions_met_switches(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 20 + self.generator.trials_in_block = 20 + self.generator.reward_history = [True] * 5 + + result = self.generator._is_block_switch_allowed( + trials_in_block=self.generator.trials_in_block, + min_block_reward=1, + choice_history=[True] * 20, + p_right_reward=self.generator.block.p_right_reward, + p_left_reward=self.generator.block.p_left_reward, + beh_stability_params=self.generator.spec.behavior_stability_parameters, + block_length=self.generator.block.min_length, + kernel_size=self.generator.spec.kernel_size, + ) + self.assertTrue(result) + + def test_block_switch_block_length_not_reached(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 20 + self.generator.reward_history = [True] * 5 + + result = self.generator._is_block_switch_allowed( + trials_in_block=10, # below min_length + min_block_reward=1, + choice_history=[True] * 10, + p_right_reward=self.generator.block.p_right_reward, + p_left_reward=self.generator.block.p_left_reward, + beh_stability_params=self.generator.spec.behavior_stability_parameters, + block_length=self.generator.block.min_length, + kernel_size=self.generator.spec.kernel_size, + ) + self.assertFalse(result) + + def test_block_switch_reward_not_met(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 20 + self.generator.reward_history = [] # no rewards + + result = self.generator._is_block_switch_allowed( + trials_in_block=20, + min_block_reward=5, + choice_history=[True] * 20, + p_right_reward=self.generator.block.p_right_reward, + p_left_reward=self.generator.block.p_left_reward, + beh_stability_params=self.generator.spec.behavior_stability_parameters, + block_length=self.generator.block.min_length, + kernel_size=self.generator.spec.kernel_size, + ) + self.assertFalse(result) + + def test_block_switch_behavior_not_stable(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 20 + self.generator.reward_history = [True] * 5 + + result = self.generator._is_block_switch_allowed( + trials_in_block=20, + min_block_reward=1, + choice_history=[False] * 20, # always choosing low-reward side + p_right_reward=self.generator.block.p_right_reward, + p_left_reward=self.generator.block.p_left_reward, + beh_stability_params=self.generator.spec.behavior_stability_parameters, + block_length=self.generator.block.min_length, + kernel_size=self.generator.spec.kernel_size, + ) + self.assertFalse(result) + + #### Test update #### + + def _make_outcome(self, is_right_choice, is_rewarded): + return TrialOutcome(trial=Trial(), is_right_choice=is_right_choice, is_rewarded=is_rewarded) + + def test_update_appends_to_history(self): + self.generator.update(self._make_outcome(True, True)) + self.assertEqual(len(self.generator.is_right_choice_history), 1) + self.assertEqual(len(self.generator.reward_history), 1) + + def test_update_ignored_trial_extends_block_length(self): + original_length = self.generator.block.min_length + self.generator.update(self._make_outcome(None, False)) + self.assertEqual(self.generator.block.min_length, original_length + 1) + + def test_update_non_ignored_trial_does_not_extend_block(self): + original_length = self.generator.block.min_length + self.generator.update(self._make_outcome(True, True)) + self.assertEqual(self.generator.block.min_length, original_length) + + def test_update_block_switches_after_conditions_met(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 5 + self.generator.trials_in_block = 0 + + initial_block = self.generator.block + + min_stable = self.generator.spec.behavior_stability_parameters.min_consecutive_stable_trials + kernel_size = self.generator.spec.kernel_size + self.generator.reward_history = [True] * 10 + + for _ in range(min_stable + kernel_size - 1): + self.generator.update(self._make_outcome(True, True)) + + self.assertIsNot(self.generator.block, initial_block) + + def test_update_block_does_not_switch_before_min_length(self): + self.generator.block.p_right_reward = 0.8 + self.generator.block.p_left_reward = 0.2 + self.generator.block.min_length = 100 + self.generator.trials_in_block = 0 + + initial_block = self.generator.block + + for _ in range(5): + self.generator.update(self._make_outcome(True, True)) + + self.assertIs(self.generator.block, initial_block) + + #### Test next #### + + def test_next_returns_none_after_max_trials(self): + self.generator.is_right_choice_history = [True] * (self.spec.trial_generation_end_parameters.max_trial + 1) + self.generator.start_time = self.generator.start_time - timedelta( + self.spec.trial_generation_end_parameters.min_time + ) + + trial = self.generator.next() + self.assertIsNone(trial) + + def test_baiting_disabled_bait_state_never_changes(self): + self.generator.is_right_baited = True + self.generator.is_left_baited = True + self.generator.update(self._make_outcome(is_right_choice=True, is_rewarded=True)) + self.assertTrue(self.generator.is_right_baited) + self.assertTrue(self.generator.is_left_baited) + + +class TestCoupledBaitingTrialGenerator(unittest.TestCase): + def setUp(self): + self.spec = CoupledTrialGeneratorSpec(is_baiting=True) + self.generator = self.spec.create_generator() + + def _make_outcome(self, is_right_choice, is_rewarded): + return TrialOutcome(trial=Trial(), is_right_choice=is_right_choice, is_rewarded=is_rewarded) + + def test_right_bait_resets_on_right_choice(self): + self.generator.is_right_baited = True + self.generator.update(self._make_outcome(is_right_choice=True, is_rewarded=True)) + self.assertFalse(self.generator.is_right_baited) + + def test_left_bait_resets_on_left_choice(self): + self.generator.is_left_baited = True + self.generator.update(self._make_outcome(is_right_choice=False, is_rewarded=True)) + self.assertFalse(self.generator.is_left_baited) + + def test_right_bait_preserved_on_left_choice(self): + self.generator.is_right_baited = True + self.generator.update(self._make_outcome(is_right_choice=False, is_rewarded=False)) + self.assertTrue(self.generator.is_right_baited) + + def test_left_bait_preserved_on_right_choice(self): + self.generator.is_left_baited = True + self.generator.update(self._make_outcome(is_right_choice=True, is_rewarded=True)) + self.assertTrue(self.generator.is_left_baited) + + def test_bait_not_reset_on_ignored_trial(self): + self.generator.is_right_baited = True + self.generator.is_left_baited = True + self.generator.update(self._make_outcome(is_right_choice=None, is_rewarded=False)) + self.assertTrue(self.generator.is_right_baited) + self.assertTrue(self.generator.is_left_baited) + + +if __name__ == "__main__": + unittest.main() diff --git a/uv.lock b/uv.lock index 4630dae..c95ca16 100644 --- a/uv.lock +++ b/uv.lock @@ -71,7 +71,7 @@ docs = [ [package.metadata] requires-dist = [ - { name = "aind-behavior-services", specifier = "<0.14" }, + { name = "aind-behavior-services", specifier = ">=0.13.2" }, { name = "contraqctor", marker = "extra == 'data'", specifier = ">=0.5.3" }, { name = "pydantic-settings" }, ] @@ -94,7 +94,7 @@ docs = [ [[package]] name = "aind-behavior-services" -version = "0.13.0" +version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aind-behavior-curriculum" }, @@ -103,9 +103,9 @@ dependencies = [ { name = "pydantic" }, { name = "semver" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/52/169fe25fb69cb249ac86408cad77bcce0950e60cc6491e0117c26f206e91/aind_behavior_services-0.13.0.tar.gz", hash = "sha256:21874c1a4555ab2a3c2afef895f279dda48ea0cc3dbc6a7a2ee6fbd7139dc544", size = 25839, upload-time = "2026-01-29T17:13:41.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/4b/3a5153a56ba92bf4cb8503b3670c58b0ce2dc1a38152a6888a654b2faefc/aind_behavior_services-0.13.2.tar.gz", hash = "sha256:506e9551c74db57026750f085b5f0034ba9896d9d7d496bf17977d4fc55b5f0f", size = 27357, upload-time = "2026-02-27T18:28:45.264Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/35/6df8230287d3747ff04192b16bd61aec4bbf4867271c619960f5f66ea222/aind_behavior_services-0.13.0-py3-none-any.whl", hash = "sha256:9b0fe77c0a4ecddf9fcf1b1d8e791de2e16ad36425d053fc587f195f88bb7286", size = 35478, upload-time = "2026-01-29T17:13:40.979Z" }, + { url = "https://files.pythonhosted.org/packages/49/ad/01b1da25639b2261159975b08e40e3fde74f73c01216cd83c1751ab23829/aind_behavior_services-0.13.2-py3-none-any.whl", hash = "sha256:2003a19aea0b0669088f02c8453c630bb0f0b3eb278c71d1107b972ac9171c8a", size = 37296, upload-time = "2026-02-27T18:28:44.055Z" }, ] [[package]]