Skip to content

[ENH] BEP044 - Stim-BIDS - #2022

Draft
neuromechanist wants to merge 119 commits into
bids-standard:masterfrom
neuromechanist:master
Draft

[ENH] BEP044 - Stim-BIDS#2022
neuromechanist wants to merge 119 commits into
bids-standard:masterfrom
neuromechanist:master

Conversation

@neuromechanist

@neuromechanist neuromechanist commented Dec 22, 2024

Copy link
Copy Markdown
Member

This PR addresses #153 by introducing specifications for handling and standardizing stimulus files and their annotations within the BIDS specifications. The changes focus on improving the organization, referencing, and metadata of stimulus files to enhance consistency, reusability, and efficiency.

Note

The issue: #153
Google Doc
Example PR: bids-standard/bids-examples#433

Known issues:

  • The validator fails because extensions in /src/schema/rules/files/raw require datatype. Stimuli might be a special data type that can only be present at the root of the dataset. So, the datatype field is missing for now.
  • There are some style errors by the remark validators

cc: @bids-standard/bep044 and @monique2208

Implement the standardization of stimulus files and their annotations within the BIDS specifications.

* **Add new file `src/modality-specific-files/stimuli.md`**
  - Describe the specifications for the stimuli directory.
  - Include guidelines for storing stimulus files and their annotations.
  - Define what goes into `stimuli.tsv/json`, `annotations.tsv/json`, and `stim-<label>.json`.
  - Use the same style as other modality-specific docs to design the tables, variables, and examples.

* **Modify `src/modality-specific-files/task-events.md`**
  - Add a section detailing the standardization of stimulus files and their annotations within the BIDS specifications.
  - Include examples of how to use the `stim_file` and `stim_id` columns in `events.tsv` files.
  - Provide guidelines for storing stimulus files in the `/stimuli` directory.
  - Expand the definition of the `stim_file` column to include `stim_id`.

* **Modify `src/schema/objects/columns.yaml`**
  - Update the definition of the `stim_file` column to ensure consistency in stimulus file references.
  - Add the `stim_id` column definition for `events.tsv` files.

* **Modify `src/schema/rules/checks/events.yaml`**
  - Add a check for missing stimulus files declared in `events.tsv`.
  - Add a check for missing `stim_id` references in `events.tsv`.

* **Modify `src/schema/rules/sidecars/events.yaml`**
  - Specify the `StimulusPresentation` metadata field for `events.tsv` files.
  - Include the `stim_id` column in the metadata field specifications.

* **Modify `src/schema/objects/entities.yaml`**
  - Add entities described in the document with proper requirement levels and descriptions.

* **Modify `src/schema/objects/suffixes.yaml`**
  - Add suffixes for `{audio, image, video, audiovideo}`.
  - Include the file extensions and descriptions for each suffix.

* **Add new file `src/schema/rules/sidecars/stimulus.yaml`**
  - Define sidecar tables for `stimuli.tsv/json`, `annotations.tsv/json`, and `stim-<label>.json`.
  - Use the same style as other modality-specific docs to design the tables.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/neuromechanist/bids-specification?shareId=XXXX-XXXX-XXXX-XXXX).
Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread src/modality-specific-files/stimuli.md
Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread src/modality-specific-files/stimuli.md Outdated
@Remi-Gau

Remi-Gau commented Jan 9, 2025

Copy link
Copy Markdown
Collaborator

will do a bit of clean up to get less red in CI and maybe see if we can get the HTML version of the BEP to render

@Remi-Gau

Remi-Gau commented Jan 9, 2025

Copy link
Copy Markdown
Collaborator

HTML: stimuli page
https://bids-specification--2022.org.readthedocs.build/en/2022/modality-specific-files/stimuli.html

