### Install PsyFlow Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt Install the PsyFlow library using pip. You can install the latest stable version from PyPI or the development version directly from GitHub. ```bash pip install psyflow ``` ```bash pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Install PsyFlow Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md Install the PsyFlow library using pip. You can install the latest stable version from PyPI or the development version directly from GitHub. ```bash pip install psyflow ``` ```bash pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Install PsyFlow using pip Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Installs the latest stable version of PsyFlow from the Python Package Index (PyPI). This is the recommended method for getting started with the library. ```shell pip install psyflow ``` -------------------------------- ### Install PsyFlow from GitHub Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Installs the latest development version of the PsyFlow library directly from its GitHub repository using pip. This ensures access to the newest features and updates. ```bash pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Install PsyFlow from GitHub Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html Installs the latest development version of PsyFlow directly from its GitHub repository using pip. This command ensures you have the most recent features and updates available. ```shell pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Initialize PsyFlow Project Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt Create a new PsyFlow project with a standardized folder structure using the `psyflow-init` command-line tool. This sets up directories for configuration, source code, and data. ```bash psyflow-init my-simple-task ``` -------------------------------- ### PsyFlow Experiment Configuration Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt Define experiment parameters, subject information fields, window settings, task structure, stimuli, and timing using a YAML file. This declarative approach simplifies experiment setup and modification. ```yaml # config/config.yaml # === Subject info form === subinfo_fields: - name: subject_id type: int constraints: min: 1 max: 999 - name: gender type: choice choices: [Male, Female] # === Window settings === window: size: [1280, 720] bg_color: gray fullscreen: False # === Task-level settings === task: task_name: "simple_rt" total_blocks: 2 trial_per_block: 10 conditions: [go] # We only have one condition in this simple task key_list: [space] # === Stimuli Definitions === stimuli: instruction: type: textbox text: | Welcome! Press the spacebar as fast as you can when you see the green circle. Press space to begin. color: white font: Arial letterHeight: 0.8 fixation: type: text text: "+" color: white height: 2 target: type: circle radius: 3 fillColor: green lineColor: black # === Timing === timing: fixation_duration: [0.5, 1.0] # Random duration between 500ms and 1000ms response_window: 2.0 # 2 seconds to respond ``` -------------------------------- ### PsyFlow Experiment Configuration Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md Define experiment parameters, subject information fields, window settings, task structure, stimuli, and timing using a YAML file. This declarative approach simplifies experiment setup and modification. ```yaml # config/config.yaml # === Subject info form === subinfo_fields: - name: subject_id type: int constraints: min: 1 max: 999 - name: gender type: choice choices: [Male, Female] # === Window settings === window: size: [1280, 720] bg_color: gray fullscreen: False # === Task-level settings === task: task_name: "simple_rt" total_blocks: 2 trial_per_block: 10 conditions: [go] # We only have one condition in this simple task key_list: [space] # === Stimuli Definitions === stimuli: instruction: type: textbox text: | Welcome! Press the spacebar as fast as you can when you see the green circle. Press space to begin. color: white font: Arial letterHeight: 0.8 fixation: type: text text: "+" color: white height: 2 target: type: circle radius: 3 fillColor: green lineColor: black # === Timing === timing: fixation_duration: [0.5, 1.0] # Random duration between 500ms and 1000ms response_window: 2.0 # 2 seconds to respond ``` -------------------------------- ### Initialize PsyFlow Project Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md Create a new PsyFlow project with a standardized folder structure using the `psyflow-init` command-line tool. This sets up directories for configuration, source code, and data. ```bash psyflow-init my-simple-task ``` -------------------------------- ### Define Experiment Configuration (config.yaml) Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html An example YAML file for configuring a PsyFlow experiment. It specifies subject information fields, window settings, task parameters, stimuli definitions (instruction, fixation, target), and timing details. ```yaml # config/config.yaml # === 被试信息表单 === subinfo_fields: - name: subject_id type: int constraints: min: 1 max: 999 - name: gender type: choice choices: [Male, Female] # === 窗口设置 === window: size: [1280, 720] bg_color: gray fullscreen: False # === 任务级别设置 === task: task_name: "simple_rt" total_blocks: 2 trial_per_block: 10 conditions: [go] # 在这个简单的任务中,我们只有一个条件 key_list: [space] # === 刺激定义 === stimuli: instruction: type: textbox text: | 欢迎! 当您看到绿色圆圈时, 请尽快按下空格键。 按空格键开始。 color: white font: Arial letterHeight: 0.8 fixation: type: text text: "+" color: white height: 2 target: type: circle radius: 3 fillColor: green lineColor: black # === 计时 === timing: fixation_duration: [0.5, 1.0] # 500ms 到 1000ms 之间的随机持续时间 response_window: 2.0 # 2 秒响应时间 ``` -------------------------------- ### Run PsyFlow Experiment Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt Command to execute the main PsyFlow experiment script from the terminal. ```bash python main.py ``` -------------------------------- ### Run PsyFlow Experiment Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md Command to execute the main PsyFlow experiment script from the terminal. ```bash python main.py ``` -------------------------------- ### Initialize PsyFlow Project Structure Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Creates a standardized project directory layout for a new PsyFlow experiment. This command-line tool helps organize configuration, source code, and data files. ```bash psyflow-init my-simple-task ``` -------------------------------- ### Initialize PsyFlow Project Structure Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html Uses the `psyflow-init` command-line tool to create a standardized project directory structure. This includes folders for configuration, source code, and data, promoting organized experiment development. ```shell psyflow-init my-simple-task ``` -------------------------------- ### Complete StimUnit Experiment Example Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_trialunit.md.txt A comprehensive example demonstrating the setup and execution of a psychopy experiment using StimUnit. It covers stimulus creation, trial definition with response handlers, stimulus presentation with triggers, state management, and data collection. The example includes setting up stimuli, defining trial logic, handling responses, and running a block of trials. ```python from psychopy import visual, core from psychopy.hardware.keyboard import Keyboard from psyflow import StimUnit, TriggerSender import random # Setup win = visual.Window(size=[1024, 768], color="black", units="deg") kb = Keyboard() sender = TriggerSender(mock=True) # Create stimuli fixation = visual.TextStim(win, text="+", height=1.0, color="white") left_target = visual.Circle(win, radius=0.8, fillColor="blue", pos=[-5, 0]) right_target = visual.Circle(win, radius=0.8, fillColor="red", pos=[5, 0]) left_highlight = visual.Rect(win, width=3, height=3, lineColor="yellow", lineWidth=3, pos=[-5, 0], fillColor=None) right_highlight = visual.Rect(win, width=3, height=3, lineColor="yellow", lineWidth=3, pos=[5, 0], fillColor=None) feedback_correct = visual.TextStim(win, text="Correct!", height=0.8, color="green", pos=[0, -3]) feedback_incorrect = visual.TextStim(win, text="Incorrect", height=0.8, color="red", pos=[0, -3]) # Run a trial def run_trial(condition): # Determine correct response for this condition if condition == "left": correct_key = "left" target_trigger = 11 else: # condition == "right" correct_key = "right" target_trigger = 12 # Create trial unit trial = StimUnit("choice", win, kb, triggersender=sender) # Register response handler @trial.on_response(["left", "right"]) def handle_response(unit, key, rt): # Check if response is correct is_correct = (key == correct_key) unit.set_state(correct=is_correct) # Show appropriate feedback unit.clear_stimuli() if is_correct: unit.add_stim(feedback_correct) else: unit.add_stim(feedback_incorrect) # Show fixation fixation_trial = StimUnit("fixation", win, kb, triggersender=sender) fixation_trial.add_stim(fixation).show( duration=(0.8, 1.2), # Jittered duration onset_trigger=10 ) # Show targets and collect response trial.add_stim(left_target, right_target) trial.set_state(condition=condition, correct_key=correct_key) trial.capture_response( keys=["left", "right"], duration=2.0, onset_trigger=target_trigger, response_trigger={"left": 21, "right": 22}, timeout_trigger=29, correct_keys=[correct_key], highlight_stim={"left": left_highlight, "right": right_highlight} ) # Show feedback for 1 second core.wait(1.0) # Return trial data return trial.to_dict() # Run a block of trials results = [] conditions = ["left", "right"] * 5 # 10 trials total random.shuffle(conditions) for i, condition in enumerate(conditions): print(f"Trial {i+1}/{len(conditions)}") trial_data = run_trial(condition) trial_data["trial_num"] = i + 1 results.append(trial_data) core.wait(0.5) # Inter-trial interval # Show completion message end_trial = StimUnit("end", win, kb, triggersender=sender) end_text = visual.TextStim( win, text="Experiment complete. Thank you!", height=0.7 ) end_trial.add_stim(end_text).wait_and_continue( keys=["space"], terminate=True ) # Clean up win.close() # Analyze results correct_count = sum(1 for trial in results if trial.get("correct", False)) accuracy = correct_count / len(results) * 100 print(f"Accuracy: {accuracy:.1f}%") ``` -------------------------------- ### Execute PsyFlow Experiment Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Command to run the PsyFlow experiment from the terminal. This command navigates to the experiment directory and executes the main Python script. ```bash python main.py ``` -------------------------------- ### Main Experiment Script (main.py) Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html The primary Python script that initializes and runs the experiment. It loads configuration, collects subject data, sets up the experiment window and stimuli, runs blocks of trials, and saves the collected data. ```python # main.py from psyflow import ( BlockUnit, StimBank, SubInfo, TaskSettings, load_config, initialize_exp, count_down ) import pandas as pd from psychopy import core from functools import partial from src.run_trial import run_trial # 1. 从 YAML 文件加载所有配置 cfg = load_config() # 2. 收集被试信息 subform = SubInfo(cfg['subinfo_config']) subject_data = subform.collect() # 3. 设置任务设置 settings = TaskSettings.from_dict(cfg['task_config']) settings.add_subinfo(subject_data) # 4. 设置窗口和键盘 win, kb = initialize_exp(settings) # 5. 加载配置中定义的所有刺激 stim_bank = StimBank(win, cfg['stim_config']).preload_all() # 6. 显示说明并等待开始 StimUnit('instruction', win, kb) \ .add_stim(stim_bank.get('instruction')) \ .wait_and_continue() # 7. 运行所有组块和试验 all_data = [] for block_i in range(settings.total_blocks): count_down(win, 3) # 在组块前显示 3 秒倒计时 block = BlockUnit( block_id=f"block_{block_i}", settings=settings, window=win, keyboard=kb ).generate_conditions() \ .run_trial(partial(run_trial, stim_bank=stim_bank)) \ .to_dict(all_data) # 8. 保存收集的数据 df = pd.DataFrame(all_data) df.to_csv(settings.res_file, index=False) print(f"数据已保存到 {settings.res_file}") # 9. 清理并退出 core.quit() ``` -------------------------------- ### PsyFlow Experiment Main Script Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html This Python script demonstrates the core workflow of a PsyFlow experiment. It covers loading configurations, collecting subject data, initializing the experiment window and keyboard, preloading stimuli, displaying instructions, running experimental blocks with trials, saving collected data, and cleaning up resources. ```python from src.run_trial import run_trial import pandas as pd from psychopy import core from functools import partial # Assuming load_config, SubInfo, TaskSettings, initialize_exp, StimBank, StimUnit, BlockUnit, count_down are defined elsewhere in the PsyFlow library # 1. Load all configurations from the YAML file cfg = load_config() # 2. Collect subject information subform = SubInfo(cfg['subinfo_config']) subject_data = subform.collect() # 3. Set up task settings settings = TaskSettings.from_dict(cfg['task_config']) settings.add_subinfo(subject_data) # 4. Set up window and keyboard win, kb = initialize_exp(settings) # 5. Load all stimuli defined in the config stim_bank = StimBank(win, cfg['stim_config']).preload_all() # 6. Display instructions and wait to start StimUnit('instruction', win, kb) \ .add_stim(stim_bank.get('instruction')) \ .wait_and_continue() # 7. Run all blocks and trials all_data = [] for block_i in range(settings.total_blocks): count_down(win, 3) # Show a 3-second countdown before the block block = BlockUnit( block_id=f"block_{block_i}", settings=settings, window=win, keyboard=kb ).generate_conditions() \ .run_trial(partial(run_trial, stim_bank=stim_bank)) \ .to_dict(all_data) # 8. Save the collected data df = pd.DataFrame(all_data) df.to_csv(settings.res_file, index=False) print(f"Data saved to {settings.res_file}") # 9. Clean up and exit core.quit() ``` -------------------------------- ### PsyFlow Main Script (`main.py`) Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt The main Python script for a PsyFlow experiment. It loads configurations, initializes the experiment, runs trials using `BlockUnit` and `StimBank`, and saves the results. Requires PsyFlow, pandas, and psychopy libraries. ```python # main.py from psyflow import ( BlockUnit, StimBank, SubInfo, TaskSettings, load_config, initialize_exp, count_down ) import pandas as pd from psychopy import core from functools import partial from src.run_trial import run_trial # 1. Load all configurations from the YAML file cfg = load_config() # 2. Collect subject information subform = SubInfo(cfg['subinfo_config']) subject_data = subform.collect() # 3. Set up task settings settings = TaskSettings.from_dict(cfg['task_config']) settings.add_subinfo(subject_data) # 4. Set up window and keyboard win, kb = initialize_exp(settings) # 5. Load all stimuli defined in the config stim_bank = StimBank(win, cfg['stim_config']).preload_all() # 6. Display instructions and wait to start StimUnit('instruction', win, kb) \ .add_stim(stim_bank.get('instruction')) \ .wait_and_continue() # 7. Run all blocks and trials all_data = [] for block_i in range(settings.total_blocks): count_down(win, 3) # Show a 3-second countdown before the block block = BlockUnit( block_id=f"block_{block_i}", settings=settings, window=win, keyboard=kb ).generate_conditions() \ .run_trial(partial(run_trial, stim_bank=stim_bank)) \ .to_dict(all_data) # 8. Save the collected data df = pd.DataFrame(all_data) df.to_csv(settings.res_file, index=False) print(f"Data saved to {settings.res_file}") # 9. Clean up and exit core.quit() ``` -------------------------------- ### PsyFlow Main Script (`main.py`) Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md The main Python script for a PsyFlow experiment. It loads configurations, initializes the experiment, runs trials using `BlockUnit` and `StimBank`, and saves the results. Requires PsyFlow, pandas, and psychopy libraries. ```python # main.py from psyflow import ( BlockUnit, StimBank, SubInfo, TaskSettings, load_config, initialize_exp, count_down ) import pandas as pd from psychopy import core from functools import partial from src.run_trial import run_trial # 1. Load all configurations from the YAML file cfg = load_config() # 2. Collect subject information subform = SubInfo(cfg['subinfo_config']) subject_data = subform.collect() # 3. Set up task settings settings = TaskSettings.from_dict(cfg['task_config']) settings.add_subinfo(subject_data) # 4. Set up window and keyboard win, kb = initialize_exp(settings) # 5. Load all stimuli defined in the config stim_bank = StimBank(win, cfg['stim_config']).preload_all() # 6. Display instructions and wait to start StimUnit('instruction', win, kb) \ .add_stim(stim_bank.get('instruction')) \ .wait_and_continue() # 7. Run all blocks and trials all_data = [] for block_i in range(settings.total_blocks): count_down(win, 3) # Show a 3-second countdown before the block block = BlockUnit( block_id=f"block_{block_i}", settings=settings, window=win, keyboard=kb ).generate_conditions() \ .run_trial(partial(run_trial, stim_bank=stim_bank)) \ .to_dict(all_data) # 8. Save the collected data df = pd.DataFrame(all_data) df.to_csv(settings.res_file, index=False) print(f"Data saved to {settings.res_file}") # 9. Clean up and exit core.quit() ``` -------------------------------- ### PsyFlow Main Experiment Script Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html The primary Python script for a PsyFlow experiment. It handles loading configurations, initializing the experiment environment, managing trial blocks, and saving collected data. ```python from psyflow import ( BlockUnit, StimBank, SubInfo, TaskSettings, load_config, initialize_exp, count_down ) import pandas as pd from psychopy import core from functools import partial # Example of how to use these imports (actual experiment logic would follow) # config = load_config('config/config.yaml') # exp = initialize_exp(config) # exp.run() # exp.save_data() ``` -------------------------------- ### Run the PsyFlow Experiment Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html Command to execute the main experiment script from the terminal. This launches the PsychoPy application, presents the subject information form, instructions, and then runs the defined task. ```shell python main.py ``` -------------------------------- ### PsyFlow Trial Logic Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started.md.txt Implement the logic for a single trial using PsyFlow's `StimUnit`. This Python code demonstrates showing a fixation cross and then a target stimulus while capturing user responses. ```python # src/run_trial.py from psyflow import StimUnit from functools import partial def run_trial(win, kb, settings, condition, stim_bank): """ Runs a single trial of the reaction time task. """ # Create a dictionary to store data for this trial trial_data = {"condition": condition} # Use a partial function to pre-fill common StimUnit arguments make_unit = partial(StimUnit, win=win, kb=kb) # 1. Show fixation cross make_unit(unit_label='fixation') \ .add_stim(stim_bank.get("fixation")) \ .show(duration=settings.fixation_duration) \ .to_dict(trial_data) # 2. Show target and capture response make_unit(unit_label='target') \ .add_stim(stim_bank.get("target")) \ .capture_response( keys=settings.key_list, duration=settings.response_window ) \ .to_dict(trial_data) return trial_data ``` -------------------------------- ### PsyFlow Trial Logic Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started.md Implement the logic for a single trial using PsyFlow's `StimUnit`. This Python code demonstrates showing a fixation cross and then a target stimulus while capturing user responses. ```python # src/run_trial.py from psyflow import StimUnit from functools import partial def run_trial(win, kb, settings, condition, stim_bank): """ Runs a single trial of the reaction time task. """ # Create a dictionary to store data for this trial trial_data = {"condition": condition} # Use a partial function to pre-fill common StimUnit arguments make_unit = partial(StimUnit, win=win, kb=kb) # 1. Show fixation cross make_unit(unit_label='fixation') \ .add_stim(stim_bank.get("fixation")) \ .show(duration=settings.fixation_duration) \ .to_dict(trial_data) # 2. Show target and capture response make_unit(unit_label='target') \ .add_stim(stim_bank.get("target")) \ .capture_response( keys=settings.key_list, duration=settings.response_window ) \ .to_dict(trial_data) return trial_data ``` -------------------------------- ### PsyFlow Experiment Configuration Schema Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Defines the structure and parameters for a PsyFlow experiment using YAML. This declarative approach separates experiment logic from configuration, covering subject information, window settings, task parameters, stimuli, and timing. ```APIDOC subinfo_fields: - name: subject_id type: int constraints: min: 1 max: 999 - name: gender type: choice choices: [Male, Female] window: size: [1280, 720] bg_color: gray fullscreen: False task: task_name: "simple_rt" total_blocks: 2 trial_per_block: 10 conditions: [go] key_list: [space] stimuli: instruction: type: textbox text: | Welcome! Press the spacebar as fast as you can when you see the green circle. Press space to begin. color: white font: Arial letterHeight: 0.8 fixation: type: text text: "+" color: white height: 2 target: type: circle radius: 3 fillColor: green lineColor: black timing: fixation_duration: [0.5, 1.0] response_window: 2.0 ``` -------------------------------- ### Install PsyFlow Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/getting_started_cn.md.txt Instructions for installing the PsyFlow library. It can be installed from PyPI for the latest stable version or directly from GitHub for the development version. ```bash pip install psyflow ``` ```bash pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Psyflow Tutorials Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/py-modindex.html Provides links to tutorials for getting started with and utilizing the psyflow library. Tutorials cover core functionalities such as setting up tasks, managing stimuli, collecting participant data, and sending hardware triggers. ```English Getting Started with PsyFlow SubInfo: Collecting Participant Information TaskSettings: Configuring Your Experiment BlockUnit: Managing Trials StimBank: Flexible Stimulus Management StimUnit: Modular Stimulus & Response Handler TriggerSender: Sending Hardware Triggers psyflow-init: Command-Line Interface Utility Functions LLMClient: Using Large Language Models ``` -------------------------------- ### Install PsyFlow Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/getting_started_cn.md Instructions for installing the PsyFlow library. It can be installed from PyPI for the latest stable version or directly from GitHub for the development version. ```bash pip install psyflow ``` ```bash pip install git+https://github.com/Xiong-Hao-MHC/psyflow.git ``` -------------------------------- ### Complete StimBank Workflow Example Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/build_stimulus_cn.md A comprehensive example combining stimulus definition in YAML, StimBank initialization, preloading, and dynamic retrieval within a simple trial loop. It demonstrates the practical application of StimBank. ```python from psychopy import visual from psyflow.stim_bank import StimBank from psyflow.stim_unit import StimUnit from psychopy.hardware.keyboard import Keyboard # 1. Setup win = visual.Window(size=[800, 600], color='black') kb = Keyboard() # 2. Stimulus definitions loaded from YAML (or defined directly) stim_config = { 'fixation': {'type': 'text', 'text': '+'}, 'feedback': {'type': 'text', 'text': 'You scored {points} points!'} } # 3. Initialize StimBank and preload stim_bank = StimBank(win, stim_config) stim_bank.preload_all() # --- Trial Loop --- for trial in range(2): # 4. Present a fixation cross fixation_unit = StimUnit('fix', win, kb) fixation_unit.add_stim(stim_bank.get('fixation')) fixation_unit.show(duration=0.5) # (Core trial logic here...) points_this_trial = 10 # Assume points earned # 5. Present dynamic feedback feedback_unit = StimUnit('feedback', win, kb) feedback_stim = stim_bank.get('feedback', points=points_this_trial) feedback_unit.add_stim(feedback_stim) feedback_unit.show(duration=1.0) win.close() ``` -------------------------------- ### Example: Sending Triggers at Block Boundaries Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/build_blocks.md A practical example showing how to attach trigger sending functions to block start and end events using Psyflow's chaining method. This ensures precise timing for external hardware synchronization. ```python from psyflow import BlockUnit # Assuming block_i, settings, win, kb, trigger_sender are defined block = BlockUnit( block_id=f"block_{block_i}", block_idx=block_i, settings=settings, window=win, keyboard=kb ).generate_conditions(func=generate_sst_conditions) .on_start(lambda b: trigger_sender.send(settings.triggers.get("block_onset"))) .on_end(lambda b: trigger_sender.send(settings.triggers.get("block_end"))) ``` -------------------------------- ### Example: Sending Triggers at Block Boundaries Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_blocks.md.txt A practical example showing how to attach trigger sending functions to block start and end events using Psyflow's chaining method. This ensures precise timing for external hardware synchronization. ```python from psyflow import BlockUnit # Assuming block_i, settings, win, kb, trigger_sender are defined block = BlockUnit( block_id=f"block_{block_i}", block_idx=block_i, settings=settings, window=win, keyboard=kb ).generate_conditions(func=generate_sst_conditions) .on_start(lambda b: trigger_sender.send(settings.triggers.get("block_onset"))) .on_end(lambda b: trigger_sender.send(settings.triggers.get("block_end"))) ``` -------------------------------- ### Generate Text Example Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/llm_client.html Shows how to use the generate method of the LLMClient to get a text response from the LLM. ```python prompt = "Hello world" # Generate text with default sampling parameters resp = client.generate(prompt) print(resp) # Generate text with specific temperature resp_deterministic = client.generate(prompt, temperature=0.5) ``` -------------------------------- ### Initialize PsychoPy Experiment Environment Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_modules/psyflow/utils.html Sets up the PsychoPy window, keyboard, and logging system based on provided settings. It configures the display, input devices, global quit key (Ctrl+Q), and logging output, returning the initialized Window and Keyboard objects. ```python from psychopy.visual import Window from psychopy.hardware import keyboard from psychopy import event, core, logging, monitors from typing import Tuple def initialize_exp(settings, screen_id: int = 1) -> Tuple[Window, keyboard.Keyboard]: """Set up the PsychoPy window, keyboard and logging. Parameters ---------- settings : Any Configuration object with attributes describing window and logging settings. screen_id : int, optional Monitor index to open the window on. Defaults to `1`. Returns ------- tuple of (Window, Keyboard) The created PsychoPy `Window` and `Keyboard` objects. Examples -------- >>> win, kb = initialize_exp(my_settings) """ # === Window Setup === mon = monitors.Monitor('tempMonitor') mon.setWidth(getattr(settings, 'monitor_width_cm', 35.5)) mon.setDistance(getattr(settings, 'monitor_distance_cm', 60)) mon.setSizePix(getattr(settings, 'size', [1024, 768])) win = Window( size=getattr(settings, 'size', [1024, 768]), fullscr=getattr(settings, 'fullscreen', False), screen=screen_id, monitor=mon, units=getattr(settings, 'units', 'pix'), color=getattr(settings, 'bg_color', [0, 0, 0]), gammaErrorPolicy='ignore' ) # === Keyboard Setup === kb = keyboard.Keyboard() win.mouseVisible = False # === Global Quit Key (Ctrl+Q) === try: event.globalKeys.clear() # Ensure no duplicate 'q' entries except Exception: pass event.globalKeys.add( key='q', modifiers=['ctrl'], func=lambda: (win.close(), core.quit()), name='shutdown' ) # === Frame Timing === try: settings.frame_time_seconds = win.monitorFramePeriod settings.win_fps = win.getActualFrameRate() or 60 # fallback if FPS detection fails except Exception as e: print(f"[Warning] Could not determine frame rate: {e}") settings.frame_time_seconds = 1 / 60 settings.win_fps = 60 # === Logging Setup === log_path = getattr(settings, 'log_file', 'experiment.log') logging.setDefaultClock(core.Clock()) logging.LogFile(log_path, level=logging.DATA, filemode='a') logging.console.setLevel(logging.INFO) return win, kb ``` -------------------------------- ### StimUnit Initialization and Basic Setup Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/build_stimunit_cn.md Shows how to initialize StimUnit instances for different trial components (fixation, target, feedback) using a StimBank. It also illustrates the use of `functools.partial` for simplifying the instantiation of multiple StimUnits with common parameters. ```python from psychopy import visual from psychopy.hardware.keyboard import Keyboard from psyflow.stim_unit import StimUnit from functools import partial win = visual.Window([1024,768], color='black') kb = Keyboard() # Instantiate StimUnit for each component fix = StimUnit('fix', win, kb).add_stim(stim_bank.get('fixation')) tar = StimUnit('tar', win, kb).add_stim(stim_bank.get('target')) fb = StimUnit('fb', win, kb).add_stim(stim_bank.get('feedback')) # Using functools.partial for simplified instantiation make_unit = partial(StimUnit, win=win, kb=kb) # --- Cue Phase --- fix=make_unit('fix').add_stim(stim_bank.get('fixation')) tar=make_unit('tar').add_stim(stim_bank.get('target')) fb=make_unit('fb').add_stim(stim_bank.get('feedback')) ``` -------------------------------- ### StimUnit Initialization and Basic Setup Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_stimunit_cn.md.txt Shows how to initialize StimUnit instances for different trial components (fixation, target, feedback) using a StimBank. It also illustrates the use of `functools.partial` for simplifying the instantiation of multiple StimUnits with common parameters. ```python from psychopy import visual from psychopy.hardware.keyboard import Keyboard from psyflow.stim_unit import StimUnit from functools import partial win = visual.Window([1024,768], color='black') kb = Keyboard() # Instantiate StimUnit for each component fix = StimUnit('fix', win, kb).add_stim(stim_bank.get('fixation')) tar = StimUnit('tar', win, kb).add_stim(stim_bank.get('target')) fb = StimUnit('fb', win, kb).add_stim(stim_bank.get('feedback')) # Using functools.partial for simplified instantiation make_unit = partial(StimUnit, win=win, kb=kb) # --- Cue Phase --- fix=make_unit('fix').add_stim(stim_bank.get('fixation')) tar=make_unit('tar').add_stim(stim_bank.get('target')) fb=make_unit('fb').add_stim(stim_bank.get('feedback')) ``` -------------------------------- ### PsyFlow Trial Logic Implementation Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started.html Python function to execute a single trial within a PsyFlow experiment. It utilizes `StimUnit` to manage stimuli presentation and response capture, collecting trial-specific data. ```python from psyflow import StimUnit from functools import partial def run_trial(win, kb, settings, condition, stim_bank): """ Runs a single trial of the reaction time task. """ # Create a dictionary to store data for this trial trial_data = {"condition": condition} # Use a partial function to pre-fill common StimUnit arguments make_unit = partial(StimUnit, win=win, kb=kb) # 1. Show fixation cross make_unit(unit_label='fixation') \ .add_stim(stim_bank.get("fixation")) \ .show(duration=settings.fixation_duration) \ .to_dict(trial_data) # 2. Show target and capture response make_unit(unit_label='target') \ .add_stim(stim_bank.get("target")) \ .capture_response( keys=settings.key_list, duration=settings.response_window ) \ .to_dict(trial_data) return trial_data ``` -------------------------------- ### BlockUnit Initialization Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_blocks.md.txt Demonstrates how to initialize a BlockUnit instance with essential parameters like block identifier, index, task settings, and PsychoPy window/keyboard objects. ```Python from psyflow import BlockUnit # Assuming 'settings', 'win', and 'kb' are defined elsewhere # settings: TaskSettings instance # win: PsychoPy Window object # kb: PsychoPy Keyboard object block = BlockUnit( block_id='block1', # unique identifier block_idx=0, # block index (0-based) settings=settings, # TaskSettings instance window=win, # PsychoPy Window keyboard=kb # PsychoPy Keyboard ) ``` -------------------------------- ### Initialize PsychoPy Window, Keyboard, and Logging Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/api/psyflow.html Sets up the PsychoPy window, keyboard, and logging based on provided settings. It takes a configuration object and an optional screen ID. The function returns the created PsychoPy Window and Keyboard objects. ```APIDOC psyflow.utils.initialize_exp(_settings_, _screen_id=1_) Set up the PsychoPy window, keyboard and logging. Parameters: * **settings** (_Any_) – Configuration object with attributes describing window and logging settings. * **screen_id** (_int__,_ _optional_) – Monitor index to open the window on. Defaults to `1`. Returns: The created PsychoPy `Window` and `Keyboard` objects. Return type: tuple of (Window, Keyboard) Examples >>> win, kb = initialize_exp(my_settings) ``` -------------------------------- ### BlockUnit Logging Output Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/build_blocks.html Example log output from BlockUnit, showing metadata logged at the start and end of a block. This includes block ID, index, seed, trial count, distribution, and conditions. ```text [BlockUnit] Blockid: block1 [BlockUnit] Blockidx: 0 [BlockUnit] Blockseed: 12345 [BlockUnit] Blocktrial-N: 40 [BlockUnit] Blockdist: {'A':20,'B':20} [BlockUnit] Blockconditions: ['A','B',...] ``` -------------------------------- ### Initialize StimUnit Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_trialunit.md.txt Demonstrates how to initialize a StimUnit instance with PsychoPy window, keyboard, and an optional trigger sender. Includes examples for mock and real trigger sending. ```python from psychopy import visual from psychopy.hardware.keyboard import Keyboard from psyflow import StimUnit, TriggerSender # Create window and keyboard win = visual.Window(size=[1024, 768], color="black", units="deg") kb = Keyboard() # Create a trigger sender (mock mode for testing) sender = TriggerSender(mock=True) # Initialize a trial unit trial = StimUnit("cue", win, kb, triggersender=sender) # Example with a serial port for real triggers # import serial # port = serial.Serial('COM3', 9600) # trigger = TriggerSender( # send_fn=lambda code: port.write(bytes([code])), # post_delay=0.01 # 10ms delay after sending # ) ``` -------------------------------- ### Implement Single Trial Logic (src/run_trial.py) Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/tutorials/getting_started_cn.html Python code defining the `run_trial` function, which orchestrates a single experimental trial. It uses `StimUnit` to display stimuli (fixation, target) and capture responses, storing trial data. ```python # src/run_trial.py from psyflow import StimUnit from functools import partial def run_trial(win, kb, settings, condition, stim_bank): """ 运行反应时任务的单个试验。 """ # 为此试验创建一个字典来存储数据 trial_data = {"condition": condition} # 使用偏函数预填充常见的 StimUnit 参数 make_unit = partial(StimUnit, win=win, kb=kb) # 1. 显示注视十字 make_unit(unit_label='fixation') \ .add_stim(stim_bank.get("fixation")) \ .show(duration=settings.fixation_duration) \ .to_dict(trial_data) # 2. 显示目标并捕获响应 make_unit(unit_label='target') \ .add_stim(stim_bank.get("target")) \ .capture_response( keys=settings.key_list, duration=settings.response_window ) \ .to_dict(trial_data) return trial_data ``` -------------------------------- ### Psyflow StimUnit Setup and Lifecycle Hooks Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/build_stimunit.md This snippet shows the basic setup for using Psyflow's `StimUnit` for managing stimuli and trial events. It initializes a window, keyboard, and `StimUnit`, then adds a stimulus. The description explains that lifecycle hooks (`start`, `response`, `timeout`, `end`) allow custom code execution at key trial phases, with state keys automatically prefixed by the `unit_label`. ```python from psychopy import core, visual from psychopy.hardware.keyboard import Keyboard from psyflow import StimUnit # 1. Setup win = visual.Window([800,600], color='black', units='deg') kb = Keyboard() unit = StimUnit('demo', win, kb) # 2. Add a stimulus fix = visual.TextStim(win, text='+', height=1.0) unit.add_stim(fix) ``` -------------------------------- ### Psyflow StimUnit Setup and Lifecycle Hooks Source: https://github.com/taskbeacon/psyflow/blob/main/docs/_build/html/_sources/tutorials/build_stimunit.md.txt This snippet shows the basic setup for using Psyflow's `StimUnit` for managing stimuli and trial events. It initializes a window, keyboard, and `StimUnit`, then adds a stimulus. The description explains that lifecycle hooks (`start`, `response`, `timeout`, `end`) allow custom code execution at key trial phases, with state keys automatically prefixed by the `unit_label`. ```python from psychopy import core, visual from psychopy.hardware.keyboard import Keyboard from psyflow import StimUnit # 1. Setup win = visual.Window([800,600], color='black', units='deg') kb = Keyboard() unit = StimUnit('demo', win, kb) # 2. Add a stimulus fix = visual.TextStim(win, text='+', height=1.0) unit.add_stim(fix) ``` -------------------------------- ### List Supported TTS Voices Source: https://github.com/taskbeacon/psyflow/blob/main/docs/tutorials/build_stimulus.md Provides examples of using the list_supported_voices helper function from psyflow.tts_utils to retrieve available TTS voices. It shows how to get all voices or filter them by language code, aiding in voice selection for natural pronunciation. ```python from psyflow.tts_utils import list_supported_voices # All voices tsv = list_supported_voices(human_readable=True) # Filter by language code ts_jp = list_supported_voices(filter_lang="ja", human_readable=True) ```