top of page

Randomization Design

In this article:


Randomization is essential for controlling order effects and ensuring balanced presentation of experimental conditions. EventIDE provides dedicated elements and tools—primarily the Condition List element—to design, preview, and execute randomized trial sequences, as well as utilities for single random draws or adaptive methods such as staircases.

Key Randomization Tools

Condition List Element

  • Randomizes combinations of independent variables organized in a condition list.

  • Offers a spreadsheet editor for defining variables, condition frequencies, block-specific adjustments, and previewing shuffled trial blocks.

  • At runtime, generates trial blocks by withdrawing conditions in random order, counts trials and blocks, and exposes dynamic properties (and proxy variables) for each condition.


Staircase Method Element

  • Implements weighted up/down staircase procedures (e.g. Kaernbach, 1991) with a predefined performance target.

  • Collects statistics, adjusts stimulus parameters adaptively, and provides a dynamic staircase plot visible on the Status Screen.


System Random Functions

  • For simple random draws outside of a full condition list, you can use built-in random functions of the chosen scripting language (e.g. C#).

    Example in C#:

    Initialize a random number generator in the Header snippet:

Random RNG = new Random();  

Generate random numbers in other snippets:

int NumberA = RNG.Next(0, 10);     // Integer in [0, 9]

int NumberB = RNG.Next(0, 10);

double NumberD = RNG.NextDouble(); // Double in [0.0, 1.0)

  • Use this for on-the-fly random choices or probabilistic decisions not covered by the Condition List.


External Randomization (e.g. MATLAB)

  • If you have complex designs generated elsewhere (e.g. MATLAB), you can import pre-randomized lists.

  • EventIDE can call MATLAB functions or read files produced externally; see EventIDE FAQ for MATLAB integration details.

Condition List Element

The Condition List element in EventIDE is designed to handle multi-variable randomization, block management, and runtime exposure of condition values. It is suitable for factorial designs, trial-by-trial stimulus selection, or any scenario where conditions must be drawn in a controlled, randomized fashion.

Adding the Condition List Element

Insert Element

  • Select the event where randomization should occur (typically the first event of a trial loop).

  • Go to Events Ribbon Tab > Add Element > Randomization > Condition List.

Adding the Condition List element.
Adding the Condition List element.

Access Properties

  • With the Condition List element selected, its properties appear in the Property Panel.

  • Look for the Condition List Editor property; click its button (→) to open the editor.

    Open the Condition List Editor.
    Open the Condition List Editor.

Condition List Editor

When you open the Condition List Editor, a separate window appears with two main tabs:

  • Condition List Tab

  • Trial Block Tab

Condition List Tab

This tab lets you define independent variables and their combinations (conditions) in a spreadsheet-like interface.

Condition List Tab.
Condition List Tab.

Table Structure

  • Condition Number (first column): auto-generated index for each row.

  • Per-Block Frequency (optional, second column): expand via the “>” button to set block-specific frequencies that override defaults.

  • Frequency: number of repetitions of this condition per block (integer ≥ 0).

  • Pr(): read-only column showing the calculated probability (%) of each condition within a block.

  • Condition Name: a label for the combination (optional; can be auto-generated or custom).

  • Variable Columns: one column per independent variable (e.g. StimulusIndex, CorrectKey, Color, etc.). Each variable cell holds the value for that condition.


Configuring Variables

  • Data Types: For each variable, choose from int32, double, string, Boolean, or single.

  • Note: A string variable can encode other types, e.g. colors: "#FFFF0000", "Red", etc.

  • Adding Variables: Click Add New Variable. If Auto-proxy variables is toggled on, a proxy variable is created automatically for each new variable.

  • Linking Existing Proxies: Click Link Proxy Variable, select from available proxy variables in your experiment. For structured properties, expand to subfields (e.g. color.R, color.G). Once linked, name and type cannot be changed here.


Editing Rows

  • Insert/Delete Rows: Fill the last blank row (automatically adds a new row), or right-click to insert/delete/copy-paste rows.

  • Entering Values: Type directly or paste from external applications (e.g. Excel, MATLAB).


Setting Frequencies:

  • After defining variable columns, edit the Frequency column to set how many times each condition appears in a block. The Pr() column updates automatically.

  • For block-specific adjustments, expand the Per-Block Frequency column: define Block Number and Frequency pairs. Setting frequency to zero excludes that condition in the specified block (useful for practice blocks or phased designs).

Tip: Save regularly before and after editing the condition list to avoid data loss if the editor crashes due to large changes.


Trial Block Tab

This tab allows you to preview how one block of trials would be constructed given current settings:

Selected block number: Choose which block number to preview (accounts for per-block frequency overrides).

Shuffling mode:

  • Shuffle the condition order: fully random order each preview.

  • Shuffle starting condition but keep order: fixes relative order after the first item.

  • None: no shuffling; conditions appear in the sequence defined in the table.

Reshuffle button (dice Icon): Generates a new random sequence within the preview.

Review of a randomized block: Check that probabilities and frequencies match intended design before closing.

Reminder: Click OK to save changes; closing without OK discards edits.

Trial Block Tab.
Trial Block Tab.

Condition List Properties

Once the Condition List is defined and the editor is closed, EventIDE automatically generates a set of dynamic properties and optional proxy variables, allowing you to access and control the condition values at runtime.


Dynamic Properties

For each variable defined in your Condition List, EventIDE creates dynamic properties under the Trial Conditions and Block Conditions categories in the element's Property Panel. These properties reflect the current values of each condition during runtime and can be read programmatically.

Trial Condition Properties and Their Associated Proxy Variables.
Trial Condition Properties and Their Associated Proxy Variables.

Automatic Proxy Variables


If the Auto-proxy variables option is enabled in the Condition List, EventIDE creates corresponding proxy variables for each condition variable. These proxies are visible in the Proxy Panel and can be used in code snippets, bound to UI elements, or displayed on the status screen.


Using Condition Values in Code


Condition values—either as dynamic properties or proxy variables—can be accessed within code snippets, typically in the After Onset snippet of the parent event. This is where you configure stimulus presentation or response logic based on the current trial settings.

Example:

StimulusText = Letter;     // 'Letter' is a proxy variable for the current stimulus value
TextColor    = Color;      // 'Color' proxy defines the current trial's text color

Runtime Commands (Write-Only)


You can also control the experiment flow dynamically by writing to special runtime command properties:

  • RepeatConditionNow – Set to true to immediately repeat the current condition.

  • RecallConditionNow – Set to true to reinsert the current condition later in the block (reshuffled).

These properties must be set before the onset of the next trial and are typically used after incorrect responses or other runtime criteria.

Runtime Commands of the Condition List Element.
Runtime Commands of the Condition List Element.

Runtime Status Properties


EventIDE provides additional read-only properties to monitor trial progress:

  • IsLastTrial – Returns true if the current trial is the last one in the block. Useful for triggering breaks or transitions.

  • TrialNumber and BlockNumber – Built-in counters for the current trial and block. These values can be used in conditional logic or displayed on the status screen.

When the last trial in a block is completed, EventIDE automatically generates a new block and reshuffles the conditions (if the automatic mode is enabled).

Runtime Status Properties of the Condition List Element.
Runtime Status Properties of the Condition List Element.

Condition List Withdrawal Modes

The Condition List element in EventIDE controls how trial variables are randomly selected from a predefined list. This behavior is governed by the element's Withdrawal Mode property, which supports two operational modes: automatic withdrawal and manual withdrawal.


Automatic Withdrawal (New Trial on Event Onset)

In this default mode, the Condition List element automatically selects a new set of variable values from the trial block each time its parent event begins (i.e. on event onset). This mode requires placing the Condition List element in the first event of your trial loop to accurately detect the start of each trial.


Key Features:

  • Automatically tracks the number of trials and blocks based on the number of variable withdrawals.

  • Initiates a new trial block with a fresh randomized order once all conditions from the current block are exhausted.

  • Simplifies timing and flow by binding condition updates to the start of each trial.


Manual Withdrawal

In manual mode, variable values are not withdrawn automatically. Instead, you control when and how new conditions are accessed and when trial blocks are regenerated.


Key Features:

  • Conditions are accessed directly in code using dynamic properties (e.g., via index-based access).

  • Regenerating a new random trial block requires explicitly setting the ResetBlockNow property in code.

  • Provides maximum flexibility for advanced custom designs.


Summary

Use Automatic Withdrawal for standard trial-by-trial experiments where conditions should be drawn automatically at trial start. Choose Manual Withdrawal when you need more control over how and when conditions are accessed, such as in adaptive designs or complex randomization schemes.

Setting up Condition List Withdrawal Mode

Automatic Withdrawal Mode (Default)

  • Placement: Add the Condition List element to the first event of your trial loop (so it can detect event onset as trial start).

  • Design: Use the Condition List Editor to define variables, frequencies, and per-block overrides.

  • Proxy Setup: Ensure dynamic properties have proxies (via Auto-proxy or manual linking).

  • Trial Preparation: In the parent event’s After Onset snippet, write code to configure stimuli based on proxy values.

StimulusImageIndex = ImageIndex;   // ImageIndex proxy from condition list

  • Handling Repeats: If a trial must be repeated (e.g. incorrect response), assign RepeatConditionNow = true; (or RecallConditionNow = true;) before the next trial onset.

  • Flow Control: Use Is Last Trial property in flow routes to branch (e.g. show break screen) when a block ends.

  • Block Regeneration: After the final trial, a new block is created automatically with shuffled conditions.

Tip: Place all setup code in the After Onset snippet of the trial event to ensure stimuli are configured just before presentation, maximizing timing precision.


Manual Withdrawal Mode


For advanced or custom scenarios where you control exactly when new condition values are drawn:

  • Placement: Add the Condition List element to any event (it does not need to detect trial onsets automatically).

  • Design: Define conditions in the editor as before.

  • Accessing Values: Use dynamic properties under Block Conditions group in the Property Panel. Link proxies if desired.

  • Index-Based Access: In code, use an index to pick a condition from the current block:

int n = 7;  // e.g. seventh trial in the block
StimulusText = Letters[n - 1];  // zero-based indexing
TextColor    = Colors[n - 1];
  • Be mindful that conditions are shuffled within the block, so an incrementing index yields random sequence access.

  • Not Using Runtime Status: Status properties like IsLastTrial are not updated in manual mode; avoid relying on them.

  • Regenerating a Block: When you require a fresh block, set

ResetBlockNow = true; 

via a code snippet. A new block with the same design parameters is generated for subsequent withdrawals.

Custom Scenarios with Condition List

The manual mode enables flexible custom logic, such as selecting a subset from a larger pool.


Example: Random Subset Selection

Goal: Each trial presents 5 unique colors drawn from a larger pool, without repetition within a trial, but with reshuffling between trials.


  1. Switch to Manual Withdrawal Mode: In the Condition List element properties, set Withdrawal Mode to Manual.

  2. Define Pool: In the Condition List Editor, create a single variable (e.g. Colors) listing all possible colors.

  3. Proxy Variables: Link proxies for:

    1. The Colors property under Block Conditions group in the Property Panel (gives an array of all colors in random order).

    2. The ResetBlockNow runtime command.

  4. Trial Code (in the relevant snippet):

for (int i = 0; i < 5; i++)
{
StimulusColor[i] = Colors[i];    // Assign first 5 colors from shuffled block
}
ResetBlockNow = true;  // Prepare a new shuffled pool for the next trial
  1. Next Trials: On the next trial, the Colors array is reshuffled automatically, providing a fresh random subset.


Tip: You can extend this logic to multiple pools or multi-dimensional selections by defining additional variables and using similar indexing or conditional logic in snippets.

Best Practices

  • Plan Your Design: Sketch variables, levels, and desired block structure before creating the condition list.

  • Use Auto-Proxy Wisely: Auto-creating proxies speeds setup, but review and organize proxy names and categories for clarity.

  • Preview Thoroughly: Always use the Trial Block tab to verify frequencies and shuffling modes before running participants.

  • Isolate Trial Setup Code: Place condition-based stimulus configuration in the correct snippet (e.g. After Onset) to ensure precise timing.

  • Leverage Runtime Status: In automatic mode, use properties like IsLastTrial, TrialNumber, and BlockNumber to manage breaks, feedback, or block transitions.

  • Custom Logic: Use manual mode for scenarios needing special withdrawal logic (e.g. subset selection, adaptive sampling).

  • Combine with Flow Routes: Integrate randomization with flow logic—e.g. loop events until a criterion is met, branch based on performance, or end experiment after certain blocks.

Staircase Method Element

The Staircase Method element implements a powerful psychophysical estimation technique based on the weighted up/down staircase procedure with a fixed performance rate (Kaernbach, 1991). This method dynamically adjusts stimulus intensity based on participant responses, allowing accurate threshold detection. The element tracks various statistics, visualizes the progression in a real-time plot, and can be reset or reused across experimental sessions.

Reference: Kaernbach, C. (1991). Simple adaptive testing with the weighted up-down method.


Description

The Staircase Method element assists in estimating a participant's detection threshold by adapting stimulus intensity based on response accuracy. The method supports a fixed desired correct rate (e.g. 80%), adjusting forward and backward steps automatically. The element maintains real-time statistics, provides runtime control over responses, and offers a live XAML plot for visual monitoring on the Status Screen or in a XAML Layout.

The algorithm supports a single staircase. If multiple interleaved staircases are needed, multiple elements can be added and controlled independently.


Practical Use

Design Time

  • Add the Staircase Method element to any event. It operates globally within the experiment scope.

  • Set the following key properties:

    • Initial Intensity – starting value for stimulus intensity (e.g., image opacity or audio duration).

    • Forward Step – the increment/decrement applied when a correct response is given. Sign defines staircase direction.

    • Enforced Correct Rate – desired correct rate in percentage (e.g., 80). Determines the logic of adaptive steps.

    • Minimal Reversal Number – minimum number of reversals to declare completion.

    • Ignorable Reversal Number – number of early reversals to exclude from final threshold estimation.

  • Optionally set:

    • Plot Title, Show Subtitle, and Font Size for customizing the visual plot.

    • Data Report Label to tag exported results.

  • Create proxies for:

    • Add Response Now – to feed trial outcomes.

    • New Intensity – to update stimulus intensity.

    • Monitoring results like Estimated Threshold, Actual Correct Rate, Reversal Count, and Staircase Points.


Runtime

  • To operate the staircase during trials:

// Example: Add participant response
AddResponseNow = Response == 1;
// Or use integer representation
AddResponseNow = Response; // Response = 1 (correct), 0 (incorrect)
  • Adjust stimulus using the new intensity:

RendererOpacity = NewIntensity; // Adjust visual stimulus opacity
EventDuration = Convert.ToUInt64(NewIntensity); // Adjust timing
  • To reset the staircase for a new sequence:

ResetStaircaseNow = true;
  • Export the full progression of intensity levels:

Report = "Staircase intensity trace:\r\n";
for (int i = 0; i < StaircasePoints.Length; i++)
Report += StaircasePoints[i] + ";";
  • Bind the staircase plot to a Status Screen control:

<ContentControl Content="{Binding XAMLStaircasePlot}"/>

Notes

Do not combine Add Response Now and reading New Intensity in the same snippet. Always perform these in two separate snippets, as the next intensity is only updated after the response has been processed.

Incorrect usage example:

AddResponseNow = Response;
EventDuration = Convert.ToUInt64(NewIntensity); // Won't reflect updated intensity yet



bottom of page