Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/longitudinal-and-multi-site-studies.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ A guide for using macros can be found at
},
"sub-control01_sessions.tsv": "",
},
"participant+sessions.tsv": "",
"participants.tsv": "",
"dataset_description.json": "",
"README": "",
Expand All @@ -71,6 +72,13 @@ ses-predrug 2009-06-15T13:45:30 120
ses-postdrug 2009-06-16T13:45:30 100
```

In addition to per-subject `_sessions.tsv` files,
a dataset-level `participant+sessions.tsv` file can aggregate
metadata that varies across both participants and sessions
(such as age at each session) into a single file.
See [Participant and sessions file](modality-agnostic-files/data-summary-files.md#participant-and-sessions-file)
for details.

See this [example dataset](https://github.com/bids-standard/bids-examples/tree/master/7t_trt)
that has been formatted
using this specification and can be used
Expand Down
57 changes: 57 additions & 0 deletions src/modality-agnostic-files/data-summary-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,63 @@ to date of birth.
}
```

## Participant and sessions file

Template:

```Text
participant+sessions.tsv
participant+sessions.json
```

<!-- This block generates a description.
A guide for using macros can be found at
https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md
-->
{{ MACROS___render_text("objects.files.participant_sessions.description") }}

We RECOMMEND to make use of these columns, and
in case that you do use them, we RECOMMEND to use the following values
for them:

<!-- This block generates a columns table.
The definitions of these fields can be found in
src/schema/rules/tabular_data/*.yaml
and a guide for using macros can be found at
https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md
-->
{{ MACROS___make_columns_table("modality_agnostic.ParticipantSessions") }}

`participant+sessions.tsv` example:

```tsv
participant_id session_id age body_weight
sub-01 ses-predrug 34 81.3
sub-01 ses-postdrug 35 83.1
sub-02 ses-predrug 12 45.2
sub-02 ses-postdrug 13 48.7
```

It is RECOMMENDED to accompany each `participant+sessions.tsv` file with a sidecar
`participant+sessions.json` file to describe the TSV column names and properties
of their values (see also
the [section on tabular files](../common-principles.md#tabular-files)).
Such sidecar files are needed to interpret the data, especially so when
additional columns are defined beyond `age`,
such as `body_weight` in this example.

`participant+sessions.json` example:

```JSON
{
"body_weight": {
"Description": "body weight of the participant at the time of the session",
"Format": "number",
"Units": "kg"
}
}
```

## Samples file

Template:
Expand Down
5 changes: 3 additions & 2 deletions src/schema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,9 @@ Here, `README` and `README.md` are both valid, while only `dataset_description.j
#### Tabular metadata files

`rules.files.common.tables` describes TSV files and their associated metadata,
including `participants.tsv`, `samples.tsv`, `*_sessions.tsv` and `*_scans.tsv`.
The first two use the `stem` field, while the latter two specify the entities used
including `participants.tsv`, `participant+sessions.tsv`, `samples.tsv`,
`*_sessions.tsv` and `*_scans.tsv`.
The first three use the `stem` field, while the latter two specify the entities used
to construct the filename.

The valid fields are:
Expand Down
12 changes: 12 additions & 0 deletions src/schema/meta/context.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ properties:
type: array
items:
type: string
sessions:
description: 'Collections of sessions in dataset'
type: object
required:
- ses_dirs
additionalProperties: false
properties:
ses_dirs:
description: 'Union of all ses-* directories found across all subjects'
type: array
items:
type: string
subject:
description: 'Properties and contents of the current subject'
type: object
Expand Down
10 changes: 10 additions & 0 deletions src/schema/objects/files.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ participants:
(for examples `homo sapiens`, `mus musculus`, `rattus norvegicus`).
For backwards compatibility, if `species` is absent, the participant is assumed to be
`homo sapiens`.
participant_sessions:
display_name: Participant and Session Information
file_type: regular
description: |
The purpose of this OPTIONAL file is to describe properties that vary
across both participants and sessions, such as age at each session.
If this file exists, it MUST contain the columns `participant_id` and `session_id`,
which MUST consist of `sub-<label>` and `ses-<label>` values respectively,
identifying one row for each participant-session combination.
Each combination of participant and session MUST be described by one and only one row.
samples:
display_name: Sample Information
file_type: regular
Expand Down
37 changes: 37 additions & 0 deletions src/schema/rules/checks/dataset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,43 @@ ParticipantIDMismatch:
sorted(dataset.subjects.sub_dirs)
)

ParticipantSessionsParticipantsMissing:
issue:
code: PARTICIPANT_SESSIONS_PARTICIPANTS_MISSING
message: |
participant+sessions.tsv lists participant_id values that do not correspond
to subject directories found in the dataset.
level: error
selectors:
- path == '/participant+sessions.tsv'
checks:
- |
allequal(
sorted(intersects(columns.participant_id, dataset.subjects.sub_dirs)),
sorted(unique(columns.participant_id))
)

ParticipantSessionsSessionsMissing:
issue:
code: PARTICIPANT_SESSIONS_SESSIONS_MISSING
message: |
participant+sessions.tsv lists session_id values that do not correspond
to session directories found in the dataset.
level: error
selectors:
- path == '/participant+sessions.tsv'
checks:
- |
allequal(
sorted(intersects(columns.session_id, dataset.sessions.ses_dirs)),
sorted(unique(columns.session_id))
)

# TODO: Add a check that each (participant_id, session_id) *combination*
# corresponds to an actual sub-*/ses-*/ directory. The current check only
# validates the sets independently. Checking combinations requires either
# string concatenation in the expression language or a dedicated function.

# 214
SamplesTSVMissing:
issue:
Expand Down
6 changes: 6 additions & 0 deletions src/schema/rules/files/common/tables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ participants:
extensions:
- .tsv
- .json
participant_sessions:
level: optional
stem: participant+sessions
extensions:
- .tsv
- .json
samples:
level: optional
stem: samples
Expand Down
20 changes: 20 additions & 0 deletions src/schema/rules/tabular_data/modality_agnostic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ Participants:
index_columns: [participant_id]
additional_columns: allowed

ParticipantSessions:
selectors:
- path == "/participant+sessions.tsv"
initial_columns:
- participant_id
- session_id
columns:
participant_id:
level: required
description_addendum: |
There MUST be exactly one row for each combination of participant and session.
session_id: required
age:
level: optional
description_addendum: |
Age of the participant at the time of the session.
HED: optional
index_columns: [participant_id, session_id]
additional_columns: allowed

Samples:
selectors:
- path == "/samples.tsv"
Expand Down
Loading