psyflow package

Submodules

psyflow.BlockUnit module

class psyflow.BlockUnit.BlockUnit(block_id, block_idx, settings, window=None, keyboard=None, seed=None, n_trials=None)

Bases: object

A container that manages a block of experimental trials.

BlockUnit is responsible for generating trial conditions, running trials, executing lifecycle hooks, and collecting trial-level results.

add_condition(condition_list)

Manually set the condition list.

Parameters:

condition_list (list) – A list of trial condition labels.

Returns:

The same instance for method chaining.

Return type:

BlockUnit

generate_conditions(func=None, n_trials=None, condition_labels=None, weights=None, order='random', seed=None, **kwargs)

Generate trial conditions for this block.

If func is provided, delegate generation to it. Otherwise, use the built-in weighted, balanced generator with optional sequential vs. random ordering.

Parameters:
  • func (Callable, optional) – User-supplied generator with signature (n_trials, condition_labels, seed=…, **kwargs) -> array-like.

  • n_trials (int, optional) – Number of trials in this block. Defaults to self.n_trials.

  • condition_labels (list of Any, optional) – Labels for each condition. Defaults to self.settings.conditions.

  • weights (list of float, optional) – Relative weight for each label; defaults to equal weights.

  • order ({'random','sequential'}) – If ‘sequential’, interleave labels in the order given; if ‘random’, build the list then shuffle.

  • seed (int, optional) – Overrides self.seed for this generation call, without mutating the block’s stored seed.

  • **kwargs (dict) – Extra keyword arguments passed to func when used.

Returns:

Returns self for chaining.

Return type:

BlockUnit

get_all_data()

Return trial results without modifying anything.

Returns:

Trial result dictionaries.

Return type:

list of dict

get_trial_data(key, pattern, match_type='exact', negate=False)

Filter trial data based on value of a key using matching rules.

Parameters:
  • key (str) – The key in each trial dict to match against.

  • pattern (str or list of str) – One or more patterns to match.

  • match_type ({'exact', 'startswith', 'endswith', 'regex'}) – Type of string matching to use.

  • negate (bool) – If True, return trials that do NOT match the pattern(s).

Returns:

Filtered list of trial dicts.

Return type:

List[Dict]

logging_block_info()

Log block metadata including ID, index, seed, trial count, and condition distribution.

on_end(func=None)

Register a function to run at the end of the block.

Parameters:

func (Callable, optional) – A function that takes the BlockUnit as input.

on_start(func=None)

Register a function to run at the start of the block.

Parameters:

func (Callable, optional) – A function that takes the BlockUnit as input.

run_trial(func, **kwargs)

Run all trials using a specified trial function.

Parameters:
  • func (Callable) – Function to run each trial. Must accept (win, kb, settings, condition, **kwargs).

  • **kwargs (dict) – Additional keyword arguments forwarded to func.

summarize(summary_func=None)

Summarize trial results.

Parameters:

summary_func (Callable, optional) – Custom summary function. If None, hit rate and RT by condition are computed.

Returns:

Summary results.

Return type:

dict

to_dict(target=None)

Append trial results to a target list, or return self for chaining.

Parameters:

target (list of dict, optional) – A list to append trial results to.

Returns:

The BlockUnit itself for chaining.

Return type:

BlockUnit

psyflow.StimBank module

class psyflow.StimBank.StimBank(win, config=None)

Bases: object

A hybrid stimulus management system for PsychoPy experiments.

StimBank supports: - Manual registration of stimuli via decorators (@registry.define(“name”)) - Loading stimuli from YAML or Python dictionaries - Centralized retrieval, lazy instantiation, and batch preview

add_from_dict(named_specs=None, **kwargs)

Add stimuli from a dictionary or keyword-based specifications.

Parameters:
  • named_specs (dict, optional) – Dictionary where keys are stimulus names and values are stimulus specs.

  • kwargs (dict) – Additional stimuli as keyword-based name=spec entries.

add_voice(stim_label, text, overwrite=False, voice='zh-CN-XiaoxiaoNeural')