@yarikoptic yarikoptic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initial quick pass with little recommendations etc

Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread src/modality-specific-files/task-events.md Outdated
Comment thread src/schema/rules/files/raw/audio.yaml Outdated
Comment thread src/schema/objects/suffixes.yaml Outdated
Comment thread src/modality-specific-files/stimuli.md Outdated
Comment thread mkdocs.yml Outdated
yarikoptic and others added 8 commits June 3, 2026 11:56
The pixel format (FFmpeg's pix_fmt) applies equally to single images and
video frames: ffprobe reports it for both, and the encoded information
(color model, channel count, chroma subsampling, bit depth) is the same
concept in either case.

Move the field out of MediaVideoProperties into MediaImageProperties
(which already covers image, video, and audiovideo), and rename with the
Image prefix to match the rest of the group (ImageWidth, ImageHeight).
Description broadened from "video stream" to "video frame or image".

Co-Authored-By: Claude Code 2.1.161 / Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Yaroslav Halchenko <debian@onerussian.com>
Per PR review discussion on thread r2989972681 (h-mayorquin proposed,
@CodyCBakerPhD raised the image-vs-video tension on r3349547943):
ImagePixelFormat (FFmpeg pix_fmt) deterministically encodes bit depth
for any FFmpeg-readable file, so ImageBitDepth is redundant for video.
However:

- Common PIL modes (L, RGB, RGBA, P, ...) are implicitly 8-bit-per-
  channel and do not encode bit depth in the mode name. Image-domain
  tooling (Pillow, libtiff, PNG library) surfaces bit depth as a
  first-class integer rather than as part of a pix_fmt string.
- For image-only sidecars whose producing tools do not naturally go
  through FFmpeg, ImagePixelFormat may be absent and bit depth is the
  only color-precision field available.
- An integer is more directly discoverable for the typical researcher
  than the FFmpeg pix_fmt naming convention.

Added as OPTIONAL with an explicit "redundant with ImagePixelFormat
when both present; the two MUST agree" note in the description, so the
redundancy is acknowledged rather than hidden.

Co-authored-by: Heberto Mayorquin <h.mayorquin@gmail.com>
Co-authored-by: Cody Baker <CodyCBakerPhD@gmail.com>
Co-Authored-By: Claude Code 2.1.161 / Claude Opus 4.7 <noreply@anthropic.com>
These are generic media properties usable by any modality that stores
audio, so define them alongside the other common media file definitions:
- flac (.flac) lossless audio extension
- AudioBitDepth metadata, added as an optional field of MediaAudioProperties

Moved here from the BEP047 behavioral PR per review discussion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add flac extension and AudioBitDepth to common media definitions
@neuromechanist neuromechanist linked an issue Jun 26, 2026 that may be closed by this pull request
# Conflicts:
#	src/schema/objects/extensions.yaml
@yarikoptic

Copy link
Copy Markdown
Collaborator

@neuromechanist can you please update the PR merging the #2367 and also addressing the conflicts . What is your plan towards making it available for review?

* mediafiles: (211 commits)
  chore(deps): bump prettier in the node-utilities group (bids-standard#2454)
  chore(deps): bump codecov/codecov-action from 5 to 7 (bids-standard#2453)
  chore(deps): bump the actions-infrastructure group with 2 updates (bids-standard#2452)
  rf(schema): Consolidate `rules.dataset_metadata` under `rules.json` (bids-standard#2348)
  [ENH] Define PET surface map derivatives (bids-standard#2416)
  chore(deps): bump tornado from 6.5.5 to 6.5.7 (bids-standard#2447)
  chore(deps): bump aiohttp from 3.13.4 to 3.14.1
  List flac in the media-files appendix audio formats table
  Add flac extension and AudioBitDepth to common media definitions
  [FIX] Bump pymdown-extensions to >=10.21.2 to restore code-block rendering (bids-standard#2438)
  Add ImageBitDepth (OPTIONAL) under MediaImageProperties
  Minor wording tune up on the choices
  Rename PixelFormat to ImagePixelFormat and move to MediaImageProperties
  Add VideoFrameCount; prefix-align FrameRate, Width, Height
  Clarify Width/Height and add PixelFormat
  Remove overspecification for "photo" and clarify on variable rate
  chore(deps): bump idna from 3.11 to 3.15 in /tools/schemacode
  chore(deps): bump idna from 3.10 to 3.15
  chore(deps): bump urllib3 from 2.6.3 to 2.7.0 in /tools/schemacode
  chore(deps): bump urllib3 from 2.6.3 to 2.7.0
  ...

Conflicts:
	src/schema/objects/metadata.yaml
	src/schema/objects/suffixes.yaml

    there I had to remove duplicated now with mediafiles branch which had
    more generic descriptions . Here is original ones from here

    audio:
      value: audio
      display_name: Audio stimulus file
      description: |
        Any data file used as an audio stimulus. Media files usually have an audio file type (such as wav, mp3, aac, ogg).
        The JSON sidecar associated with each media file should contain information to describe the origin and the
        nature of the media.
        However, in the case of the imposed distribution restrictions of the stimulus, the media stimulus file may not be
        present with only JSON sidecar file containing the aforementioned pertinent metadata.
    image:
      value: image
      display_name: Image stimulus file
      description: |
        Any data file used as an image stimulus. Media files usually have an image file type (such as jpg, png, svg).
        The JSON sidecar associated with each media file should contain information to describe the origin and the
        nature of the media.
        However, in the case of the imposed distribution restrictions of the stimulus, the media stimulus file may not be
        present with only JSON sidecar file containing the aforementioned pertinent metadata.
    video:
      value: video
      display_name: Video stimulus file
      description: |
        Any data file used as a video stimulus. Media files usually have a video file type (such as mp4, avi, mkv, webm).
        The JSON sidecar associated with each media file should contain information to describe the origin and the
        nature of the media.
        However, in the case of the imposed distribution restrictions of the stimulus, the media stimulus file may not be
        present with only JSON sidecar file containing the aforementioned pertinent metadata.
    audiovideo:
      value: audiovideo
      display_name: Audiovideo stimulus file
      description: |
        Any data file used as an audiovideo stimulus. Media files usually have an audiovideo file type (such as mp4, avi,
        mkv, webm).
        The JSON sidecar associated with each media file should contain information to describe the origin and the
        nature of the media.
        However, in the case of the imposed distribution restrictions of the stimulus, the media stimulus file may not be
        present with only JSON sidecar file containing the aforementioned pertinent metadata.

    I also in src/schema/objects/extensions.yaml removed duplicate suffixes detected during pre-commit.
* master: (27 commits)
  enh(metaschema): require and constrain `inherit` in associations + provide it for atlas _description.json (bids-standard#2479)
  chore: Bump schema package to 1.2.8-dev
  chore: Bump schema package to 1.2.7
  fix(ci): Drop test.pypi.org publication
  chore: Bump schema package to 1.2.7-dev
  chore: Bump schema package to 1.2.6
  fix(ci): Fix download-artifact target
  chore: Bump schema package to 1.2.6-dev
  chore: Bump schema package to 1.2.5
  [SCHEMA] Warn when *_beh.tsv contains onset and duration (bids-standard#2467)
  [FIX][SCHEMA] Phenotype subjects are a subset of participants.tsv (bids-standard#2468)
  [INFRA] Add Bluesky social link, drop Twitter (bids-standard#2470)
  [INFRA] Skip link check for encodeproject.org URLs (bids-standard#2469)
  [SCHEMA] Warn when *_beh.tsv contains onset and duration (bids-standard#2467)
  DOC: fix URL to Code of Conduct (bids-standard#2464)
  [ENH] Move PET DICOM correspondences into term definitions (bids-standard#2298)
  [ENH] Render phenotype sidecar table from schema (bids-standard#2324)
  [FIX] Replace non-existent `len` with existent `length` (bids-standard#2466)
  chore(deps): bump soupsieve from 2.8 to 2.8.4
  [pre-commit.ci] pre-commit autoupdate
  ...
Add stimulus and annotation to rules/entities.yaml so filename rules
referencing them resolve. Rewrite stimulus description (referenced a
nonexistent Stimulus metadata field), align annotation description
with the annot_id column, and drop the unused part__stimuli object.
The stim_id existence checks treated identifiers as file paths under
/stimuli and used functions absent from the expression language
(for_any, matches_pattern), so they could never pass. Replace them
with an expressible stimuli.tsv presence check, move value-format
enforcement to column patterns (participant_id convention), and drop
the duplicate STIMULUS_ID_MISSING check from events.yaml.
Add .flac (audio) and .tif (image) to the stimulus file rules and the
formats table in stimuli.md to match the media-files appendix. Fix the
dangling Legacy section reference and a filed/field typo.
The stimulus type column is defined as type__stimuli in columns.yaml;
no sidecar rule references a type metadata field.
Subdirectories are allowed under /stimuli; the dataset-wide stimuli.tsv
and stimuli.json must sit at the /stimuli root, and scoped copies in
subdirectories amend or override them per the Inheritance Principle.
Adds the STIMULI_TSV_NOT_AT_ROOT check (verified against good and bad
layouts with the deno validator).
initial_columns referenced 'type' and 'description' instead of the
type__stimuli and description__annot column keys, which crashed rule
evaluation. Selectors for the catalog tables now match on path instead
of suffix: the validator clears context.suffix for stem-matched files,
so suffix-based selectors never fired and stimuli.tsv columns were
silently unvalidated. Adds a StimuliScoped rule so subdirectory
stimuli.tsv files only require stimulus_id (they amend the root catalog
per the Inheritance Principle).
Subdirectories under /stimuli are fully self-describing so a stimulus
set travels between datasets as a portable unit. A dataset-wide
stimuli.tsv at the /stimuli root, even a sparse one listing only
stimulus_id values, stays RECOMMENDED (warning-level checks) as the
single entry point and override site. Sibling catalogs must not define
the same stimulus_id. Root type column relaxed to recommended so a
sparse root validates cleanly.
@neuromechanist

Copy link
Copy Markdown
Member Author

Quick update on the recent pushes, now that @yarikoptic's media-files harmonization is merged here:

  • The schema caught up with the spec text: the stim/annot entities are properly wired in, the stim_id checks are rewritten so the validator can actually run them (value patterns now live in the column definitions), and stimulus formats are consistent across the appendix, the file rules, and the docs.
  • /stimuli now supports hierarchical subdirectories. A subdirectory is self-describing, so a stimulus set can move between datasets as a portable unit. A dataset-wide stimuli.tsv at the root is RECOMMENDED, even a sparse one listing only the stimulus_ids; scoped catalogs amend or override it following the inheritance principle.
  • Legacy datasets are untouched: the new rules only kick in when a stimuli.tsv exists somewhere under /stimuli.
  • Everything is tested end to end with a new beh_stimuli example ([WIP] examples for BEP044, Stim-BIDS bids-examples#433, now including LLM-generated descriptions and HED annotations for the NSD shared1000 images) and a validator implementation (feat: Support BEP044 stimulus organization in /stimuli bids-validator#445); legacy examples like eeg_matchingpennies validate unchanged.

@yarikoptic yarikoptic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initial, mostly formatting, but raising concern to added groupping folders which are nohow formalized or mostly not inline with the main bids hierarchy building principles (besides hardcoded datatype/ folders)

note that so far BEP does not introduce the concept of stimuli NEAR the data files as we need for reprostim

stimuli.tsv
stimuli.json
annotations.tsv
faces/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, this is "new" to me concept here, somewhat mimicing the "datatype/" folders we have now (anat/, func/ etc) which sticks out like a sore point... yet to digest this and see how to mediate -- since unlike datatype those are nohow formalized. I feel like we would need some 'cohort-' like entity (similar to ses-) to group them and providing cohorts.tsv to describe such groups if we are to go this way

stimuli.json
annotations.tsv
faces/
stimuli.tsv # amends/overrides root entries for stimuli in faces/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that here must be following Inheritance principle but we have not defined it well for .tsv yet!


### Example `stimuli.tsv`

```Text

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are tsv types

src/common-principles.md:```tsv {linenums="1"}
src/common-principles.md-onset      duration        response_time   trial_type      trial_extra
src/common-principles.md-200        20.0    15.8    word    中国人
src/common-principles.md-240        5.0     17.34e-1        visual  n/a
--
src/common-principles.md:```tsvgz {linenums="1"}
src/common-principles.md-200        20.0    15.8    word    中国人
src/common-principles.md-240        5.0     17.34e-1        visual  n/a

hence

Suggested change
```Text
```tsv


Annotations of the still images or general description of the stimuli (such as frequency and duration of a beep sound) can be stored in the `stimuli.tsv` as an additional column or `stim-<label>_<suffix>.json` as described above. Here is an example of how annotations can be stored in the `stimuli.tsv` file for an image from the Natural Scene Dataset (NSD):

| stimulus_id | type | description | HED | NSD_id | COCO_id |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likely this is intended to be yet another tsv inlined example, not .md table right away, reformat


### Example `*_annotations.tsv`

```Text

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also tsv


Example `events.tsv` file:

| onset | duration | trial_type | response_time | stim_id |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also reformat as tsv inline

@neuromechanist

neuromechanist commented Sep 2, 2026

Copy link
Copy Markdown
Member Author

Thanks @yarikoptic,

Deferring the styling convo to later:
I think we briefly discussed having subdirectories in the stimuli/ dir. Having thousands of images or their annotations, could make subdirs quite useful. I still proposed it as a convenience though, meaning that validators and tools flatten them.

On the TSV inheritance I agree that it is loosely defined, although I doubt it would be hard to tighten with examples?

@yarikoptic

Copy link
Copy Markdown
Collaborator

Deferring the styling convo to later: I think we briefly discussed having subdirectories in the stimuli/ dir. Having thousands of images or their annotations, could make subdirs quite useful. I still proposed it as a convenience though, meaning that validators and tools flatten them.

I do feel that directories could be useful but I just noted that it adds some "inconsistency". We should also check on what they do in other related BEPs like BEP036 on that

On the TSV inheritance I agree that it is loosely defined, although I doubt it would be hard to tighten with examples?

I would say we first need to tighten in language since examples can't mandate how things are validated etc, they could just demonstrate. And overall point here, as .tsv as .json just different containers for metadata, it should be congruent with IP overall as there is now no "overrides" but rather only "summarization" into higher levels... the question is either it is on per-row or per-cell basis -- we better make it clear first in common principles outside of this BEP/examples, and here only demonstrate... what example use cases you had in mind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BEP 044: Stimuli Project Tracking