API Reference
Core types
ADDM.Trial — TypeTrial(choice, RT, valueLeft, valueRight)Arguments
Required keyword arguments
choice: either -1 (for left item) or +1 (for right item).RT: response time in milliseconds.valueLeft: value of the left item.valueRight: value of the right item.
Optional
fixItem: list of items fixated during the trial in chronological order; 1 correponds to left, 2 corresponds to right, and any other value is considered a transition/blank fixation.fixTime: list of fixation durations (in milliseconds) in chronological order.fixRDV: list of Float64 corresponding to the RDV values at the end of each fixation in the trial.uninterruptedLastFixTime: Int64 corresponding to the duration, in milliseconds, that the last fixation in the trial would have if it had not been interrupted when a decision was made.RDV: vector of RDV over time.
Example
julia> t = Trial(choice = 1, RT = 2145, valueLeft = 1, valueRight = 3)
Trial(1, 2145, 1, 3, #undef, #undef, #undef, #undef, #undef)
julia> t.RT
2145
julia> t.uninterruptedLastFixTime
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[1] getproperty(x::Trial, f::Symbol)
@ Base ./Base.jl:37
[2] top-level scope
@ REPL[4]:1
julia> t.uninterruptedLastFixTime = 189
189
julia> t
Trial(1, 2145, 1, 3, #undef, #undef, #undef, 189, #undef)ADDM.aDDM — TypeConstructor for model definitions that will contain model parameter and parameter value mapping. Not intended to be used alone but as part of define_model
Example
julia> MyModel = ADDM.aDDM()
aDDM(Dict{Symbol, Any}())
julia> MyModel.d = 0.005
0.005
julia> MyModel.σ = .06
0.06
julia> MyModel
aDDM(Dict{Symbol, Any}(:σ => 0.06, :d => 0.005))ADDM.define_model — Functiondefine_model(d, σ, θ = 1, η = 0, barrier = 1, decay = 0, nonDecisionTime = 0, bias = 0.0)Create attentional drift diffusion model with parameters described in Krajbich et al. (2010).
Arguments
Required parameters
d: Number, parameter of the model which controls the speed of integration of the signal.σ: Number, parameter of the model, standard deviation for the normal distribution.
Optional parameters
θ: Float64 Traditionally between 0 and 1, parameter of the model which controls the attentional discounting. Default at 1 makes it a ddm.η: Float64 Additive attentional enhancement the attentional discounting. Default at 0 makes it a ddm.barrier: positive Int64, boundary separation in each direction from 0. Default at 1.decay: constant for linear barrier decay at each time step. Default at 0.nonDecisionTime: non-negative Number, the amount of time in milliseconds during which processes other than evidence accummulation occurs. Default at 0.bias: Number, corresponds to the initial value of the relative decision value variable. Must be smaller than barrier.
Todo
- Tests
- Change decay parameter to function instead of scalar
Example
julia julia> MyModel = define_model(d = .006, σ = 0.05) aDDM(Dict{Symbol, Any}(:nonDecisionTime => 0, :σ => 0.05, :d => 0.006, :bias => 0.0, :barrier => 1, :decay => 0, :θ => 1.0, :η => 0.0))`
Fixation data
ADDM.FixationData — TypeFixationData(probFixLeftFirst, latencies, transitions, fixations;
fixDistType="fixation")Arguments:
probFixLeftFirst: Float64 between 0 and 1, empirical probability that the left item will be fixated first.latencies: Vector corresponding to the empirical distribution of trial latencies (delay before first fixation) in milliseconds.transitions: Vector corresponding to the empirical distribution of transitions (delays between item fixations) in milliseconds.fixations: Dict whose indexing is defined according to parameter fixDistType. Each entry is an array corresponding to the empirical distribution of item fixation durations in milliseconds.fixDistType: String, one of {'simple', 'difficulty', 'fixation'}, determines how the fixation distributions are indexed. If 'simple', fixation distributions are indexed only by type (1st, 2nd, etc). If 'difficulty', they are indexed by type and by trial difficulty, i.e., the absolute value for the trial's value difference. If 'fixation', they are indexed by type and by the value difference between the fixated and unfixated items.
ADDM.process_fixations — Functionprocess_fixations(data::Dict; timeStep::Number = 10,
maxFixTime::Number = 3000,
numFixDists::Int64 = 3, fixDistType::String = "fixation",
valueDiffs::Vector{Int64} = collect(-3:1:3),
subjectIds::Vector{String} = String[])Create empirical distributions from the data to be used when generating model simulations.
Arguments
data: a dict, indexed by subjectId, where each entry is a list of Trial objects. E.g. output ofload_data_from_csvtimeStep: integer, minimum duration of a fixation to be considered, in miliseconds.maxFixTime: integer, maximum duration of a fixation to be considered, in miliseconds.numFixDists: integer, number of fixation types to use in the fixation distributions. For instance, if numFixDists equals 3, then 3 separate fixation types will be used, corresponding to the 1st, 2nd and other (3rd and up) fixations in each trial.fixDistType: string, one of {'simple', 'difficulty', 'fixation'}, used to determine how the fixation distributions should be indexed. If 'simple', then fixation distributions will be indexed only by type (1st, 2nd, etc). If 'difficulty', they will be indexed by type and by trial difficulty, i.e., the absolute value for the trial's value difference. If 'fixation', they will be indexed by type and by the value difference between the fixated and unfixated items. Note that this is not the same as the value difference for the trial.valueDiffs: list of integers. If fixDistType is 'difficulty' or 'fixation', valueDiffs is a range correspoding to the item values to be used when indexing the fixation distributions. So ifdifficultymake sure to input absolute value differences if that is the measure of difficulty of the decision.subjectIds: list of strings corresponding to the subjects whose data should be used. If not provided, all existing subjects will be used.
Return
- A FixationData object.
ADDM.convert_to_fixationDist — Functionconvert_to_fixationDist(fixationData::FixationData; timeStep::Number = 10)Create empirical distributions from the data to be used when generating model simulations.
Arguments
fixationData: FixationData type that is the output ofprocess_fixations.timeStep: integer, timeBin size in ms.
Return
fixationDist: Dictionary indexed by value difference and fixation type. Contains the distributions of fixation durations in each time bin specifiutimeBinMidPoints: Mid points of the time bins, for which the fixation duration distributions were calculated. Will be the durations sampled inaddm_simulate_trialif usingfixationDistinstead offixationData
Data simulation
ADDM.aDDM_simulate_trial — FunctionaDDM_simulate_trial(model::aDDM, fixationData::FixationData,
valueLeft::Number, valueRight::Number; timeStep::Number=10.0,
numFixDists::Int64=3 , fixationDist=nothing, timeBins=nothing,
cutOff::Number=100000)Generate a DDM trial given the item values.
Arguments
model: aDDM object.fixationData: FixationData object.Required even when using fixationDistbecause it specifies latencies and transitions as well.valueLeft: value of the left item.valueRight: value of the right item.timeStep: Number, value in milliseconds to be used for binning time axis.numFixDists: Int64, number of fixation types to use in the fixation distributions. For instance, if numFixDists equals 3, then 3 separate fixation types will be used, corresponding to the 1st, 2nd and other (3rd and up) fixations in each trial.fixationDist: distribution of fixations which, when provided, will be used instead of fixationData.fixations. This should be a dict of dicts of dicts, corresponding to the probability distributions of fixation durations. Indexed first by fixation type (1st, 2nd, etc), then by the value difference between the fixated and unfixated items, then by time bin. Each entry is a number between 0 and 1 corresponding to the probability assigned to the particular time bin (i.e. given a particular fixation type and value difference, probabilities for all bins should add up to 1). Can be obtained fromfixationDatausingconvert_to_fixationDist. If using this instead offixationDatato sample fixations make sure to specify latency and transition info infixationData.timeBins: array containing the time bins used in fixationDist. Can be obtained fromfixationDatausingconvert_to_fixationDist
Returns
- An Trial object resulting from the simulation.
ADDM.DDM_simulate_trial — FunctionDDM_simulate_trial(model::aDDM, valueLeft::Number, valueRight::Number; timeStep::Number = 10.0,
cutOff::Int64 = 20000)Generate a DDM trial given the item values.
Arguments
model: aDDM object.valueLeft: value of the left item.valueRight: value of the right item.timeStep: Number, value in milliseconds to be used for binning the time axis.cutOff: Number, value in milliseconds to be used as a cap if trial response time is too long.Returns
A Trial object resulting from the simulation.
ADDM.simulate_data — Functionsimulate_data(model::aDDM, stimuli, simulator_fn, simulator_args = (timeStep = 10.0, cutOff = 20000))Simulate data using the model for the given stimuli.
Arguments
model: aDDM object.stimuli: Named tuple withvalueLeftandvalueRightspecifying the values of options.simulator_fn: Name of the function that simulates a trial for the given model.simulator_args: Named tuple containing kwargs that should be fed tosimulator_fn
Returns
- Vector of Trial objects containing simulated data.
Likelihood computation
ADDM.aDDM_get_trial_likelihood — FunctionaDDM_get_trial_likelihood(;addm::aDDM, trial::Trial, timeStep::Number = 10.0,
stateStep::Number = 0.01)Compute the likelihood of the data from a single aDDM trial for these particular aDDM parameters.
Arguments:
Keyword arguments
model: aDDM object.trial: Trial object.timeStep: Number, value in milliseconds to be used for binning the time axis.stateStep: Number, to be used for binning the RDV axis.
Returns:
- The likelihood obtained for the given trial and model.
ADDM.DDM_get_trial_likelihood — FunctionDDM_get_trial_likelihood(;ddm::aDDM, trial::Trial, timeStep::Number = 10,
stateStep::Number = 0.01)Compute the likelihood of the data from a single DDM trial for these particular DDM parameters.
Arguments
Keyword arguments
model: aDDM object.trial: Trial object.timeStep: Number, value in milliseconds to be used for binning the time axis.stateStep: Number, to be used for binning the RDV axis.
Returns
- The likelihood obtained for the given trial and model.
ADDM.compute_trials_nll — Functioncompute_trials_nll(model::aDDM, data, likelihood_fn, likelihood_args = (timeStep = 10.0, cutOff = 20000))Compute likelihood of a dataset for a given model.
Arguments
model: aDDM object. Holds info on the parameter values for the likelihood function.data: Vector ofADDM.Trialobjects.likelihood_fn: Name of the function that computes the likelhoods of a trial for the given model.likelihood_args: Named tuple containing kwargs that should be fed tolikelihood_fnreturn_trial_likelihoods: Boolean to specify whether to return the likelihoods for each trialsequential_model: Boolean to specify if the model requires all data concurrently (e.g. RL-DDM). Iftruemodel cannot be multithreaded
Returns
- Negative log likelihood of data
- (Optional) Dictionary of trial likelihoods keyed by the trial number
Grid search
ADDM.setup_fit_for_params — Functionsetup_fit_for_params(fixed_params, likelihood_fn, cur_grid_params, likelihood_fn_module=Main)Return parameter container and likelihood function for given parameter combination.
Arguments
fixed_params: Model parameters that are fixed to a value and not fitted.likelihood_fn: Name of likelihood function.cur_grid_params: NamedTuple containing the parameter combinationlikelihood_fn_module: DefaultMain. Module where the likelihood function is defined.
Returns
model: Container holding parameter combination info.likelihood_fn: Likelihood function that computes trial likelihoods for a given parameter combination.
ADDM.get_trial_posteriors — Functionget_trial_posteriors(param_grid, model_priors, trial_likelihoods)Compute model posteriors after each trial given model priors and trialwise likelihoods.
Arguments
param_grid: Vector of NamedTuples defining parameter space.model_priors: Dictionary with parameter combinations as keys and prior model probability as values.trial_likelihoods: Nested dictionary with outer keys of parameter combinations, inner keys of trial numbers, and values of trial likelihoods.
Returns
trial_posteriors: Nested dictionary with outer keys of parameter combinations, inner keys of trial numbers, and values of model posterior probabilities after each observation.
ADDM.save_intermediate_likelihoods_fn — Functionsave_intermediate_likelihoods(trial_likelihoods_for_grid_params, cur_grid_params, save_path)Write out trial likelihoods as soon as they are computed for a given parameter combination. Intended to be used when running a large parameter grid and worried that job might fail unexpectedly. Saved trial likelihoods can later be read in to compute posteriors if necessary.
Arguments
trial_likelihoods_for_grid_params: Dictionary with keys of trial numbers and values of likelihoods forcur_grid_params.cur_grid_params: parameter combination, for which the likelihoods are being saved. NamedTuple entry inparam_grid.save_path: Path to save the intermediate output. Default to"./outputs"which saves output to directory from which the function is run (creates it if needed).fn: File name for the saved output. ".csv" will be appended to this string.
ADDM.match_param_grid_keys — Functionmatch_param_grid_keys(param_grid)If paramgrid contains models with different parameter names, ensure all entries in paramgrid have the same names and assigns a "NA" if that parameter names does not exist for a given model.
Arguments
param_grid: Vector of NamedTuples with parameter names as keys and parameter values as values.
ADDM.get_mle — Functionget_mle(all_nll, likelihood_args)Extract maximum likelihood estimate from all_nll
Arguments
all_nll: Dictionary containing parameter combinations as keys and sum of negative log likelihoods as values.likelihood_args: NamedTuple containing step size info.
Return
best_pars: MLE amongst the parameter combinations tried inall_nllfor step sizes specified inlikelihood_args
ADDM.grid_search — Functiongrid_search(data, param_grid, likelihood_fn = nothing,
fixed_params = Dict(:θ=>1.0, :η=>0.0, :barrier=>1, :decay=>0, :nonDecisionTime=>0, :bias=>0.0);
likelihood_args = (timeStep = 10.0, stateStep = 0.01),
model_priors = nothing,
likelihood_fn_module = Main,
sequential_model = false,
grid_search_exec = ThreadedEx(),
compute_trials_exec = ThreadedEx(),
return_grid_nlls = false,
return_model_posteriors = false,
return_trial_posteriors = false,
save_intermediate_likelihoods = false,
noise_param_name = "sigma")Compute the likelihood of either observed or simulated data for all parameter combinations in param_grid.
Arguments
Required
data: Data for which the sum of negative log likelihoods will be computed for each trial. Should be a vector ofADDM.Trialobjects.param_grid: Parameter combinations for which the sum of nll's for thedatais computed. Vector of NamedTuples. E.g. ```
15-element Vector{@NamedTuple{d::Float64, sigma::Float64, theta::Float64, likelihoodfn::String}}: (d = 0.001, sigma = 0.01, theta = 0.12, likelihoodfn = "ADDM.aDDMgettriallikelihood") (d = 0.002, sigma = 0.01, theta = 0.12, likelihoodfn = "ADDM.aDDMgettrial_likelihood") ... ```
likelihood_fn: Name of likelihood function to be used to compute likelihoods. The toolbox hasADDM.aDDM_get_trial_likelihoodandADDM.DDM_get_trial_likelihooddefined. If comparing different generative processes then leave at default value ofnothingand make sure to define alikelihood_fnin theparam_grid.fixed_params: DefaultDict(:θ=>1.0, :η=>0.0, :barrier=>1, :decay=>0, :nonDecisionTime=>0, :bias=>0.0). Parameters required by thelikelihood_fnthat are not specified to vary across likelihood computations.likelihood_args: Default(timeStep = 10.0, stateStep = 0.01). Additional arguments to be passed ontolikelihood_fn.
Optional
model_priors: priors for each model probability if not assummed to be uniform. Should be specified as aDictwith values of probabilities matching the keys for the parameter combinations specified inparam_grid.likelihood_fn_module: DefaultMain. Scope from which to pull the likelihood function. Default works for custom functions defined inline or in a script, as well as, the built-in functions.sequential_model: Boolean to specify if the model requires all data concurrently (e.g. RL-DDM). Iftruelikelihood computation for model cannot be multithreaded (though grid search still can be).grid_search_exec: Executor used byFLoops.jlto parallelize computation of nll for each parameter combination over threads. Default isThreadedEx(). Other options areDistributedEx()andSequentialEx(). SeeFLoops.jldocumentation for more details.compute_trials_exec: Executor used byFLoops.jlto parallelize computation of each trial's likelihood over threads. Default isThreadedEx(). Other options areDistributedEx()andSequentialEx(). SeeFLoops.jldocumentation for more details.return_grid_nlls: Defaultfalse. If true, will return aDataFramecontaining the sum of nll's for each parameter combination in the grid search.return_model_posteriors: Defaultfalse. If true, will return the posterior probability for each parameter combination inparam_grid.return_trial_posteriors: Defaultfalse. If true, will return the posterior probability for each parameter combination inparam_gridafter each trial indata.save_intermediate_likelihoods: Defaultfalse. If true, will crate a csv containing the likelihoods for each trial after it is computed for a given parameter combination. Could be useful if doing a large parameter sweep and are worried about the job terminating unexpectedly. Job could be restarted for parameter combinations, for which the trial likelihoods have not been saved, instead of all parameter combinations.noise_param_name: Default"sigma". String specifying the name of the noise parameter in the model. Used to check stability criterion for Forward Euler.
Returns
output:Dictwith keys:best_pars:Dictcontaining the parameter combination with the lowest nll.grid_nlls: (Optional)DataFramecontaining sum of nll's for each parameter combination.trial_posteriors: (Optional) Posterior probability for each parameter combination after each trial.model_posteriors: (Optional) Posterior probability for each parameter combination after all trials.
Marginal posteriors
ADDM.marginal_posteriors — Functionmarginal_posteriors(posteriors_dict, two_d_marginals)Compute the marginal posterior distributions for the fitted parameters specified in param_grid.
Arguments
Required
posteriors_dict: Dictionary of posterior model probabilities. Keys of this dictionary are the parameter combinations specified inparam_grid. Values are the posterior probabilties after accounting for each observation.two_d_marginals: Boolean. Whether to compute posteriors to plot heatmaps of posteriors. Default is false.
Returns
- Vector of
DataFrames. Iftwo_d_marginalsis false, return only dataframes containing posteriors for each parameter. Otherwise, also includes posteriors for pairwise combinations of parameters as well.
ADDM.marginal_posterior_plot — Functionmarginal_posterior_plotThis plot type shows the posteriors for each parameter individually, as well as the posterior probabilities of pairwise combinations.
The input is an array of dataframes resulting from ADDM.marginal_posteriors with the third positional argument set to true.
best_pars, nll_df, model_posteriors = ADDM.grid_search(subj_data, ADDM.aDDM_get_trial_likelihood, param_grid,
Dict(:η=>0.0, :barrier=>1, :decay=>0, :nonDecisionTime=>0, :bias=>0.0),
likelihood_args=my_likelihood_args,
return_model_posteriors = true)
ADDM.marginal_posteriors(param_grid, model_posteriors, true)Recipe modified from https://github.com/JuliaPlots/StatsPlots.jl/blob/master/src/corrplot.jl
Helpers
ADDM.load_data_from_csv — Functionload_data_from_csv(expdataFileName, fixationsFileName; stimsOnly = false)Load experimental data from two CSV files: an experimental data file and a fixations file. Format expected for experimental data file: parcode, trial, rt, choice, itemleft, itemright. Format expected for fixations file: parcode, trial, fixitem, fixtime.
Arguments
Positional
expdataFileName: String, name of experimental data file.fixationsFileName: String, name of fixations file.parcode: Subject identifiertrial: Trial numberfix_item: Fixation location. 0 = transition, 1 = left, 2 = right,
fix_time: Fixation duration.
Keyword
stimsOnly: Boolean, true ifexpdataFileNamecontains only stimuli info and no choice or rt info.
Return
A dict, indexed by subjectId, where each entry is a list of Trial objects.
ADDM.convert_param_text_to_symbol — Functionconvert_param_text_to_symbols(model)Convert parameter names that are specified in text into greek/latex symbols. Used by ADDM.grid_search