Install
$ agentstack add skill-neuromechanist-research-skills-experiment-design ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Experiment Design
Design and implement neuroscience experiments with PsychoPy, including stimulus presentation, timing validation, event markers, and Lab Streaming Layer (LSL) integration.
When to Use
- Designing a new behavioral or neuroimaging experiment
- Creating PsychoPy scripts for stimulus presentation
- Setting up event markers via LSL or parallel port
- Validating timing accuracy
- Converting an experiment protocol to code
Experiment Design Principles
Trial Structure
Every trial consists of:
[Fixation] -> [Stimulus] -> [Response Window] -> [Inter-trial Interval]
| | | |
marker marker marker marker
Design Types
| Design | Best For | Example | |--------|----------|---------| | Block | fMRI, sustained attention | 30s blocks of condition A, B | | Event-related | ERP/EEG, rapid events | Randomized single trials | | Mixed | Both sustained and transient | Blocks with jittered events | | Resting state | Baseline/connectivity | Eyes open/closed periods |
Timing Considerations
- Frame-based timing (preferred): Specify durations in frames, not seconds
- Monitor refresh rate: 60 Hz = 16.67 ms/frame; 120 Hz = 8.33 ms/frame
- Stimulus onset: Sync to vertical blank for precise timing
- Jitter: Add random ITI variation for event-related designs (avoid expectation effects)
- Minimum stimulus duration: 1 frame (16.67 ms at 60 Hz)
PsychoPy Experiment Template
Basic Structure
from psychopy import visual, core, event, data, gui
import numpy as np
# Experiment parameters
exp_info = {
"participant": "",
"session": "01",
"task": "experiment_name",
}
# GUI dialog
dlg = gui.DlgFromDict(exp_info, title="Experiment")
if not dlg.OK:
core.quit()
# Window setup
win = visual.Window(
size=[1920, 1080],
fullscr=True,
monitor="testMonitor",
units="deg",
color=[0, 0, 0],
)
# Stimuli
fixation = visual.TextStim(win, text="+", height=2)
stimulus = visual.ImageStim(win, image=None, size=[10, 10])
feedback = visual.TextStim(win, text="", height=1.5)
# Trial handler
conditions = data.importConditions("conditions.xlsx")
trials = data.TrialHandler(
conditions,
nReps=1,
method="random",
)
# Clock
clock = core.Clock()
# Main experiment loop
for trial in trials:
# Fixation
fixation.draw()
win.flip()
core.wait(0.5) # 500 ms fixation
# Stimulus
stimulus.image = trial["stimulus_file"]
stimulus.draw()
win.flip()
# Send marker here
# Response
clock.reset()
keys = event.waitKeys(
maxWait=2.0,
keyList=["left", "right", "escape"],
timeStamped=clock,
)
if keys:
if keys[0][0] == "escape":
core.quit()
trials.addData("response", keys[0][0])
trials.addData("rt", keys[0][1])
# ITI (jittered)
iti = np.random.uniform(0.8, 1.2)
core.wait(iti)
# Save data
import os
os.makedirs("data", exist_ok=True)
trials.saveAsWideText(f"data/sub-{exp_info['participant']}_task-{exp_info['task']}.csv")
win.close()
core.quit()
Conditions File Format
# conditions.xlsx or conditions.csv
stimulus_file,condition,correct_response
stimuli/face01.png,face,left
stimuli/house01.png,house,right
stimuli/face02.png,face,left
Lab Streaming Layer (LSL) Integration
Sending Markers
from pylsl import StreamInfo, StreamOutlet
# Create marker stream
info = StreamInfo(
name="ExperimentMarkers",
type="Markers",
channel_count=1,
nominal_srate=0, # irregular rate
channel_format="string",
source_id="psychopy_markers",
)
outlet = StreamOutlet(info)
# Send marker at stimulus onset
stimulus.draw()
win.flip()
outlet.push_sample(["stimulus_onset"]) # Send immediately after flip
Common Marker Scheme
| Marker | Code | Description | |--------|------|-------------| | stimulusonset | S1-S99 | Stimulus presentation | | response | R1-R4 | Participant response | | feedback | F1-F2 | Correct/incorrect feedback | | blockstart | B1-B10 | Block onset | | blockend | BE | Block offset | | trialstart | T | Trial onset | | experimentstart | EXPSTART | First trial | | experimentend | EXPEND | Last trial |
HED Annotation for Markers
Annotate events with Hierarchical Event Descriptors (HED) for standardized event description:
onset duration trial_type value HED
0.0 0.0 stimulus S1 Sensory-event, Visual-presentation, (Image, Face)
1.5 0.0 response R1 Agent-action, (Press, Key/Left)
Timing Validation
Photodiode Check
# Add a small white square in the corner that flashes with stimulus
photodiode = visual.Rect(win, width=50, height=50, pos=[900, -500], units="pix")
# During stimulus presentation
stimulus.draw()
photodiode.fillColor = [1, 1, 1] # White
photodiode.draw()
win.flip()
# Photodiode sensor on screen corner measures actual onset time
Frame Timing Check
# Check for dropped frames
win.recordFrameIntervals = True
# After experiment:
frame_intervals = win.frameIntervals
dropped = sum(1 for fi in frame_intervals if fi > 1.5 * (1.0 / 60.0))
print(f"Dropped frames: {dropped}/{len(frame_intervals)}")
Output for BIDS
Structure experiment output to be BIDS-compatible:
data/
sub-01/
sub-01_task-name_events.tsv # onset, duration, trial_type, response, rt
sub-01_task-name_beh.tsv # behavioral data
sub-01_task-name_beh.json # metadata
Additional Resources
- Reference: [references/psychopy-components.md](references/psychopy-components.md) - Visual, audio, and response components
- Reference: [references/lsl-integration.md](references/lsl-integration.md) - LSL setup, synchronization, and troubleshooting
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: neuromechanist
- Source: neuromechanist/research-skills
- License: BSD-3-Clause
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.