Skip to content

Commit 75924cf

Browse files
authored
Merge branch 'master' into plus-sign-labels
2 parents f551f7d + 79e4ea8 commit 75924cf

File tree

13 files changed

+77
-49
lines changed

13 files changed

+77
-49
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ repos:
4747
files: tools/schemacode
4848
args: ["--settings-file", "tools/schemacode/pyproject.toml"]
4949
- repo: https://github.com/pyCQA/flake8
50-
rev: 7.1.1
50+
rev: 7.1.2
5151
hooks:
5252
- id: flake8
5353
args: [--config=tools/schemacode/.flake8]
@@ -74,7 +74,7 @@ repos:
7474
- id: codespell
7575
args: ["--config=.codespellrc", "--dictionary=-", "--dictionary=.codespell_dict"]
7676
- repo: https://github.com/pre-commit/mirrors-mypy
77-
rev: v1.14.1
77+
rev: v1.15.0
7878
hooks:
7979
- id: mypy
8080
# Sync with project.optional-dependencies.typing

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ If you have any questions that aren't discussed below, please let us know
99
by [opening an issue](https://github.com/bids-standard/bids-specification/issues/new).
1010

1111
If you are not familiar with Git and GitHub,
12-
check our [generic contributing guidelines](https://bids-website.readthedocs.io/en/latest/collaboration/bids_github/CONTRIBUTING.html).
12+
check our [generic contributing guidelines](https://bids.neuroimaging.io/collaboration/bids_github/CONTRIBUTING.html).
1313

1414
If you want to contribute to the BIDS specification,
1515
make sure you also read the instructions below.

src/schema/README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -259,20 +259,20 @@ The following operators should be defined by an interpreter:
259259

260260
The following functions should be defined by an interpreter:
261261

262-
| Function | Definition | Example | Note |
263-
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ |
264-
| `count(arg: array, val: any) -> int` | Number of elements in an array equal to `val` | `count(columns.type, "EEG")` | The number of times "EEG" appears in the column "type" of the current TSV file |
265-
| `exists(arg: str \| array, rule: str) -> int` | Count of files in an array that exist in the dataset. String is array with length 1. See following section for the meanings of rules. | `exists(sidecar.IntendedFor, "subject")` | True if all files in `IntendedFor` exist, relative to the subject directory. |
266-
| `index(arg: array, val: any) -> int` | Index of first element in an array equal to `val`, `null` if not found | `index(["i", "j", "k"], axis)` | The number, from 0-2 corresponding to the string `axis` |
267-
| `intersects(a: array, b: array) -> bool` | `true` if arguments contain any shared elements | `intersects(dataset.modalities, ["pet", "mri"])` | True if either PET or MRI data is found in dataset |
268-
| `allequal(a: array, b: array) -> bool` | `true` if arrays have the same length and paired elements are equal | `intersects(dataset.modalities, ["pet", "mri"])` | True if either PET or MRI data is found in dataset |
269-
| `length(arg: array) -> int` | Number of elements in an array | `length(columns.onset) > 0` | True if there is at least one value in the onset column |
270-
| `match(arg: str, pattern: str) -> bool` | `true` if `arg` matches the regular expression `pattern` (anywhere in string) | `match(extension, ".gz$")` | True if the file extension ends with `.gz` |
271-
| `max(arg: array) -> number` | The largest non-`n/a` value in an array | `max(columns.onset)` | The time of the last onset in an events.tsv file |
272-
| `min(arg: array) -> number` | The smallest non-`n/a` value in an array | `min(sidecar.SliceTiming) == 0` | A check that the onset of the first slice is 0s |
273-
| `sorted(arg: array, method: str) -> array` | The sorted values of the input array; defaults to type-determined sort. If method is "lexical", or "numeric" use lexical or numeric sort. | `sorted(sidecar.VolumeTiming) == sidecar.VolumeTiming` | True if `sidecar.VolumeTiming` is sorted |
274-
| `substr(arg: str, start: int, end: int) -> str` | The portion of the input string spanning from start position to end position | `substr(path, 0, length(path) - 3)` | `path` with the last three characters dropped |
275-
| `type(arg: Any) -> str` | The name of the type, including `"array"`, `"object"`, `"null"` | `type(datatypes)` | Returns `"array"` |
262+
| Function | Definition | Example | Note |
263+
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ |
264+
| `count(arg: array, val: any) -> int` | Number of elements in an array equal to `val` | `count(columns.type, "EEG")` | The number of times "EEG" appears in the column "type" of the current TSV file |
265+
| `exists(arg: str \| array, rule: str) -> int` | Count of files in an array that exist in the dataset. String is array with length 1. See following section for the meanings of rules. | `exists(sidecar.IntendedFor, "subject")` | True if all files in `IntendedFor` exist, relative to the subject directory. |
266+
| `index(arg: array, val: any) -> int` | Index of first element in an array equal to `val`, `null` if not found | `index(["i", "j", "k"], axis)` | The number, from 0-2 corresponding to the string `axis` |
267+
| `intersects(a: array, b: array) -> array \| bool` | The intersection of arrays `a` and `b`, or `false` if there are no shared values. | `intersects(dataset.modalities, ["pet", "mri"])` | Non-empty array if either PET or MRI data is found in dataset, otherwise false |
268+
| `allequal(a: array, b: array) -> bool` | `true` if arrays have the same length and paired elements are equal | `intersects(dataset.modalities, ["pet", "mri"])` | True if either PET or MRI data is found in dataset |
269+
| `length(arg: array) -> int` | Number of elements in an array | `length(columns.onset) > 0` | True if there is at least one value in the onset column |
270+
| `match(arg: str, pattern: str) -> bool` | `true` if `arg` matches the regular expression `pattern` (anywhere in string) | `match(extension, ".gz$")` | True if the file extension ends with `.gz` |
271+
| `max(arg: array) -> number` | The largest non-`n/a` value in an array | `max(columns.onset)` | The time of the last onset in an events.tsv file |
272+
| `min(arg: array) -> number` | The smallest non-`n/a` value in an array | `min(sidecar.SliceTiming) == 0` | A check that the onset of the first slice is 0s |
273+
| `sorted(arg: array, method: str) -> array` | The sorted values of the input array; defaults to type-determined sort. If method is "lexical", or "numeric" use lexical or numeric sort. | `sorted(sidecar.VolumeTiming) == sidecar.VolumeTiming` | True if `sidecar.VolumeTiming` is sorted |
274+
| `substr(arg: str, start: int, end: int) -> str` | The portion of the input string spanning from start position to end position | `substr(path, 0, length(path) - 3)` | `path` with the last three characters dropped |
275+
| `type(arg: Any) -> str` | The name of the type, including `"array"`, `"object"`, `"null"` | `type(datatypes)` | Returns `"array"` |
276276

277277
#### The `exists()` function
278278

src/schema/meta/expression_tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
- expression: type(true)
9494
result: 'boolean'
9595
- expression: intersects([1], [1, 2])
96-
result: true
96+
result: [1]
9797
- expression: intersects([1], [])
9898
result: false
9999
- expression: length([1, 2, 3])

src/schema/objects/files.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ participants:
7575
followed by a list of optional columns describing participants.
7676
Each participant MUST be described by one and only one row.
7777
78+
The `participant_id` entries MUST be a superset of all subject directories
79+
and all `participant_id` entries found among phenotypic and assessment data
80+
in the `phenotype/` directory.
81+
7882
Commonly used *optional* columns in `participants.tsv` files are `age`, `sex`,
7983
`handedness`, `strain`, and `strain_rrid`.
8084

src/schema/objects/metadata.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,8 +3245,8 @@ ScreenResolution:
32453245
- type: array
32463246
items:
32473247
type: integer
3248-
minItems: 2
3249-
maxItems: 2
3248+
minItems: 2
3249+
maxItems: 2
32503250
- type: string
32513251
enum:
32523252
- n/a
@@ -3262,8 +3262,8 @@ ScreenSize:
32623262
items:
32633263
type: number
32643264
unit: m
3265-
minItems: 2
3266-
maxItems: 2
3265+
minItems: 2
3266+
maxItems: 2
32673267
- type: string
32683268
enum:
32693269
- n/a

src/schema/rules/checks/dataset.yaml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,35 @@ ParticipantIDMismatch:
1818
issue:
1919
code: PARTICIPANT_ID_MISMATCH
2020
message: |
21-
Participant labels found in this dataset did not match the values in participant_id column
22-
found in the participants.tsv file.
21+
Subject directories found in this dataset did not match the values in
22+
the participant_id column found in the participants.tsv file.
2323
level: error
2424
selectors:
2525
- path == '/participants.tsv'
2626
checks:
27-
- allequal(sorted(columns.participant_id), sorted(dataset.subjects.sub_dirs))
27+
- |
28+
allequal(
29+
sorted(intersects(columns.participant_id, dataset.subjects.sub_dirs)),
30+
sorted(dataset.subjects.sub_dirs)
31+
)
2832
2933
# 51
3034
PhenotypeSubjectsMissing:
3135
issue:
3236
code: PHENOTYPE_SUBJECTS_MISSING
3337
message: |
34-
A phenotype/ .tsv file lists subjects that were not found in the dataset.
38+
A phenotype/ .tsv file lists subjects that were not found in
39+
the participant_id column found in the participants.tsv file.
3540
level: error
3641
selectors:
37-
- path == '/dataset_description.json'
42+
- path == '/participants.tsv'
3843
- type(dataset.subjects.phenotype) != 'null'
3944
checks:
40-
- allequal(sorted(dataset.subjects.phenotype), sorted(dataset.subjects.sub_dirs))
45+
- |
46+
allequal(
47+
sorted(intersects(columns.participant_id, dataset.subjects.phenotype)),
48+
sorted(dataset.subjects.phenotype)
49+
)
4150
4251
# 214
4352
SamplesTSVMissing:

tools/schemacode/pyproject.toml

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ markers = [
103103
minversion = "6.0"
104104
xfail_strict = true
105105

106+
[tool.coverage]
107+
106108
[tool.coverage.paths]
107109
source = [
108110
"src/bidsschematools",
@@ -112,10 +114,32 @@ source = [
112114
[tool.coverage.run]
113115
parallel = true
114116

115-
[tool.bumpver]
117+
# Release process:
118+
# cd tools/schemacode
119+
# uvx bump-my-version bump pre_label --tag
120+
# [inspect result]
121+
# git push upstream <current-branch> --tags
122+
# uvx bump-my-version bump <patch|minor|major>
123+
# git push upstream <current-branch>
124+
[tool.bumpversion]
116125
current_version = "1.1.0-dev"
117-
version_pattern = "MAJOR.MINOR.PATCH[-TAG]"
118-
commit = false
126+
parse = """(?x)
127+
(?P<major>[0-9]+)
128+
\\.(?P<minor>[0-9]+)
129+
\\.(?P<patch>[0-9]+)
130+
(?:-(?P<pre_label>dev))?
131+
"""
132+
serialize = ["{major}.{minor}.{patch}-{pre_label}", "{major}.{minor}.{patch}"]
133+
commit = true
134+
message = "chore: Bump schema package to {new_version}"
135+
# Use --tag on releases
136+
tag = false
137+
tag_name = "schema-{new_version}"
138+
tag_message = "Schema release {new_version}"
139+
140+
[tool.bumpversion.parts.pre_label]
141+
values = ["dev", "final"]
142+
optional_value = "final"
119143

120-
[tool.bumpver.file_patterns]
121-
"src/bidsschematools/data/schema/SCHEMA_VERSION" = ['{version}']
144+
[[tool.bumpversion.files]]
145+
filename = "../../src/schema/SCHEMA_VERSION"

tools/schemacode/src/bidsschematools/__main__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@
33
import os
44
import re
55
import sys
6+
from importlib.resources import files
67
from itertools import chain
78

89
import click
910

10-
if sys.version_info < (3, 9):
11-
from importlib_resources import files
12-
else:
13-
from importlib.resources import files
14-
1511
from .rules import regexify_filename_rules
1612
from .schema import export_schema, load_schema
1713
from .validator import _bidsignore_check

tools/schemacode/src/bidsschematools/render/text.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _make_entity_definition(entity, entity_info):
6060
"""Describe an entity."""
6161
entity_shorthand = entity_info["name"]
6262
text = ""
63-
text += "## {}".format(entity_shorthand)
63+
text += f"## {entity_shorthand}"
6464
text += "\n\n"
6565
text += f"**Full name**: {entity_info['display_name']}"
6666
text += "\n\n"

0 commit comments

Comments
 (0)