basic simulators
ssms.basic_simulators.Simulator
Simulator(
model=None,
boundary=None,
drift=None,
simulator_function=None,
parameter_adapter=None,
parameter_adaptations=None,
**config_overrides
)
Class-based interface for Sequential Sampling Model simulations.
This class provides a flexible, extensible way to configure and run SSM simulations. It supports: - Pre-defined models (via string names like "ddm", "angle", etc.) - Custom boundary and drift functions with existing simulators - Fully custom simulator functions - Configuration overrides for any model parameter
Examples:
Basic usage with pre-defined model:
>>> sim = Simulator("ddm")
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3})
Custom boundary function:
>>> def my_boundary(t, theta, scale):
... return scale * np.sin(theta * t)
>>> sim = Simulator("ddm", boundary=my_boundary, boundary_params=["theta", "scale"])
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3,
... 'theta': 0.5, 'scale': 1.0})
Fully custom simulator:
>>> def my_sim(v, a, z, t, max_t=20, n_samples=1000, **kwargs):
... rts = np.random.exponential(1/abs(v), n_samples) + t
... choices = np.where(np.random.random(n_samples) < z, 1, -1)
... return {'rts': rts, 'choices': choices,
... 'metadata': {'model': 'custom', 'n_samples': n_samples}}
>>> sim = Simulator(simulator_function=my_sim, params=["v", "a", "z", "t"],
... nchoices=2)
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3})
Attributes:
-
config(dict) –The full model configuration dictionary
Parameters:
-
model(str, dict, or None, default:None) –Either a model name (e.g., "ddm", "angle"), a full configuration dictionary, or None if providing a custom simulator_function.
-
boundary(str, Callable, or None, default:None) –Boundary function. Can be: - A string name from the boundary registry (e.g., "angle", "weibull_cdf") - A callable function with signature: func(t, **params) -> np.ndarray - None to use the model's default boundary
-
drift(str, Callable, or None, default:None) –Drift function. Can be: - A string name from the drift registry (e.g., "constant", "gamma_drift") - A callable function with signature: func(t, **params) -> np.ndarray - None to use the model's default drift (if applicable)
-
simulator_function(Callable or None, default:None) –Custom simulator function. If provided, this overrides the model's default simulator. Must follow the simulator interface contract.
-
parameter_adapter(ParameterSimulatorAdapterProtocol or None, default:None) –Custom parameter adapter for preparing parameters for simulators. If None, uses ModularParameterSimulatorAdapter with default adaptations for the model.
-
parameter_adaptations(list[ParameterAdaptation] or None, default:None) –Additional parameter adaptations to apply AFTER the model's default adaptations. Useful for adding custom parameter preparation without replacing the entire adapter. Only used if parameter_adapter is None.
-
**config_overrides–Additional configuration parameters to override. Common options: - params : list[str] - Parameter names (required if simulator_function provided) - param_bounds : list - [[lower bounds], [upper bounds]] - nchoices : int - Number of choices (required if simulator_function provided) - choices : list - Possible choice values - boundary_params : list[str] - Parameters for custom boundary function - drift_params : list[str] - Parameters for custom drift function - name : str - Model name (for custom simulators)
Raises:
-
ValueError–If configuration is invalid or missing required parameters
Examples:
Use default modular adapter:
>>> sim = Simulator("lba2")
>>> results = sim.simulate(theta={'v0': 0.5, 'v1': 0.6, 'A': 0.5, 'b': 1.0})
Add custom adaptations:
>>> from ssms.basic_simulators.parameter_adapters import SetDefaultValue
>>> sim = Simulator("ddm", parameter_adaptations=[SetDefaultValue("custom_param", 42)])
Use a custom parameter adapter:
>>> custom_adapter = ModularParameterSimulatorAdapter()
>>> sim = Simulator("ddm", parameter_adapter=custom_adapter)
parameter_adapter
property
Get the configured parameter adapter.
Returns:
-
ParameterSimulatorAdapterProtocol–The parameter adapter instance used for parameter preparation
simulate
simulate(
theta,
n_samples=1000,
delta_t=0.001,
max_t=20,
no_noise=False,
sigma_noise=None,
smooth_unif=True,
random_state=None,
return_option="full",
n_threads=1,
extra_fields=None,
)
Run simulation with given parameters.
Parameters:
-
theta(list, np.ndarray, dict, or pd.DataFrame) –Model parameters. If dict or DataFrame, keys/columns should match parameter names in config. If array, order should match config['params'].
-
extra_fields(dict or None, default:None) –Optional per-trial covariates forwarded to the model function (e.g. the aDDM fixations
r1, r2, flag, sacc_array, d, sigma), so a covariate-driven model can condition on observed inputs rather than self-sampling them. Empty/None is a no-op for models that take no covariates. Arrays are per-trial (aligned withtheta's trial axis). -
n_samples(int, default:1000) –Number of simulation samples per parameter set
-
delta_t(float, default:0.001) –Time step size for simulation
-
max_t(float, default:20) –Maximum simulation time
-
no_noise(bool, default:False) –If True, disable noise in simulation
-
sigma_noise(float or None, default:None) –Standard deviation of noise. If None, uses model defaults.
-
smooth_unif(bool, default:True) –Whether to add uniform smoothing to RTs
-
random_state(int or None, default:None) –Integer seed for the C-level RNG. Must lie in
[-2**31, 2**31 - 1](fits a 32-bit signed Clong, required on Windows).Nonepicks a seed in[0, 2**31 - 1]automatically. -
return_option(str, default:"full") –Output format: "full" or "minimal"
-
n_threads(int, default:1) –Number of threads for parallel execution. If > 1 and OpenMP is available, uses multi-threaded simulation. Note: trajectory recording is only available with n_threads=1.
Returns:
-
dict–Simulation results with keys: - 'rts' : np.ndarray of reaction times - 'choices' : np.ndarray of choices - 'metadata' : dict with simulation metadata - Additional keys depending on model and return_option
Raises:
-
ValueError–If parameters are invalid
ssms.basic_simulators.boundary_functions
Define a collection of boundary functions for the simulators in the package.
addm_collapse
Linearly collapsing boundary for the attentional DDM: a - b * t.
The aDDM simulator uses this for the upper boundary and mirrors it (-(a - b
* t)) for the lower one. b >= 0 collapses the bounds over time; b = 0
recovers a constant boundary. This documents the boundary the cssm.addm
engine computes internally from its own a/b params.
Arguments
t (float or np.ndarray, optional): Time point(s). Defaults to 0.
a (float, optional): Boundary intercept at t=0. Defaults to 1.0.
b (float, optional): Collapse slope (>= 0). Defaults to 0.5.
Returns:
-
float or np.ndarray: ``a - b * t``.–
angle
module-attribute
angle = angle
Linear collapsing boundary at angle theta.
Arguments
t (float or np.ndarray, optional): Time point(s). Defaults to 1.
a (float, optional): Threshold parameter (starting height). Defaults to 1.0.
theta (float, optional): Collapse angle in radians. Defaults to 1.0.
Returns:
-
np.ndarray or float: Boundary value = a + t * tan(theta)–
conflict_gamma
module-attribute
conflict_gamma = conflict_gamma
Conflict boundary with gamma bump and linear collapse.
Arguments
t: (float, np.ndarray)
Time points (with arbitrary measure, but in HDDM it is used as seconds),
at which to evaluate the bound. Defaults to np.arange(0, 20, 0.1).
a: float
Threshold parameter (starting height). Defaults to 1.0.
theta: float
Collapse angle. Defaults to 0.5.
scale: float
Scaling the gamma distribution of the boundary
(since bound does not have to integrate to one). Defaults to 1.0.
alphaGamma: float
alpha parameter for a gamma in scale shape parameterization. Defaults to 1.01.
scaleGamma: float
scale parameter for a gamma in scale shape parameterization. Defaults to 0.3.
Returns:
-
np.ndarray: Boundary value = a + gamma_bump(t) + t*tan(theta)–
constant
module-attribute
constant = constant
Constant boundary function.
Arguments
t (float or np.ndarray, optional): Time point(s). Defaults to 0.
a (float, optional): Threshold parameter. Defaults to 1.0.
Returns:
-
float or np.ndarray: Constant boundary value = a (scalar if t is scalar, array if t is array)–
generalized_logistic
module-attribute
generalized_logistic = generalized_logistic
Generalized logistic boundary function.
Arguments
t (float or np.ndarray, optional): Time point(s). Defaults to 1.
a (float, optional): Threshold parameter. Defaults to 1.0.
B (float, optional): Growth rate. Defaults to 2.0.
M (float, optional): Time of maximum growth. Defaults to 3.0.
v (float, optional): Affects near which asymptote maximum growth occurs.
Defaults to 0.5.
Returns:
-
np.ndarray or float: Boundary value = a + logistic_decay(t)–
weibull_cdf
module-attribute
weibull_cdf = weibull_cdf
Weibull decay boundary function.
Arguments
t (float or np.ndarray, optional): Time point(s). Defaults to 1.
a (float, optional): Threshold parameter (starting height). Defaults to 1.0.
alpha (float, optional): Shape parameter. Defaults to 1.0.
beta (float, optional): Scale parameter. Defaults to 1.0.
Returns:
-
np.ndarray or float: Boundary value = a * exp(-(t/β)^α)–
ssms.basic_simulators.drift_functions
Define a collection of drift functions for the simulators in the package.
All drift functions accept v as a parameter and return the FINAL drift value,
consistent with boundary functions that accept a and return the final boundary value.
attend_drift
module-attribute
attend_drift = attend_drift
Shrink spotlight model, which involves a time varying function dependent on a linearly decreasing standard deviation of attention.
The final drift is v + (attention-weighted drift component).
Arguments
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate (typically 0 for shrink_spot models). Defaults to 0.0.
pouter: float
perceptual input for outer flankers
pinner: float
perceptual input for inner flankers
ptarget: float
perceptual input for target flanker
r: float
rate parameter for sda decrease
sda: float
width of attentional spotlight
Return
np.ndarray Final drift evaluated at timepoints t
attend_drift_simple
Drift function for shrinking spotlight model, which involves a time varying function dependent on a linearly decreasing standard deviation of attention.
The final drift is v + (attention-weighted drift component).
Arguments
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate (typically 0 for shrink_spot models). Defaults to 0.0.
pouter: float
perceptual input for outer flankers
ptarget: float
perceptual input for target flanker
r: float
rate parameter for sda decrease
sda: float
width of attentional spotlight
Return
np.ndarray Final drift evaluated at timepoints t
conflict_ds_drift
module-attribute
conflict_ds_drift = conflict_ds_drift
This drift is inspired by a conflict task which involves a target and a distractor stimuli both presented simultaneously.
Two drift timecourses are linearly combined weighted by the coherence in the respective target and distractor stimuli. Each timecourse follows a dynamical system as described in the ds_support_analytic() function.
The final drift is v + (combined drift timecourse).
Arguments
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate (typically 0 for conflict models). Defaults to 0.0.
tinit: float
Initial condition of target drift timecourse
dinit: float
Initial condition of distractor drift timecourse
tslope: float
Slope parameter for target drift timecourse
dslope: float
Slope parameter for distractor drift timecourse
tfixedp: float
Fixed point for target drift timecourse
tcoh: float
Coefficient for the target drift timecourse
dcoh: float
Coefficient for the distractor drift timecourse
Return
np.ndarray The full drift timecourse evaluated at the supplied timepoints t.
conflict_dsstimflex_drift
module-attribute
conflict_dsstimflex_drift = conflict_dsstimflex_drift
Drift function for conflict task with stimuli with potentially variable onset.
The final drift is v + (combined drift timecourse).
Arguments:
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate (typically 0 for conflict models). Defaults to 0.0.
tcoh: float
Coherence of the target stimulus when 'on'.
dcoh: float
Coherence of the distractor stimulus when 'on'.
tinit: float
Initial condition of target drift timecourse.
dinit: float
Initial condition of distractor drift timecourse.
tslope: float
Slope parameter for target drift timecourse.
dslope: float
Slope parameter for distractor drift timecourse.
tfixedp: float
Fixed point for target drift timecourse.
tonset: float
Onset time of the target stimulus coherence.
donset: float
Onset time of the distractor stimulus coherence.
rel_first: bool
If True, the first stimulus to appear (target or distractor)
is treated as appearing at time 0, and the other stimulus
is adjusted accordingly. If False, the onsets are treated
as absolute times.
conflict_stimflex_drift
module-attribute
conflict_stimflex_drift = conflict_stimflex_drift
Drift function for conflict task with stimuli with potentially variable onset and duration.
The final drift is v + (combined drift timecourse) when sum_drifts=True. When sum_drifts=False, returns 2D array for dual-drift models (v not added).
Arguments:
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate (typically 0 for conflict models). Defaults to 0.0.
Only used when sum_drifts=True.
tcoh: float
Coherence of the target stimulus when 'on'.
dcoh: float
Coherence of the distractor stimulus when 'on'.
vt: float
Static drift-rate of target stimulus, when 'on'.
vd: float
Static drift-rate of distractor stimulus, when 'on'.
tonset: float
Onset time of the target stimulus coherence.
donset: float
Onset time of the distractor stimulus coherence.
toffset, doffset: float or None
Duration of the stimulus coherence pulse. If None, the pulse
lasts until the end of the trial.
rel_first: bool
If True, the first stimulus to appear (target or distractor)
is treated as appearing at time 0, and the other stimulus
is adjusted accordingly. If False, the onsets are treated
as absolute times.
sum_drifts: bool
If True, the drift contributions from target and distractor
are summed to produce a single drift timecourse. If False,
a 2D array is returned with separate columns for target
and distractor drift timecourses (for dual-drift models).
Returns:
-
np.ndarray: Array of drift values, same length as t. If sum_drifts–is False, the array has shape (len(t), 2)
constant
module-attribute
constant = constant
Constant drift function.
Arguments
t: np.ndarray, optional
Timepoints at which to evaluate the drift. Defaults to
np.arange(0, 20, 0.1).
v: float, optional
Drift rate. Defaults to 0.0.
Returns:
-
np.ndarray: Array of constant drift values = v, same length as t–
ds_support_analytic
module-attribute
ds_support_analytic = ds_support_analytic
Solve DE.
DE is of the form: x' = slope*(fix_point - x), with initial condition init_p. The solution takes the form: (init_p - fix_point) * exp(-slope * t) + fix_point
Arguments
t: np.ndarray
Timepoints at which to evaluate the drift. Usually np.arange() of some sort.
init_p: float
Initial condition of dynamical system
fix_point: float
Fixed point of dynamical system
slope: float
Coefficient in exponent of the solution.
Return
np.ndarray The gamma drift evaluated at the supplied timepoints t.
gamma_drift
module-attribute
gamma_drift = gamma_drift
Drift function that follows a scaled gamma distribution.
The final drift is v + (scaled gamma component).
Arguments
t: np.ndarray
Timepoints at which to evaluate the drift.
Usually np.arange() of some sort.
v: float
Base drift rate. Defaults to 0.0.
shape: float
Shape parameter of the gamma distribution
scale: float
Scale parameter of the gamma distribution
c: float
Scalar parameter that scales the peak of
the gamma distribution.
(Note this function follows a gamma distribution
but does not integrate to 1)
Return
np.ndarray
The final drift (v + gamma component) evaluated at the supplied timepoints t.
stimflex_support
Construct a rectangular coherence timecourse, with discrete and potentially variable onsets and offsets of stimulus evidence.
Arguments
t: np.ndarray
Timepoints within trial.
onset: float
Onset time of the coherence pulse.
offset: float
Offset time of the coherence pulse.
coh: float
Coherence of the stimulus when 'on'.
Returns:
-
np.ndarray: Array of coherence values, same length as t.–
ssms.basic_simulators.fixation_continuation
Pluggable fixation-continuation strategies + a positive-distribution factory for the aDDM.
The aDDM posterior-predictive path conditions on observed fixations (Mode 2). When a
re-simulated particle has not decided by the last observed fixation, the drift "freezes" at
the last gaze. This module makes that tail behaviour pluggable, and shares a scipy.stats
positive-distribution factory with the aDDM's Mode-1 self-sampling.
Strategies (name -> callable), each mapping
(node_r, d_r, flag_r, T, params, rng) -> (node_r, d_r, flag_r, max_d):
prolong_last_fixation-- no new fixations; the engine holds the last gaze toT(today's behaviour; the default).sample_continuation-- keep the observed fixations; draw the continuation (tail) durations from a chosen positive distribution and keep alternating past the last observed onset. (Appending an onset after the last observed onset resamples the censored last fixation's duration; further onsets are new alternating fixations.)resample_all_fixations-- ignore the observed fixation schedule; keep the observed stimulus (r1/r2untouched upstream), re-sample the first-gazeflagand a fresh schedule. The drift still conditions on the stimulus, so the PPC stays comparable to data.
All durations come from :data:POSITIVE_DISTRIBUTIONS (scipy.stats), so any positive-support
distribution is available by name with scipy-native parameters. Mirrors the
attention_process registry idiom (name -> callable + a resolve_* helper).
draw_durations
Draw an array of size positive durations from dist_name (scipy-native params).
generate_schedule
Self-sample a padded (n, max_d) fixation-onset schedule + per-row stage count d.
Durations are drawn from dist_name and cumulatively summed; column 0 is anchored at 0.0
(trial start). d = number of onsets strictly before T (>=1). The pre-draw budget is
sized from the distribution's analytic mean, then over-allocated columns (onsets >= T) are
trimmed to the realised max_d.
prolong_last_fixation
No continuation: the engine holds the last observed gaze to T (today's behaviour).
resample_all_fixations
Ignore observed fixations; re-sample first-gaze + a fresh schedule (keep stimulus r1/r2).
resolve_continuation_mode
Resolve a registry name or a callable to a concrete continuation strategy.
resolve_distribution
Return the scipy.stats distribution registered under name.
ssms.basic_simulators.inv_temp_softmax
ssms.basic_simulators.modular_parameter_simulator_adapter
Modular parameter simulator adapter using adaptation pipelines.
This module provides the ModularParameterSimulatorAdapter class which applies parameter adaptations defined in model_config['parameter_transforms']['simulation'].
ModularParameterSimulatorAdapter
Modular parameter simulator adapter using config-defined transforms.
This adapter applies a sequence of parameter adaptations defined in the
model configuration's parameter_transforms.simulation field.
All built-in models define their simulation transforms directly in their model config, making this adapter simple and transparent.
Examples:
>>> adapter = ModularParameterSimulatorAdapter()
>>> theta = adapter.adapt_parameters(theta, model_config, n_trials)
The model_config should have transforms defined like:
>>> model_config = {
... "name": "lba_angle_3",
... "parameter_transforms": {
... "sampling": [...],
... "simulation": [
... ColumnStackParameters(["v0", "v1", "v2"], "v"),
... ExpandDimension(["a", "z", "theta"]),
... SetZeroArray("t"),
... ],
... },
... }
adapt_parameters
Process theta by applying config-defined transformations.
Parameters:
-
theta(dict[str, Any]) –Dictionary of theta parameters
-
model_config(dict[str, Any]) –Model configuration dictionary containing
parameter_transforms -
n_trials(int) –Number of trials
Returns:
-
dict[str, Any]–Processed theta parameters
ParameterSimulatorAdapterProtocol
Bases: Protocol
Protocol defining the interface for parameter adapters.
Any class that implements an adapt_parameters method with this signature
can be used as a parameter adapter.
adapt_parameters
Adapt theta parameters for simulator consumption.
Parameters:
-
theta(dict[str, Any]) –Dictionary of theta parameters
-
model_config(dict[str, Any]) –Model configuration dictionary
-
n_trials(int) –Number of trials
Returns:
-
dict[str, Any]–Processed theta parameters
ssms.basic_simulators.parameter_adapters
Parameter adaptation system for modular parameter processing.
This module provides a composable system for adapting parameters before they are passed to simulators. Adaptations are small, focused classes that can be combined to handle complex parameter preparation logic.
Main Components: - ParameterAdaptation: Alias for ParameterTransform (backward compatibility) - Common adaptations: SetDefaultValue, ExpandDimension, etc. - ParameterAdapterRegistry: Maps models to adaptation pipelines - ModularParameterSimulatorAdapter: Applies adaptations in sequence
Example: >>> from ssms.basic_simulators.parameter_adapters import ( ... ExpandDimension, ColumnStackParameters ... ) >>> >>> adaptations = [ ... ColumnStackParameters(["v0", "v1", "v2"], "v"), ... ExpandDimension(["a", "t"]) ... ] >>> >>> for adaptation in adaptations: ... theta = adaptation.apply(theta, model_config, n_trials)
Note: New code should import directly from ssms.transforms.simulation for the common adaptation classes. This module re-exports them for backward compatibility.
ApplyMapping
ApplyMapping(
source_param,
target_param,
mapping_key,
additional_sources=None,
delete_source=False,
)
Bases: ParameterTransform
Apply a mapping function to transform a parameter.
Uses a mapping from model_config to transform a parameter value. Commonly used for random variable distributions.
Parameters:
-
source_param(str) –Parameter to read from
-
target_param(str) –Parameter to write to
-
mapping_key(str) –Key in model_config["simulator_param_mappings"]
-
additional_sources(list[str], default:None) –Additional parameters to pass to the mapping function
-
delete_source(bool, default:False) –Whether to delete the source parameter after mapping
ColumnStackParameters
Bases: ParameterTransform
Stack multiple parameters into a single multi-column array.
Takes individual parameters (e.g., v0, v1, v2) and stacks them column-wise into a single array (e.g., v with shape (n_trials, 3)).
Parameters:
-
source_params(list[str]) –Names of parameters to stack
-
target_param(str) –Name of the resulting stacked parameter
-
delete_sources(bool, default:True) –Whether to delete the source parameters after stacking
Examples:
ConditionalAdaptation
Bases: ParameterTransform
Apply a transform only if a condition is met.
Parameters:
-
condition(Callable) –Function that takes (theta, model_config, n_trials) and returns bool
-
transformation(ParameterTransform) –Transform to apply if condition is True
Examples:
DeleteParameters
Bases: ParameterTransform
Delete specified parameters from theta.
Parameters:
-
param_names(list[str]) –Names of parameters to delete
Examples:
ExpandDimension
Bases: ParameterTransform
Expand dimensions of specified parameters.
Converts 1D arrays of shape (n_trials,) to shape (n_trials, 1) by adding a dimension. This is commonly needed for multi-particle models.
Parameters:
-
param_names(list[str]) –Names of parameters to expand
Examples:
LambdaAdaptation
Bases: ParameterTransform
Wrap a lambda or callable function as a transform.
Parameters:
-
func(Callable) –Function with signature: func(theta, model_config, n_trials) → theta
-
name(str, default:None) –Optional name for debugging
Examples:
ParameterAdapterRegistry
Registry mapping models to parameter adaptation pipelines.
The registry supports two types of lookups: 1. Exact model match: Direct lookup by model name 2. Family match: Pattern-based matching using lambda functions
Exact matches take precedence over family matches, allowing specific models to override family defaults.
Examples:
>>> registry = ParameterAdapterRegistry()
>>>
>>> # Register exact model
>>> registry.register_model("lba2", [
... SetDefaultValue("nact", 2),
... ColumnStackParameters(["v0", "v1"], "v")
... ])
>>>
>>> # Register model family
>>> registry.register_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Lookup
>>> adaptations = registry.get_processor("lba2") # Exact match
>>> adaptations = registry.get_processor("race_no_bias_2") # Family match
describe
Get human-readable description of adaptations for a model.
Parameters:
-
model_name(str) –Name of the model
Returns:
-
str–Description of the adaptation pipeline
Examples:
get_processor
Get adaptation pipeline for a model.
Lookup priority: 1. Exact model name match 2. First matching family 3. Empty list (no adaptations)
Parameters:
-
model_name(str) –Name of the model to look up
Returns:
-
list[ParameterAdaptation]–List of adaptations to apply (empty list if no match)
Examples:
>>> adaptations = registry.get_processor("lba2")
>>> # Returns registered adaptations for "lba2"
>>>
>>> adaptations = registry.get_processor("race_no_bias_2")
>>> # Returns adaptations for "race_2" family (if registered)
>>>
>>> adaptations = registry.get_processor("unknown_model")
>>> # Returns [] (empty list)
has_processor
Check if a processor is registered for a model.
This checks if the model has a registration (exact or family match), even if the transformation list is empty.
Parameters:
-
model_name(str) –Name of the model to check
Returns:
-
bool–True if model has a registration (explicit or via family)
list_registered_families
Get list of registered family names.
Returns:
-
list[str]–List of family names
list_registered_models
Get list of explicitly registered model names.
Returns:
-
list[str]–List of model names with exact registrations
register_family
Register adaptations for a family of models.
The matcher function determines which models belong to this family. It receives a model name and should return True if the model matches.
Parameters:
-
family_name(str) –Name for this model family (used as key)
-
matcher(Callable[[str], bool]) –Function that takes a model name and returns True if it matches
-
adaptations(list[ParameterAdaptation]) –List of adaptations to apply for matching models
Examples:
>>> registry = ParameterAdapterRegistry()
>>>
>>> # Match all race models with 2 choices
>>> registry.register_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Match all models with "no_bias" in the name
>>> registry.register_family(
... "no_bias_models",
... lambda m: "no_bias" in m,
... [SetDefaultValue("z", 0.5)]
... )
register_model
Register adaptations for a specific model.
Parameters:
-
model_name(str) –Exact model name (e.g., "lba2", "ddm", "race_3")
-
adaptations(list[ParameterAdaptation]) –List of adaptations to apply for this model
Examples:
RenameParameter
Bases: ParameterTransform
Rename a parameter and optionally transform its value.
Parameters:
-
old_name(str) –Current parameter name
-
new_name(str) –New parameter name
-
transform_fn(Callable or None, default:None) –Optional function to apply to the value during renaming
Examples:
SetDefaultValue
Bases: ParameterTransform
Set a parameter to a default value if not present.
This transform adds a parameter with a default value if it doesn't already exist in theta. The value is automatically tiled to match n_trials.
Parameters:
-
param_name(str) –Name of the parameter to set
-
default_value(float or int or ndarray) –Default value to use. If scalar, will be tiled to (n_trials,).
-
dtype(dtype, default:float32) –Data type for the parameter. Defaults to np.float32.
Examples:
SetZeroArray
Bases: ParameterTransform
Set a parameter to an array of zeros.
Parameters:
-
param_name(str) –Name of the parameter to set
-
shape(tuple or None, default:None) –Shape of the array. Use None for n_trials dimension.
-
dtype(dtype, default:float32) –Data type for the array. Defaults to np.float32.
Examples:
TileArray
Bases: ParameterTransform
Tile a constant value across trials.
Parameters:
-
param_name(str) –Name of the parameter to create
-
value(float or array - like) –Value(s) to tile
-
dtype(dtype, default:float32) –Data type for the array. Defaults to np.float32.
Examples:
base
Base classes for parameter adaptations.
This module provides backward compatibility by re-exporting ParameterTransform as ParameterAdaptation.
Note: New code should use ParameterTransform from ssms.transforms.base directly.
ParameterTransform
Bases: ABC
Abstract base class for all parameter transforms.
A parameter transform is a single, focused operation that modifies theta parameters. Transforms can be composed into pipelines and are used at two phases:
-
Sampling phase: Applied after parameter sampling to enforce constraints (e.g., ensure a > z by swapping values)
-
Simulation phase: Applied before calling the simulator to prepare parameters for the expected format (e.g., stack v0, v1 → v)
Subclasses must implement the apply method. The method signature
includes optional model_config and n_trials arguments to support
both simple constraints (which only need theta) and complex adapters
(which may need additional context).
Examples:
Create a custom transform:
>>> class ScaleParameter(ParameterTransform):
... def __init__(self, param_name: str, scale: float):
... self.param_name = param_name
... self.scale = scale
...
... def apply(self, theta, model_config=None, n_trials=None):
... if self.param_name in theta:
... theta[self.param_name] = theta[self.param_name] * self.scale
... return theta
Use in model config:
>>> model_config = {
... "name": "my_model",
... "parameter_transforms": {
... "sampling": [SwapIfLessConstraint("a", "z")],
... "simulation": [ColumnStackParameters(["v0", "v1"], "v")],
... }
... }
__repr__
String representation for debugging.
Returns:
-
str–A string describing this transform.
apply
abstractmethod
Apply transform to theta parameters.
This method should modify the theta dictionary in place and return it. It may add new parameters, modify existing parameters, or remove parameters as needed.
Parameters:
-
theta(dict[str, Any]) –Dictionary of model parameters. Values are typically numpy arrays.
-
model_config(dict[str, Any] or None, default:None) –Model configuration dictionary. Available for transforms that need additional context (e.g., looking up simulator_fixed_params). Sampling-time transforms typically ignore this.
-
n_trials(int or None, default:None) –Number of trials. Available for transforms that need to create arrays of a specific size. Sampling-time transforms typically ignore this.
Returns:
-
dict[str, Any]–The modified theta dictionary (usually the same object passed in).
Notes
- Transforms should be pure when possible (no side effects)
- If creating new arrays, use dtype=np.float32 for consistency
- Document any parameters that are added, modified, or removed
get_adapter_registry
Get the global parameter adapter registry.
Use this to access registry methods like list_registered_models() or get_processor() directly.
Returns:
-
ParameterAdapterRegistry–The global parameter adapter registry instance, pre-populated with all built-in model adaptations
Examples:
>>> from ssms.basic_simulators.parameter_adapters import get_adapter_registry
>>>
>>> # List all models with registered adaptations
>>> registry = get_adapter_registry()
>>> print(registry.list_registered_models())
['lba2', 'lba3', 'lca_3', ...]
>>>
>>> # Check if a model has adaptations
>>> if registry.has_processor("my_model"):
... adaptations = registry.get_processor("my_model")
>>>
>>> # Describe adaptations for a model
>>> print(registry.describe("lba3"))
register_adapter_to_model
Register parameter adaptations to a specific model globally.
This associates existing parameter adaptation classes with a model. Once registered, the model will use these adaptations automatically when simulated with ModularParameterSimulatorAdapter.
Note: This registers which adaptations a MODEL uses, not a new adapter type. To create custom adapter types, subclass ParameterAdaptation directly.
Parameters:
-
model_name(str) –Unique model name
-
adaptations(list[ParameterAdaptation]) –List of parameter adaptation instances to apply for this model
Examples:
Register adaptations for a custom model:
>>> from ssms.basic_simulators.parameter_adapters import register_adapter_to_model
>>> from ssms.basic_simulators.parameter_adapters import (
... SetDefaultValue, ExpandDimension, ColumnStackParameters
... )
>>>
>>> register_adapter_to_model("my_model", [
... SetDefaultValue("z", 0.5),
... ExpandDimension(["a", "t"]),
... ColumnStackParameters(["v0", "v1"], "v"),
... ])
>>>
>>> # Now when simulating with this model, adaptations are applied automatically
>>> sim = Simulator(model="my_model")
Override built-in model adaptations:
register_adapter_to_model_family
Register parameter adaptations to a family of models globally.
This associates existing parameter adaptation classes with multiple models matching a pattern, without having to register each model individually.
Parameters:
-
family_name(str) –Name for this model family (used as identifier)
-
matcher(Callable[[str], bool]) –Function that returns True if a model name matches this family
-
adaptations(list[ParameterAdaptation]) –List of parameter adaptation instances to apply for matching models
Examples:
Register adaptations for all race models with 2 alternatives:
>>> from ssms.basic_simulators.parameter_adapters import register_adapter_to_model_family
>>> from ssms.basic_simulators.parameter_adapters import ColumnStackParameters
>>>
>>> register_adapter_to_model_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Now all models matching the pattern use these adaptations
>>> # e.g., "race_no_bias_2", "race_no_z_2", etc.
Register for models with specific naming pattern:
registry
Registry system for mapping models to parameter adaptations.
The registry provides a centralized way to associate model names with their required parameter adaptations. It supports both exact model matching and pattern-based family matching.
ParameterAdapterRegistry
Registry mapping models to parameter adaptation pipelines.
The registry supports two types of lookups: 1. Exact model match: Direct lookup by model name 2. Family match: Pattern-based matching using lambda functions
Exact matches take precedence over family matches, allowing specific models to override family defaults.
Examples:
>>> registry = ParameterAdapterRegistry()
>>>
>>> # Register exact model
>>> registry.register_model("lba2", [
... SetDefaultValue("nact", 2),
... ColumnStackParameters(["v0", "v1"], "v")
... ])
>>>
>>> # Register model family
>>> registry.register_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Lookup
>>> adaptations = registry.get_processor("lba2") # Exact match
>>> adaptations = registry.get_processor("race_no_bias_2") # Family match
describe
Get human-readable description of adaptations for a model.
Parameters:
-
model_name(str) –Name of the model
Returns:
-
str–Description of the adaptation pipeline
Examples:
get_processor
Get adaptation pipeline for a model.
Lookup priority: 1. Exact model name match 2. First matching family 3. Empty list (no adaptations)
Parameters:
-
model_name(str) –Name of the model to look up
Returns:
-
list[ParameterAdaptation]–List of adaptations to apply (empty list if no match)
Examples:
>>> adaptations = registry.get_processor("lba2")
>>> # Returns registered adaptations for "lba2"
>>>
>>> adaptations = registry.get_processor("race_no_bias_2")
>>> # Returns adaptations for "race_2" family (if registered)
>>>
>>> adaptations = registry.get_processor("unknown_model")
>>> # Returns [] (empty list)
has_processor
Check if a processor is registered for a model.
This checks if the model has a registration (exact or family match), even if the transformation list is empty.
Parameters:
-
model_name(str) –Name of the model to check
Returns:
-
bool–True if model has a registration (explicit or via family)
list_registered_families
Get list of registered family names.
Returns:
-
list[str]–List of family names
list_registered_models
Get list of explicitly registered model names.
Returns:
-
list[str]–List of model names with exact registrations
register_family
Register adaptations for a family of models.
The matcher function determines which models belong to this family. It receives a model name and should return True if the model matches.
Parameters:
-
family_name(str) –Name for this model family (used as key)
-
matcher(Callable[[str], bool]) –Function that takes a model name and returns True if it matches
-
adaptations(list[ParameterAdaptation]) –List of adaptations to apply for matching models
Examples:
>>> registry = ParameterAdapterRegistry()
>>>
>>> # Match all race models with 2 choices
>>> registry.register_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Match all models with "no_bias" in the name
>>> registry.register_family(
... "no_bias_models",
... lambda m: "no_bias" in m,
... [SetDefaultValue("z", 0.5)]
... )
register_model
Register adaptations for a specific model.
Parameters:
-
model_name(str) –Exact model name (e.g., "lba2", "ddm", "race_3")
-
adaptations(list[ParameterAdaptation]) –List of adaptations to apply for this model
Examples:
get_adapter_registry
Get the global parameter adapter registry.
Use this to access registry methods like list_registered_models() or get_processor() directly.
Returns:
-
ParameterAdapterRegistry–The global parameter adapter registry instance, pre-populated with all built-in model adaptations
Examples:
>>> from ssms.basic_simulators.parameter_adapters import get_adapter_registry
>>>
>>> # List all models with registered adaptations
>>> registry = get_adapter_registry()
>>> print(registry.list_registered_models())
['lba2', 'lba3', 'lca_3', ...]
>>>
>>> # Check if a model has adaptations
>>> if registry.has_processor("my_model"):
... adaptations = registry.get_processor("my_model")
>>>
>>> # Describe adaptations for a model
>>> print(registry.describe("lba3"))
register_adapter_to_model
Register parameter adaptations to a specific model globally.
This associates existing parameter adaptation classes with a model. Once registered, the model will use these adaptations automatically when simulated with ModularParameterSimulatorAdapter.
Note: This registers which adaptations a MODEL uses, not a new adapter type. To create custom adapter types, subclass ParameterAdaptation directly.
Parameters:
-
model_name(str) –Unique model name
-
adaptations(list[ParameterAdaptation]) –List of parameter adaptation instances to apply for this model
Examples:
Register adaptations for a custom model:
>>> from ssms.basic_simulators.parameter_adapters import register_adapter_to_model
>>> from ssms.basic_simulators.parameter_adapters import (
... SetDefaultValue, ExpandDimension, ColumnStackParameters
... )
>>>
>>> register_adapter_to_model("my_model", [
... SetDefaultValue("z", 0.5),
... ExpandDimension(["a", "t"]),
... ColumnStackParameters(["v0", "v1"], "v"),
... ])
>>>
>>> # Now when simulating with this model, adaptations are applied automatically
>>> sim = Simulator(model="my_model")
Override built-in model adaptations:
register_adapter_to_model_family
Register parameter adaptations to a family of models globally.
This associates existing parameter adaptation classes with multiple models matching a pattern, without having to register each model individually.
Parameters:
-
family_name(str) –Name for this model family (used as identifier)
-
matcher(Callable[[str], bool]) –Function that returns True if a model name matches this family
-
adaptations(list[ParameterAdaptation]) –List of parameter adaptation instances to apply for matching models
Examples:
Register adaptations for all race models with 2 alternatives:
>>> from ssms.basic_simulators.parameter_adapters import register_adapter_to_model_family
>>> from ssms.basic_simulators.parameter_adapters import ColumnStackParameters
>>>
>>> register_adapter_to_model_family(
... "race_2",
... lambda m: m.startswith("race_") and m.endswith("_2"),
... [ColumnStackParameters(["v0", "v1"], "v")]
... )
>>>
>>> # Now all models matching the pattern use these adaptations
>>> # e.g., "race_no_bias_2", "race_no_z_2", etc.
Register for models with specific naming pattern:
ssms.basic_simulators.simulator
This module defines the basic simulator function which is the main workshorse of the package. In addition some utility functions are provided that help with preprocessing the output of the simulator function.
bin_simulator_output
Turns RT part of simulator output into bin-identifier by trial
Arguments
out : dict
Output of the 'simulator' function
bin_dt : float
If nbins is 0, this determines the desired
bin size which in turn automatically
determines the resulting number of bins.
nbins : int
Number of bins to bin reaction time data into.
If supplied as 0, bin_dt instead determines the number of
bins automatically.
max_t : float <default=-1>
Override the 'max_t' metadata as part of the simulator output.
Sometimes useful, but usually default will do the job.
freq_cnt : bool <default=False>
Decide whether to return proportions (default) or counts in bins.
Returns:
-
A histogram of counts or proportions.–
bin_simulator_output_pointwise
Turns RT part of simulator output into bin-identifier by trial
Arguments
out: dict
Output of the 'simulator' function
bin_dt: float
If nbins is 0, this determines the desired
bin size which in turn automatically
determines the resulting number of bins.
nbins: int
Number of bins to bin reaction time data into.
If supplied as 0, bin_dt instead determines the
number of bins automatically.
Returns:
-
2d array. The first columns collects bin-identifiers–by trial, the second column lists the corresponding choices.
make_boundary_dict
Create a dictionary containing boundary-related parameters and functions.
This function extracts boundary-related parameters from the input theta dictionary, based on the boundary configuration specified in the config. It also retrieves the appropriate boundary function from the boundary registry.
Args: config (dict): A dictionary containing model configuration, including the boundary name. theta (dict): A dictionary of parameter values, potentially including boundary-related parameters.
Returns: dict: A dictionary containing: - boundary_params (dict): Extracted boundary-related parameters (including 'a'). - boundary_fun (callable): The boundary function corresponding to the specified boundary name.
make_drift_dict
Create a dictionary containing drift-related parameters and functions.
This function extracts drift-related parameters from the input theta dictionary, based on the drift configuration specified in the config. It also retrieves the appropriate drift function from the drift registry.
Args: config (dict): A dictionary containing model configuration, including the drift name. theta (dict): A dictionary of parameter values, potentially including drift-related parameters.
Returns: dict: A dictionary containing: - drift_fun (callable): The drift function corresponding to the specified drift name. - drift_params (dict): Extracted drift-related parameters. If no drift name is specified in config, returns an empty dictionary.
make_noise_vec
Create a noise vector for simulation.
This function generates a noise vector based on the provided sigma_noise parameter, replicating it across trials and particles as needed.
Arguments
sigma_noise (float | np.ndarray): Standard deviation of the noise. Can be a single float value
or a numpy array.
n_trials (int): Number of trials to simulate.
n_particles (int): Number of particles per trial.
Returns:
-
np.ndarray: A noise vector with appropriate shape for the simulation,–containing the replicated sigma_noise values.
simulator
simulator(
theta,
model="angle",
n_samples=1000,
delta_t=0.001,
max_t=20,
no_noise=False,
sigma_noise=None,
smooth_unif=True,
random_state=None,
return_option="full",
n_threads=1,
extra_fields=None,
)
Basic data simulator for the models included in HDDM.
Arguments
theta : list, numpy.array, dict or pd.DataFrame
Parameters of the simulator. If 2d array, each row is treated as a 'trial'
and the function runs n_sample * n_trials simulations.
deadline : numpy.array <default=None>
If supplied, the simulator will run a deadline model. RTs will be returned
model: str <default='angle'>
Determines the model that will be simulated.
n_samples: int <default=1000>
Number of simulation runs for each row in the theta argument.
delta_t: float
Size fo timesteps in simulator (conceptually measured in seconds)
max_t: float
Maximum reaction the simulator can reach
no_noise: bool <default=False>
Turn noise of (useful for plotting purposes mostly)
sigma_noise: float | None <default=None>
Standard deviation of noise in the diffusion process. If None, defaults to 1.0 for most models
and 0.1 for LBA models. If no_noise is True, sigma_noise will be set to 0.0.
If 'sd' or 's' is passed via theta dictionary, sigma_noise must be None.
smooth_unif: bool <default=True>
Whether to add uniform random noise to RTs to smooth the distributions.
random_state: int | None <default=None>
Integer passed to the C-level RNG seeding. Must lie in
``[-2**31, 2**31 - 1]`` so it fits in a 32-bit signed C ``long`` (required
on Windows). ``None`` draws a seed from that range automatically.
Non-integer RNG objects may be supported on specific code paths.
return_option: str <default='full'>
Determines what the function returns. Can be either
'full' or 'minimal'. If 'full' the function returns
a dictionary with keys 'rts', 'responses' and 'metadata', and
metadata contains the model parameters and some additional
information. 'metadata' is a simpler dictionary with less information
if 'minimal' is chosen.
n_threads: int <default=1>
Number of threads for parallel execution. If > 1 and OpenMP is available,
uses multi-threaded simulation. Note: trajectory recording is only
available with n_threads=1. For models that don't support n_threads yet,
this parameter is silently ignored.
**Reproducibility note:** the sequential path (n_threads=1) uses NumPy's
RNG, while the parallel path (n_threads>1) uses a C-level GSL/Ziggurat
RNG. Results with a fixed ``random_state`` are reproducible *within* a
given ``n_threads`` value, but will differ *across* n_threads values.
Both paths produce statistically equivalent distributions.
Return
dictionary where keys can be (rts, responses, metadata) or (rt-response histogram, metadata) or (rts binned pointwise, responses, metadata)
validate_ssm_parameters
Validate the parameters for Sequential Sampling Models (SSM).
This function checks the validity of parameters for different SSM models. It performs specific checks based on the model type.
Args: model (str): The name of the SSM model. theta (dict): A dictionary containing the model parameters.
Raises: ValueError: If any of the parameter validations fail.
ssms.basic_simulators.simulator_class
Class-based interface for Sequential Sampling Model simulations.
This module provides a modern, object-oriented interface for SSM simulations that supports custom boundary functions, drift functions, and even fully custom simulator implementations.
Simulator
Simulator(
model=None,
boundary=None,
drift=None,
simulator_function=None,
parameter_adapter=None,
parameter_adaptations=None,
**config_overrides
)
Class-based interface for Sequential Sampling Model simulations.
This class provides a flexible, extensible way to configure and run SSM simulations. It supports: - Pre-defined models (via string names like "ddm", "angle", etc.) - Custom boundary and drift functions with existing simulators - Fully custom simulator functions - Configuration overrides for any model parameter
Examples:
Basic usage with pre-defined model:
>>> sim = Simulator("ddm")
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3})
Custom boundary function:
>>> def my_boundary(t, theta, scale):
... return scale * np.sin(theta * t)
>>> sim = Simulator("ddm", boundary=my_boundary, boundary_params=["theta", "scale"])
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3,
... 'theta': 0.5, 'scale': 1.0})
Fully custom simulator:
>>> def my_sim(v, a, z, t, max_t=20, n_samples=1000, **kwargs):
... rts = np.random.exponential(1/abs(v), n_samples) + t
... choices = np.where(np.random.random(n_samples) < z, 1, -1)
... return {'rts': rts, 'choices': choices,
... 'metadata': {'model': 'custom', 'n_samples': n_samples}}
>>> sim = Simulator(simulator_function=my_sim, params=["v", "a", "z", "t"],
... nchoices=2)
>>> results = sim.simulate(theta={'v': 0.5, 'a': 1.0, 'z': 0.5, 't': 0.3})
Attributes:
-
config(dict) –The full model configuration dictionary
Parameters:
-
model(str, dict, or None, default:None) –Either a model name (e.g., "ddm", "angle"), a full configuration dictionary, or None if providing a custom simulator_function.
-
boundary(str, Callable, or None, default:None) –Boundary function. Can be: - A string name from the boundary registry (e.g., "angle", "weibull_cdf") - A callable function with signature: func(t, **params) -> np.ndarray - None to use the model's default boundary
-
drift(str, Callable, or None, default:None) –Drift function. Can be: - A string name from the drift registry (e.g., "constant", "gamma_drift") - A callable function with signature: func(t, **params) -> np.ndarray - None to use the model's default drift (if applicable)
-
simulator_function(Callable or None, default:None) –Custom simulator function. If provided, this overrides the model's default simulator. Must follow the simulator interface contract.
-
parameter_adapter(ParameterSimulatorAdapterProtocol or None, default:None) –Custom parameter adapter for preparing parameters for simulators. If None, uses ModularParameterSimulatorAdapter with default adaptations for the model.
-
parameter_adaptations(list[ParameterAdaptation] or None, default:None) –Additional parameter adaptations to apply AFTER the model's default adaptations. Useful for adding custom parameter preparation without replacing the entire adapter. Only used if parameter_adapter is None.
-
**config_overrides–Additional configuration parameters to override. Common options: - params : list[str] - Parameter names (required if simulator_function provided) - param_bounds : list - [[lower bounds], [upper bounds]] - nchoices : int - Number of choices (required if simulator_function provided) - choices : list - Possible choice values - boundary_params : list[str] - Parameters for custom boundary function - drift_params : list[str] - Parameters for custom drift function - name : str - Model name (for custom simulators)
Raises:
-
ValueError–If configuration is invalid or missing required parameters
Examples:
Use default modular adapter:
>>> sim = Simulator("lba2")
>>> results = sim.simulate(theta={'v0': 0.5, 'v1': 0.6, 'A': 0.5, 'b': 1.0})
Add custom adaptations:
>>> from ssms.basic_simulators.parameter_adapters import SetDefaultValue
>>> sim = Simulator("ddm", parameter_adaptations=[SetDefaultValue("custom_param", 42)])
Use a custom parameter adapter:
>>> custom_adapter = ModularParameterSimulatorAdapter()
>>> sim = Simulator("ddm", parameter_adapter=custom_adapter)
parameter_adapter
property
Get the configured parameter adapter.
Returns:
-
ParameterSimulatorAdapterProtocol–The parameter adapter instance used for parameter preparation
simulate
simulate(
theta,
n_samples=1000,
delta_t=0.001,
max_t=20,
no_noise=False,
sigma_noise=None,
smooth_unif=True,
random_state=None,
return_option="full",
n_threads=1,
extra_fields=None,
)
Run simulation with given parameters.
Parameters:
-
theta(list, np.ndarray, dict, or pd.DataFrame) –Model parameters. If dict or DataFrame, keys/columns should match parameter names in config. If array, order should match config['params'].
-
extra_fields(dict or None, default:None) –Optional per-trial covariates forwarded to the model function (e.g. the aDDM fixations
r1, r2, flag, sacc_array, d, sigma), so a covariate-driven model can condition on observed inputs rather than self-sampling them. Empty/None is a no-op for models that take no covariates. Arrays are per-trial (aligned withtheta's trial axis). -
n_samples(int, default:1000) –Number of simulation samples per parameter set
-
delta_t(float, default:0.001) –Time step size for simulation
-
max_t(float, default:20) –Maximum simulation time
-
no_noise(bool, default:False) –If True, disable noise in simulation
-
sigma_noise(float or None, default:None) –Standard deviation of noise. If None, uses model defaults.
-
smooth_unif(bool, default:True) –Whether to add uniform smoothing to RTs
-
random_state(int or None, default:None) –Integer seed for the C-level RNG. Must lie in
[-2**31, 2**31 - 1](fits a 32-bit signed Clong, required on Windows).Nonepicks a seed in[0, 2**31 - 1]automatically. -
return_option(str, default:"full") –Output format: "full" or "minimal"
-
n_threads(int, default:1) –Number of threads for parallel execution. If > 1 and OpenMP is available, uses multi-threaded simulation. Note: trajectory recording is only available with n_threads=1.
Returns:
-
dict–Simulation results with keys: - 'rts' : np.ndarray of reaction times - 'choices' : np.ndarray of choices - 'metadata' : dict with simulation metadata - Additional keys depending on model and return_option
Raises:
-
ValueError–If parameters are invalid