Convert arbitrary text to speech (MP3) and register it as a new Sound stimulus.

Parameters:
  • stim_label (str) – The name under which to register the new voice stimulus, and the base filename for the MP3 (e.g. ‘welcome_voice’ → ‘assets/welcome_voice.mp3’).

  • text (str) – The text to synthesize.

  • overwrite (bool) – If True, overwrite an existing MP3 file. Default is False.

  • voice (str) – The TTS voice to use (default “zh-CN-XiaoxiaoNeural”). edge-tts –list-voices

convert_to_voice(keys, overwrite=False, voice='zh-CN-YunyangNeural')

Convert specified TextStim/TextBox2 stimuli to speech (MP3) and register them as new Sound stimuli in this StimBank.

Parameters:
  • keys (list[str]) – List of registered stimulus names to convert.

  • overwrite (bool) – If True, overwrite existing MP3 files (default False).

  • voice (str) – Name of the TTS voice to use (default ‘zh-CN-YunyangNeural’). edge-tts –list-voices

define(name)

Register a stimulus generator function using a decorator.

Parameters:

name (str) – Name to register the stimulus under.

Returns:

A decorator to wrap the stimulus function.

Return type:

Callable

describe(name)

Print accepted arguments for a registered stimulus.

Parameters:

name (str) – Name of the stimulus to describe.

export_to_yaml(path)

Export YAML-defined stimuli (but not decorator-defined) to file.

Parameters:

path (str) – Path to save the YAML file.

get(name)

Get a stimulus by name, instantiating it if needed.

Parameters:

name (str) – Registered stimulus name.

Returns:

Instantiated PsychoPy stimulus object.

Return type:

Any

Raises:

KeyError – If the stimulus is not registered.

get_and_format(name, **format_kwargs)

Return a fresh TextStim or TextBox2 with formatted text, keeping other properties unchanged.

Parameters:
  • name (str) – Name of the registered stimulus (TextStim or TextBox2).

  • **format_kwargs – Formatting variables to apply to the text field.

Returns:

TextStim or TextBox2

A new formatted visual text stimulus.

Raises:

TypeError – If the stimulus is not a TextStim.

get_group(prefix)

Retrieve a dictionary of stimuli whose names start with a given prefix.

Parameters:

prefix (str) – Common prefix to match.

Returns:

A dictionary of {name: stimulus} pairs.

Return type:

dict

get_selected(keys)

Retrieve a subset of named stimuli.

Parameters:

keys (list of str) – List of stimulus names to retrieve.

Returns:

A dictionary of {name: stimulus} pairs.

Return type:

dict

has(name)

Check whether a stimulus is registered.

Parameters:

name (str)

Return type:

bool

keys()

List all registered stimulus names.

Return type:

list of str

make_factory(cls, base_kwargs, name)

Create a factory function for a given stimulus class.

Parameters:
  • cls (type) – PsychoPy stimulus class (e.g., TextStim).

  • base_kwargs (dict) – Default keyword arguments.

  • name (str) – Stimulus name (used for error messages).

Returns:

A factory function that accepts (win, **overrides)

Return type:

Callable

preload_all()

Instantiate all registered stimuli and cache them internally.

preview_all(wait_keys=True)

Preview all registered stimuli one by one.

Parameters:

wait_keys (bool) – Wait for key press after last stimulus.

preview_group(prefix, wait_keys=True)

Preview all stimuli that match a name prefix.

Parameters:
  • prefix (str) – Prefix string to filter stimuli.

  • wait_keys (bool) – Wait for key press after final stimulus.

preview_selected(keys, wait_keys=True)

Preview selected stimuli by name.

Parameters:
  • keys (list of str) – Stimulus names to preview.

  • wait_keys (bool) – Wait for key press after final stimulus.

rebuild(name, update_cache=False, **overrides)

Rebuild a stimulus with optional updated parameters.

Parameters:
  • name (str) – Registered stimulus name.

  • update_cache (bool) – Whether to overwrite the existing cached version.

  • **overrides (dict) – New keyword arguments to override the original parameters.

Returns:

A fresh stimulus object.

Return type:

Any

validate_dict(config, strict=False)

Validate a dictionary of stimulus definitions.

Parameters:
  • config (dict) – Dictionary of stimulus specs.

  • strict (bool) – If True, raise errors; otherwise print warnings only.

psyflow.SubInfo module

class psyflow.SubInfo.SubInfo(config)

Bases: object

GUI-based participant information collector using a YAML-style config.

This class generates an input dialog based on a configurable field structure and provides basic localization and validation for different field types.

Supported field types: - string : Free text input - int : Integer input with optional constraints - choice : Dropdown with options

subject_data

The result of .collect(), formatted with English field keys.

Type:

dict or None

collect(exit_on_cancel=True)

Show a dialog to collect participant input. Loops until valid or cancelled.

Parameters:

exit_on_cancel (bool) – If True, exit the program if the user cancels input.

Returns:

Cleaned response dictionary with English field keys, or None if cancelled and exit_on_cancel is False.

Return type:

dict or None

validate(responses)

Validate responses based on type and constraints.

Parameters:

responses (list) – Raw responses from the dialog.

Returns:

True if all inputs are valid, False otherwise.

Return type:

bool

psyflow.TaskSettings module

class psyflow.TaskSettings.TaskSettings(size=<factory>, units='deg', screen=1, bg_color='gray', fullscreen=True, total_blocks=1, total_trials=10, key_list=<factory>, conditions=<factory>, block_seed=None, seed_mode='same_across_sub', overall_seed=2025, log_file=None, res_file=None, json_file=None, save_path='./data', task_name=None)

Bases: object

Configuration container for PsychoPy-based tasks.

This dataclass holds core experimental parameters and provides utility methods to set per-subject seeds, construct output paths, and dynamically extend settings from external config dictionaries.

Features

  • Window display settings

  • Experimental structure (blocks, trials, conditions)

  • Response keys

  • Flexible seeding strategies

  • Auto-generated per-subject filenames

add_subinfo(subinfo)

Add subject-specific information and set seed/file names accordingly.

Parameters:

subinfo (dict) – Dictionary that must contain at least ‘subject_id’. Also used to construct per-subject output file names.

Raises:

ValueError – If ‘subject_id’ is missing from subinfo.

bg_color: str = 'gray'
block_seed: Optional[List[int]] = None
conditions: List[str]
classmethod from_dict(config)

Create a TaskSettings instance from a flat dictionary.

Known fields are applied normally; unknown keys are attached as attributes.

Parameters:

config (dict) – Dictionary of configuration options.

Returns:

An initialized instance with config applied.

Return type:

TaskSettings

fullscreen: bool = True
json_file: Optional[str] = None
key_list: List[str]
log_file: Optional[str] = None
overall_seed: int = 2025
res_file: Optional[str] = None
save_path: Optional[str] = './data'
save_to_json()

Save the current TaskSettings instance to a JSON file.

screen: int = 1
seed_mode: str = 'same_across_sub'
set_block_seed(seed_base)

Generate a list of per-block seeds from a base seed.

Parameters:

seed_base (int) – Base seed used to generate a list of integers for each block.

size: List[int]
task_name: Optional[str] = None
total_blocks: int = 1
total_trials: int = 10
trials_per_block: int
units: str = 'deg'

psyflow.StimUnit module

class psyflow.StimUnit.StimUnit(unit_label, win, kb=None, triggersender=None)

Bases: object

A modular trial unit for PsychoPy-based experiments. Designed to encapsulate stimulus presentation, response handling, event triggers, and lifecycle hooks with flexible timing control.

Features

  • Add multiple visual stimuli and manage them as a group.

  • Register event hooks for start, response, timeout, and end stages.

  • Supports both time-based and frame-based control modes.

  • Triggers aligned to visual flips (e.g., for EEG/fMRI).

  • Logs detailed trial state to PsychoPy’s logging system.

type win:

Window

param win:

PsychoPy window where stimuli will be drawn.

type win:

visual.Window

type unit_label:

str

param unit_label:

Identifier for the trial (used for logging/debugging).

type unit_label:

str

param trigger:

External trigger handler (default: a dummy TriggerSender instance).

type trigger:

Trigger, optional

param frame_time:

Duration of a single frame in seconds (default: 1/60 for 60Hz).

type frame_time:

float

add_stim(*stims)

Add one or more visual or sound stimuli to the trial.

Supports calling patterns: .add_stim(stimA) .add_stim(stimA, stimB, stimC) .add_stim([stimA, stimB, stimC])

Parameters:

*stims (visual.BaseVisualStim or sound.Sound or list of such) – One or more PsychoPy stimuli (visual or audio).

Returns:

Returns self for chaining.

Return type:

StimUnit

capture_response(keys, duration, onset_trigger=None, response_trigger=None, timeout_trigger=None, terminate_on_response=True, correct_keys=None, highlight_stim=None, dynamic_highlight=False)

Wait for a keypress or timeout. Supports both time-based and frame-based duration. Triggers and onset time synced to visual flip.

Parameters:
  • keys (list[str]) – Keys to listen for.

  • duration (float) – Response window duration in seconds.

  • onset_trigger (int) – Trigger code sent at stimulus onset.

  • response_trigger (int | dict[str, int]) – Trigger code for response, can be per-key.

  • timeout_trigger (int) – Trigger code for timeout.

  • correct_keys (list[str] | None) – If provided, only keys in this list count as hits.

  • highlight_stim (VisualStim or dict) – If a single stim: draw it around whatever is chosen. If a dict: maps key names -> highlight stimuli.

  • dynamic_highlight (bool) – If True, allow multiple key presses and update the highlight each time.

Return type:

StimUnit

clear_stimuli()

Clear all previously added stimuli from the trial.

Return type:

StimUnit

close_on(*keys)

Auto-close the trial on specific key press.

Parameters:

keys (str) – One or more response keys.

duration(duration)

Auto-close the trial after a fixed or jittered duration.

Parameters:

duration (float or list) – Duration or (min, max) range for random sampling.

get_dict(target=None)

Return the internal state dictionary, or merge into an external one.

Parameters:

target (dict, optional) – If provided, updates this dict in-place and returns it.

Returns:

The internal state (or merged result if target is provided).

Return type:

dict

get_state(key, default=None, prefix=None)

Retrieve a value from internal state.

Lookup order: 1. Try exact key. 2. If not found, try prefixed key using: - provided prefix (if given) - otherwise self.label

Parameters:
  • key (str) – State variable name.

  • default (Any) – Value to return if key is not found.

  • prefix (str, optional) – Optional manual prefix to use (overrides self.label).

Returns:

Stored value, or default if not found.

Return type:

Any

log_unit()

Log the current state using PsychoPy’s logging mechanism.

Return type:

None

on_end(func=None)

Register or decorate a function to call at the end of the trial.

on_response(keys, func=None)

Register or decorate a function to call when a valid response key is pressed.

Parameters:
  • keys (list[str]) – Keys that trigger the callback.

  • func (Callable or None) – A function accepting (StimUnit, key, rt) or None to use as decorator.

on_start(func=None)

Register or decorate a function to call at trial start.

on_timeout(timeout, func=None)

Register or decorate a function to call on timeout.

Parameters:
  • timeout (float) – Time in seconds after which timeout is triggered.

  • func (Callable or None) – A function accepting (StimUnit) or None to use as decorator.

run(terminate_on_response=True)

Full logic loop for displaying stimulus, collecting response, handling timeout, and logging with precision timing.

Return type:

StimUnit

Parameters:

terminate_on_responsebool

Whether to terminate the trial upon receiving a response.

send_trigger(trigger_code)

Send a trigger value via the connected trigger object.

Parameters:

trigger_code (int) – The value to send.

Return type:

StimUnit

set_state(prefix=None, **kwargs)

Update internal state with optional key prefixing.

Parameters:
  • prefix (str, optional) – If None, use self.label. If “”, store keys as-is. Else use prefix + ‘_’.

  • kwargs (dict) – State variables to store.

