Skip to content

Trial sequencing

Igor Kagan edited this page Aug 26, 2026 · 1 revision

Trial sequencing

How the condition file builds the list of trials, shuffles it, and decides what to run next after a success or a fail.

Set in the trial-1 block of the condition script (Feno.m, combined_condition_file_*.m, …), inside the for n_exp loop:

shuffle_conditions = 2;  % how to order the list
force_conditions   = 3;  % what to do after a fail

The controller does not own this. monkeypsych only run()s the script every INI_TRI; the script picks custom_trial_condition and maps that row of sequence_matrix onto Current_con / task.


1. Building the list (trial 1 only)

Each name in esperimentazione is one block. For that block, every All.* field that is a vector is a factor. combvec makes the full factorial, then repmat(..., N_repetitions) repeats it.

Example: All.reach_hand_con = [1 2], All.instructed_choice_con = [0 1], N_repetitions = 30 → 4 unique conditions × 30 = 120 trials in that block.

Several esperimentazione names are concatenated in order (block 1, then block 2, …).

sequence_matrix columns are those trials. sequence_indexes / ordered_sequence_indexes are column indices into it.


2. shuffle_conditions (trial 1 only)

Value Order
0 As built: factorial order, then repetitions, then blocks
1 Shuffle the entire concatenated list
2 Shuffle inside each block, keep block order

Feno uses 2 (one experiment, so same as shuffling that block).


3. force_conditions (every trial after the first)

This is the “what if the monkey makes a mistake” switch.

Value On fail On success Run ends when
1 Same condition again. Index is sequence_indexes(n_success+1), so the slot does not advance until success==1 Next slot Every slot has succeeded once
2 Condition stays in the remaining pool; the pool is shuffled (not necessarily next) Drop it (sequence_indexes(2:end)) Pool empty
3 Same as 2, but shuffle within the current block only Drop it from that block; when the block is empty, go to the next All blocks empty
0 or anything else Ignore success; one pass Advance numel(trial) equals list length

Repeat the same trial until correct: force_conditions = 1.

Put the failed condition back at random (keep blocks): force_conditions = 3 (Feno default). Not an immediate repeat.

Abort vs success: the script looks at trial(end-1).success (previous trial). A completed-but-wrong-target trial (completed==1, success==0) counts as a fail here.


4. Worked example (Feno)

esperimentazione     = {'Dissociated_reach'};
shuffle_conditions   = 2;
force_conditions     = 3;
N_repetitions        = 30;

Factors in that case include reach_hand_con = [1 2], instructed_choice_con = [0 1], angle_cases = [2 5], … Unique combinations × 30 is the pool. Shuffle inside that pool. Fail → reshuffle remaining trials in the pool; success → pop the front; close when the pool is empty.

To switch to strict correction trials, only change:

force_conditions = 1;

5. Not the same thing

task.force_target_location (get_monkey, F6 “behavioral improvers”) is not sequencing. It is meant to copy the previous trial’s eye/hnd geometry after an unsuccessful trial. The condition script still picks the next Current_con; this flag does not repeat a sequence slot.

task.force_hand / task.force_effector only apply if the controller’s own randomize_reach_hand / randomize_effector is on. Condition files that set task.reach_hand from Current_con every trial override that.


Pointers

Logic lives in the condition file after %% Shuffling conditions (not in monkeypsych.m).
custom_trial_condition indexes sequence_matrix.
Related: Stimulus positioning and coordinate systems for how Current_con becomes target positions.

Clone this wiki locally