Thanks for your interest in contributing! This is a PsychoPy implementation of a deterministic Monetary Incentive Delay (MID) task for fMRI. Because it is used to run real experiments, correctness, timing fidelity, and reproducibility matter more than feature velocity. The guidelines below keep contributions safe to deploy on lab and scanner machines.
- Report a bug — crashes, incorrect stimuli/timing, or output-file problems.
- Request a feature — new functionality or tooling.
- Improve documentation — the usage and development guides.
Please open an issue using the appropriate template before starting significant work, so we can agree on the approach first.
UV is the canonical development workflow (it owns the pinned uv.lock); Anaconda
is the production environment. Both install from the same pyproject.toml. See the
Development Guide and AGENTS.md for full details.
# Development (UV)
uv venv && uv sync
uv run pytest
# Production parity check (Anaconda)
conda env create -f environment.yml
conda activate mid-task-deterministicThe MATLAB-parity test (tests/test_calibration_matlab_parity.py) needs GNU Octave
or MATLAB on PATH to run the reference algorithm. Install Octave with
brew install octave. Without an engine the test skips with a loud warning
rather than silently passing.
- This project follows Semantic Versioning. For research code, treat any change that affects data comparability (stimuli, timing, response criterion, output schema) as at least a MINOR bump — usually MAJOR. See the Release Guide for how versions are decided, verified, and cut.
- Write commit messages in the
Conventional Commits style:
type(scope): summary(e.g.fix(trial): correct target frame count). Common types:feat,fix,docs,test,refactor,chore,ci. Mark breaking changes with a!(feat!: ...) or aBREAKING CHANGE:footer. This keeps the changelog and version bumps predictable.
- Fork and branch. Create a topic branch off
main(e.g.fix/target-timing). - Keep imports headless-safe. Source modules guard their
psychopyimports intry/exceptso the logic and timing tests import and run without a display or audio device. CI does not install PsychoPy — do not add a hard top-levelimport psychopyto any module exercised by the test suite. - Add or update tests for the behavior you change. Logic and timing should be covered by headless tests.
- Update the docs and CHANGELOG. Add a
CHANGELOG.mdentry (the format follows Keep a Changelog) and update the usage or development guides if behavior changes. - Preserve UV/conda parity. If you touch dependencies, update both
pyproject.tomlandenvironment.yml, and refreshuv.lock(uv sync).
See the Release Guide for how changes become tagged releases and
what verification (timing via screen recordings, task measurements) gates a stable
versus a pre-release (-alpha/-beta/-rc) version.
Run the full check that CI runs:
uv run pytest -v --ignore=tests/test_overlay.py(tests/test_overlay.py is a manual visual.Window script that needs a live
display; it is intentionally excluded from automated runs.)
Confirm each item:
- Tests pass (
uv run pytest), including the Octave/MATLAB parity test where an engine is available. - Changes are headless/CI safe — logic & timing tests run without PsychoPy or a display.
- Documentation and
CHANGELOG.mdare updated. - Changes work under both the UV (
uv.lock) and conda (environment.yml) workflows.
- Fill out the pull request template completely.
- Link the issue your PR addresses (e.g.
Closes #123). - Keep PRs focused; smaller, single-purpose PRs are reviewed faster.
- A maintainer will review and may request changes. CI (the
testsworkflow) must be green before merge.
By contributing, you agree that your contributions will be licensed under the project's MIT License.