Return type:

StimUnit

show(duration=None, onset_trigger=None, offset_trigger=None)

Display the stimulus for a specified duration, using frame-based timing (recommended for EEG/fMRI). Audio playback is automatically started on stimulus onset.

If duration is None, the longest duration of any sound stimulus will be used. If duration is set explicitly, it will be respected even if shorter than any sound duration.

Parameters:
  • duration (float | list | tuple | None) – Duration of stimulus presentation (in seconds). Can be: - A fixed number - A (min, max) range to sample from - None → automatically use max sound duration (if any)

  • onset_trigger (int) – Trigger code to send at stimulus onset.

  • offset_trigger (int) – Trigger code to send at stimulus offset.

Return type:

StimUnit

Returns:

  • StimUnit

  • Behavior Table

  • ————–

  • | Condition | Behavior |

  • |——————————————|——————————————————|

  • | duration=None | Uses longest sound (or 0.0 if no sound) |

  • | duration=(1, 2) | Samples uniformly in [1, 2], regardless of sound |

  • | duration=1.0 + sound is 2.5 seconds | Screen ends at 1.0s, sound may be cut off early |

  • | duration=None + sound is 2.5 seconds | Screen and sound will both last full 2.5s |

to_dict(target=None)

Return the StimUnit

Parameters:

target (dict, optional) – If provided, updates this dict in-place and returns it.

Returns:

StimUnit for chaining.

Return type:

StimUnit

wait_and_continue(keys=['space'], min_wait=None, log_message=None, terminate=False)

Display the current stimuli (visual and sound) and wait for a key press to continue or quit.

Parameters:
  • keys (list[str]) – Keys that allow the trial to proceed (default: [“space”]).

  • min_wait (float or None) – Minimum time to wait before accepting key press. If None, and any sound stimuli are present, it is automatically set to the longest sound duration.

  • log_message (str, optional) – Optional log message (default: auto-generated).

  • terminate (bool) – If True, the experiment will quit after key press.

Return type:

StimUnit

psyflow.TriggerSender module

class psyflow.TriggerSender.TriggerSender(trigger_func=None, *, mock=False, post_delay=0.001, on_trigger_start=None, on_trigger_end=None)

Bases: object

A wrapper for sending EEG/MEG trigger codes with optional hooks and delays.

Can be initialized with a real sending function or used in mock mode for development/testing without hardware.

Examples

>>> sender = TriggerSender(lambda c: port.write(bytes([c])))
>>> sender.send(32)
>>> sender = TriggerSender(mock=True)
>>> sender.send(99)
send(code)

Send a trigger code using the configured function and callbacks.

Parameters:

code (int or None) – The code to send. Skips if None and logs a warning.

psyflow.utils module

psyflow.utils.count_down(win, seconds=3, **stim_kwargs)

Display a frame-accurate countdown using TextStim.

Parameters:
  • win (psychopy.visual.Window) – The PsychoPy window to display the countdown in.

  • seconds (int) – How many seconds to count down from.

  • **stim_kwargs (dict) – Additional keyword arguments for TextStim (e.g., font, height, color).

psyflow.utils.initialize_exp(settings, screen_id=1)

Initialize the experiment environment including window, keyboard, logging, and global quit key.

Parameters:
  • settings – Configuration object with display, logging, and task settings.

  • screen_id (int) – ID of the screen to display the experiment window on.

Returns:

The initialized PsychoPy window and keyboard objects.

Return type:

Tuple[Window, Keyboard]

psyflow.utils.load_config(config_file='config/config.yaml', extra_keys=None)

Load a config.yaml file and return a structured dictionary.

Parameters:
  • config_file (str) – Path to YAML config file.

  • extra_keys (list of str, optional) – Additional top-level keys to extract as ‘xxx_config’.

Returns:

Dictionary with structured configs.

Return type:

dict

psyflow.utils.show_ports()

List all available serial ports with descriptions.

psyflow.utils.taps(task_name, template='cookiecutter-psyflow')

Module contents

psyflow: A utility package for modular PsychoPy experiment development.