diff --git a/.github/workflows/publish_schema.yml b/.github/workflows/publish_schema.yml new file mode 100644 index 0000000000..c2528e02c4 --- /dev/null +++ b/.github/workflows/publish_schema.yml @@ -0,0 +1,89 @@ +name: "Publish schema" + +on: + push: + branches: + - "master" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + GIT_AUTHOR_NAME: BIDS CI + GIT_AUTHOR_EMAIL: bids.maintenance@gmail.com + GIT_COMMITTER_NAME: BIDS CI + GIT_COMMITTER_EMAIL: bids.maintenance@gmail.com + +permissions: + contents: write + id-token: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + filter: "blob:none" + - uses: actions/setup-python@v5 + with: + python-version: 3 + - name: Install bidsschematools + run: | + pip install --upgrade tools/schemacode + git clean -fxd tools/schemacode + - name: Checkout jsr-dist + run: | + git checkout -t origin/jsr-dist + - name: Regenerate schema + run: bst export > schema.json + - name: Regenerate context types + run: | + jq .meta.context schema.json \ + | npx quicktype --src-lang schema --lang ts -t Context --just-types \ + > context.ts + - name: Regenerate metaschema types + run: | + # Name the file schema so the type will be named Schema + bst export-metaschema > /tmp/schema.json + npx --package=json-schema-to-typescript json2ts --unknownAny /tmp/schema.json > metaschema.ts + - name: Determine next version + run: | + BASE=$( jq -r .schema_version schema.json ) + if [[ "$BASE" =~ ^[0-9]*.[0-9]*.[0-9]*$ ]]; then + # Release, so unconditionally update version + VERSION=$BASE + jq ".version = \"$VERSION\"" jsr.json > tmp.json && mv tmp.json jsr.json + else + DENOVER=$( jq -r .version jsr.json ) + # Get the reference of the latest commit to touch the schema directory + HASH=$( git log -n 1 --pretty=%h $REF -- src/schema ) + if [[ $DENOVER =~ ^"$BASE".[0-9] ]]; then + PREFIX=${DENOVER%+*} + let SERIAL=1+${PREFIX#$BASE.} + else + SERIAL=1 + fi + VERSION="$BASE.$SERIAL+$HASH" + fi + echo VERSION=$VERSION | tee -a $GITHUB_ENV + env: + REF: ${{ github.ref }} + - name: Check for changes, set version and commit + run: | + if ! git diff -s --exit-code; then + jq ".version = \"$VERSION\"" jsr.json > tmp.json && mv tmp.json jsr.json + git add jsr.json schema.json context.ts metaschema.ts + git commit -m "Update schema JSR distribution" + git push + fi + - name: Publish to JSR + if: success() + run: | + npx jsr publish diff --git a/.github/workflows/schemacode_ci.yml b/.github/workflows/schemacode_ci.yml index 14746534db..db6e77700a 100644 --- a/.github/workflows/schemacode_ci.yml +++ b/.github/workflows/schemacode_ci.yml @@ -33,7 +33,7 @@ jobs: - name: "Install build dependencies" run: pip install --upgrade build twine - name: "Install test dependencies on tag" - run: pip install --upgrade tools/schemacode[test] + run: pip install --upgrade tools/schemacode[all] if: ${{ startsWith(github.ref, 'refs/tags/schema-') }} - name: "Build archive on tag" run: pytest tools/schemacode/bidsschematools -k make_archive diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c59c7ce96a..277632e355 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: - id: check-added-large-files - id: check-case-conflict - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.29.0 + rev: 0.29.2 hooks: - id: check-dependabot - id: check-github-workflows @@ -25,7 +25,7 @@ repos: - id: check-readthedocs files: readthedocs.yml - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.8.0 hooks: - id: black files: ^tools/(?!schemacode) @@ -45,7 +45,7 @@ repos: files: tools/schemacode args: ["--settings-file", "tools/schemacode/pyproject.toml"] - repo: https://github.com/pyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 args: [--config=tools/schemacode/setup.cfg] @@ -67,7 +67,7 @@ repos: - id: codespell args: ["--config=.codespellrc", "--dictionary=-", "--dictionary=.codespell_dict"] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.0 + rev: v1.11.2 hooks: - id: mypy # Sync with project.optional-dependencies.typing diff --git a/README.md b/README.md index 6474f470a1..40c29b6b81 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ BIDS currently supports the following data modalities with more to come in the f - microscopy - NIRS - motion +- MRS # Formatting your data with BIDS diff --git a/mkdocs.yml b/mkdocs.yml index 114e05c135..cfbdba2a49 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,6 +19,7 @@ nav: - Microscopy: modality-specific-files/microscopy.md - Near-Infrared Spectroscopy: modality-specific-files/near-infrared-spectroscopy.md - Motion: modality-specific-files/motion.md + - Magnetic Resonance Spectroscopy: modality-specific-files/magnetic-resonance-spectroscopy.md - Derivatives: - BIDS Derivatives: derivatives/introduction.md - Common data types and metadata: derivatives/common-data-types.md diff --git a/src/appendices/arterial-spin-labeling.md b/src/appendices/arterial-spin-labeling.md index 4d1253eaab..842bde8d80 100644 --- a/src/appendices/arterial-spin-labeling.md +++ b/src/appendices/arterial-spin-labeling.md @@ -79,7 +79,7 @@ For (P)CASL, specifying the `LabelingDuration` and the `PostLabelingDelay` is re The `LabelingDuration` is defined as the total duration of the labeling pulse train in seconds. `PostLabelingDelay` is the time in seconds after the end of the labeling until the middle of the excitation pulse applied to the imaging slab (for 3D acquisition) or first slice (for 2D acquisition). -Additionally, the `BackgroundSuppressionPulseTime`'s is required in case `BackgroundSuppression` was applied. +Additionally, the `BackgroundSuppressionPulseTime` is RECOMMENDED if `BackgroundSuppression` was applied. This an array of numbers containing the timing in seconds of the background suppression pulses with respect to the start of the labeling. In the case of `PCASL`, the recommended `PCASLType` field defines the type of the gradient pulses diff --git a/src/appendices/contributors.md b/src/appendices/contributors.md index f48586f04d..a359956c8e 100644 --- a/src/appendices/contributors.md +++ b/src/appendices/contributors.md @@ -55,6 +55,7 @@ If you contributed to the BIDS ecosystem and your name is not listed, please add | Alexander Jones | 💻🐛 | | Alexander L. Cohen | 🐛💻📖💬 | | Alexander von Lautz | 📖 | +| Alexandre D'Astous | 📖 | | Alexandre Gramfort | 📖💡 | | Alexandre Hutton | 📖 | | Alexandre Routier | 📖 | diff --git a/src/appendices/cross-modality-correspondence.md b/src/appendices/cross-modality-correspondence.md index c71a1c73f5..6dba22b325 100644 --- a/src/appendices/cross-modality-correspondence.md +++ b/src/appendices/cross-modality-correspondence.md @@ -12,3 +12,10 @@ The reason for this is that the MRI needs to be corrected for nonlinear gradient in order to fit the accompanying PET scans for co-registration (Knudsen et al. 2020, [doi:10.1177/0271678X20905433](https://doi.org/10.1177/0271678X20905433); Norgaard et al. 2019, [doi:10.1016/j.neuroimage.2019.05.055](https://doi.org/10.1016/j.neuroimage.2019.05.055)). + +## MRS-MRI correspondence + +It is typical to acquire high-resolution 3D anatomical MR images alongside MRS data for +voxel/slab placement, co-registration, and partial-volume tissue correction of metabolite concentrations. +To avoid incorrectly matching an MRS dataset with a corresponding anatomical MR image, +it is RECOMMENDED that the field `AnatomicalImage` be included in the MRS sidecar JSON files. diff --git a/src/appendices/qmri.md b/src/appendices/qmri.md index 8aad465f24..d5367cfcdd 100644 --- a/src/appendices/qmri.md +++ b/src/appendices/qmri.md @@ -133,10 +133,13 @@ A guide for using macros can be found at Please visit the [file collections appendix](./file-collections.md#magnetic-resonance-imaging) to see the list of currently supported qMRI applications. -### Quantitative maps are derivatives +### Outputs are quantitative maps -Regardless of how they are obtained (pre- or post-generated), qMRI maps are stored in the `derivatives` directory. -For example a `T1map` can be generated from an `MP2RAGE` file collection using either options. +qMRI maps are stored differently depending on the process that generated them. +Pre-generated qMRI maps MAY be stored as part of a raw BIDS dataset, +whereas they MUST be stored in a derivative BIDS dataset if they were post-generated. + +See the example below of a `T1map` generated from an `MP2RAGE` file collection using either option. If the map is post-generated: @@ -151,15 +154,25 @@ A guide for using macros can be found at "qMRI-software-name": { "sub-01": { "anat": { - "sub-01_T1map.nii.gz": "", + "sub-01_T1map.nii.gz": " # --> T1 map in a derivative dataset", "sub-01_T1map.json": "", - "sub-01_UNIT1.nii.gz": "", + "sub-01_UNIT1.nii.gz": " # --> UNI T1 in a derivative dataset", "sub-01_UNIT1.json": "", - }, }, }, }, }, + "sub-01": { + "anat": { + "sub-01_inv-1_part-mag_MP2RAGE.nii.gz":"", + "sub-01_inv-1_part-phase_MP2RAGE.nii.gz":"", + "sub-01_inv-1_MP2RAGE.json":"", + "sub-01_inv-2_part-mag_MP2RAGE.nii.gz":"", + "sub-01_inv-2_part-phase_MP2RAGE.nii.gz":"", + "sub-01_inv-2_MP2RAGE.json":"", + }, + }, + }, } ) }} @@ -172,25 +185,30 @@ A guide for using macros can be found at {{ MACROS___make_filetree_example( { "ds-example": { - "derivatives": { - "Siemens": { - "sub-01": { - "anat": { - "sub-01_T1map.nii.gz": "", - "sub-01_T1map.json": "", - "sub-01_UNIT1.nii.gz": "", - "sub-01_UNIT1.json": "", - }, - }, - }, + "sub-01": { + "anat": { + "sub-01_inv-1_part-mag_MP2RAGE.nii.gz":"", + "sub-01_inv-1_part-phase_MP2RAGE.nii.gz":"", + "sub-01_inv-1_MP2RAGE.json":"", + "sub-01_inv-2_part-mag_MP2RAGE.nii.gz":"", + "sub-01_inv-2_part-phase_MP2RAGE.nii.gz":"", + "sub-01_inv-2_MP2RAGE.json":"", + "sub-01_T1map.nii.gz": " # --> T1 map in a raw dataset", + "sub-01_T1map.json": "", + "sub-01_UNIT1.nii.gz": " # --> UNI T1 in a raw dataset", + "sub-01_UNIT1.json": "", }, }, + } } ) }} -Note: Even though the process from which pre-generated qMRI maps are obtained (vendor pipelines) is not known, -vendors generally allow exporting of the corresponding input data. -It is RECOMMENDED to share them along with the vendor outputs, whenever possible for a qMRI method supported by BIDS. +!!! note "Sharing of vendor outputs" + + Even though the process from which pre-generated qMRI maps are obtained (vendor pipelines) is not known, + vendors generally allow exporting of the corresponding input data. + It is RECOMMENDED to share them along with the vendor outputs, + whenever possible for a qMRI method supported by BIDS. ### Example datasets @@ -326,7 +344,7 @@ A guide for using macros can be found at `dataset_description.json`: -```text +```json { "Name": "qMRLab Outputs", "BIDSVersion": "1.5.0", @@ -526,12 +544,13 @@ as an input to offline calculation of a `T1map` using a dictionary lookup approa provided by the stock sequence. Instead, the `magnitude` and `phase` images are exported. Please see the relevant discussion at [qMRLab issue #255](https://github.com/qMRLab/qMRLab/issues/255). -Therefore, the `UNIT1` image provided by the scanner is RECOMMENDED to be stored under the `anat` -raw dataset directory along with the `MP2RAGE` file collection and to be used as the primary input -for quantifying a `T1map`. +Therefore, the `UNIT1` image provided by the scanner +SHOULD be stored under the `anat` in a raw BIDS dataset +along with the `MP2RAGE` file collection +and to be used as the primary input for quantifying a `T1map`. -If an additional `UNIT1` image is calculated offline, then the output is to be stored in the -`derivatives` directory with necessary provenance information. +If an additional `UNIT1` image is calculated offline, +then the output MUST be stored in a derivative BIDS dataset with necessary provenance information. ##### `NumberShots` metadata field @@ -607,10 +626,15 @@ The nominal FA value of the SE pulse is twice this value. Note that the following metadata fields MUST be defined in the accompanying JSON files: -| **Field name** | **Definition** | -| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `TotalReadoutTime` | The effective readout length defined as `EffectiveEchoSpacing * PEReconMatrix`, with `EffectiveEchoSpacing = TrueEchoSpacing / PEacceleration` | -| `MixingTime` | Time interval between the SE and STE pulses | + +{{ MACROS___make_sidecar_table("fmap.TB1EPI") }} To properly identify constituents of this particular method, values of the `echo` entity MUST index the images as follows: diff --git a/src/appendices/units.md b/src/appendices/units.md index 4e4355483f..078db3b64e 100644 --- a/src/appendices/units.md +++ b/src/appendices/units.md @@ -83,30 +83,51 @@ Examples for CMIXF-12 (including the five unicode symbols mentioned above): ### Multiples -| **Prefix name** | **Prefix symbol** | **Factor** | -| ------------------------------------------- | ----------------- | --------------- | -| [deca](https://www.wikiwand.com/en/Deca-) | da | 101 | -| [hecto](https://www.wikiwand.com/en/Hecto-) | h | 102 | -| [kilo](https://www.wikiwand.com/en/Kilo-) | k | 103 | -| [mega](https://www.wikiwand.com/en/Mega-) | M | 106 | -| [giga](https://www.wikiwand.com/en/Giga-) | G | 109 | -| [tera](https://www.wikiwand.com/en/Tera-) | T | 1012 | -| [peta](https://www.wikiwand.com/en/Peta-) | P | 1015 | -| [exa](https://www.wikiwand.com/en/Exa-) | E | 1018 | -| [zetta](https://www.wikiwand.com/en/Zetta-) | Z | 1021 | -| [yotta](https://www.wikiwand.com/en/Yotta-) | Y | 1024 | +| **Prefix name** | **Prefix symbol** | **Factor** | +| --------------- | ----------------- | --------------- | +| [deca][] | da | 101 | +| [hecto][] | h | 102 | +| [kilo][] | k | 103 | +| [mega][] | M | 106 | +| [giga][] | G | 109 | +| [tera][] | T | 1012 | +| [peta][] | P | 1015 | +| [exa][] | E | 1018 | +| [zetta][] | Z | 1021 | +| [yotta][] | Y | 1024 | ### Submultiples -| **Prefix name** | **Prefix symbol** | **Factor** | -| ------------------------------------------- | ----------------- | ---------------- | -| [deci](https://www.wikiwand.com/en/Deci-) | d | 10-1 | -| [centi](https://www.wikiwand.com/en/Centi-) | c | 10-2 | -| [milli](https://www.wikiwand.com/en/Milli-) | m | 10-3 | -| [micro](https://www.wikiwand.com/en/Micro-) | u | 10-6 | -| [nano](https://www.wikiwand.com/en/Nano-) | n | 10-9 | -| [pico](https://www.wikiwand.com/en/Pico-) | p | 10-12 | -| [femto](https://www.wikiwand.com/en/Femto-) | f | 10-15 | -| [atto](https://www.wikiwand.com/en/Atto-) | a | 10-18 | -| [zepto](https://www.wikiwand.com/en/Zepto-) | z | 10-21 | -| [yocto](https://www.wikiwand.com/en/Yocto-) | y | 10-24 | +| **Prefix name** | **Prefix symbol** | **Factor** | +| --------------- | ----------------- | ---------------- | +| [deci][] | d | 10-1 | +| [centi][] | c | 10-2 | +| [milli][] | m | 10-3 | +| [micro][] | u | 10-6 | +| [nano][] | n | 10-9 | +| [pico][] | p | 10-12 | +| [femto][] | f | 10-15 | +| [atto][] | a | 10-18 | +| [zepto][] | z | 10-21 | +| [yocto][] | y | 10-24 | + +[deca]: https://en.wikipedia.org/wiki/Deca- +[hecto]: https://en.wikipedia.org/wiki/Hecto- +[kilo]: https://en.wikipedia.org/wiki/Kilo- +[mega]: https://en.wikipedia.org/wiki/Mega- +[giga]: https://en.wikipedia.org/wiki/Giga- +[tera]: https://en.wikipedia.org/wiki/Tera- +[peta]: https://en.wikipedia.org/wiki/Peta- +[exa]: https://en.wikipedia.org/wiki/Exa- +[zetta]: https://en.wikipedia.org/wiki/Zetta- +[yotta]: https://en.wikipedia.org/wiki/Yotta- +[deci]: https://en.wikipedia.org/wiki/Deci- +[centi]: https://en.wikipedia.org/wiki/Centi- +[milli]: https://en.wikipedia.org/wiki/Milli- +[micro]: https://en.wikipedia.org/wiki/Micro- +[nano]: https://en.wikipedia.org/wiki/Nano- +[pico]: https://en.wikipedia.org/wiki/Pico- +[femto]: https://en.wikipedia.org/wiki/Femto- +[atto]: https://en.wikipedia.org/wiki/Atto- +[zepto]: https://en.wikipedia.org/wiki/Zepto- +[yocto]: https://en.wikipedia.org/wiki/Yocto- diff --git a/src/introduction.md b/src/introduction.md index 4315720e3a..a07b654b2c 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -184,6 +184,10 @@ For example: PsyArXiv. [doi:10.31234/osf.io/w6z79](https://doi.org/10.31234/osf.io/w6z79) +#### MRS + +- (publication forthcoming) + ### Research Resource Identifier (RRID) BIDS has also a diff --git a/src/metaschema.json b/src/metaschema.json index c0462edcaf..c00481b5e8 100644 --- a/src/metaschema.json +++ b/src/metaschema.json @@ -68,6 +68,7 @@ "versions": { "type": "array", "items": { + "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" } } @@ -315,7 +316,7 @@ "$ref": "#/definitions/ruleTypes/expressionList" } }, - "required": ["checks", "selectors"], + "required": ["checks", "selectors", "issue"], "additionalProperties": false } } @@ -386,19 +387,25 @@ "required": ["common", "deriv", "raw"], "additionalProperties": false }, + "json": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/json" + } + }, "sidecars": { "type": "object", "patternProperties": { "^derivatives$": { "type": "object", "properties": { - "common_derivatives": { "$ref": "#/definitions/sidecar" } + "common_derivatives": { "$ref": "#/definitions/json" } }, "required": ["common_derivatives"], "additionalProperties": false }, "^(?!derivatives$)[a-z_]+$": { - "$ref": "#/definitions/sidecar" + "$ref": "#/definitions/json" }, "additionalProperties": false }, @@ -464,7 +471,7 @@ "properties": { "datatypes": { "type": "array", - "items": { "pattern": "^[a-z]+$" } + "items": { "type": "string", "pattern": "^[a-z]+$" } } }, "required": ["datatypes"], @@ -476,6 +483,7 @@ "required": [ "entities", "files", + "json", "sidecars", "tabular_data", "common_principles", @@ -586,7 +594,7 @@ } } }, - "sidecar": { + "json": { "type": "object", "patternProperties": { "^[a-zA-Z0-9_]+$": { @@ -654,7 +662,7 @@ "level": { "enum": ["optional", "recommended", "required"] }, "datatypes": { "type": "array", - "items": { "pattern": "^[a-z]+$" } + "items": { "type": "string", "pattern": "^[a-z]+$" } }, "stem": { "type": "string" }, "extensions": { "type": "array", "items": { "type": "string" } } @@ -668,11 +676,11 @@ "level": { "enum": ["optional", "recommended", "required"] }, "datatypes": { "type": "array", - "items": { "pattern": "^[a-z]+$" } + "items": { "type": "string", "pattern": "^[a-z]+$" } }, "suffixes": { "type": "array", - "items": { "pattern": "^[a-zA-Z0-9]+$" } + "items": { "type": "string", "pattern": "^[a-zA-Z0-9]+$" } }, "extensions": { "type": "array", "items": { "type": "string" } }, "entities": { diff --git a/src/modality-specific-files/electroencephalography.md b/src/modality-specific-files/electroencephalography.md index 8a584bb7a0..782012f3ea 100644 --- a/src/modality-specific-files/electroencephalography.md +++ b/src/modality-specific-files/electroencephalography.md @@ -390,7 +390,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("eeg.EEGCoordsystemGeneral") }} +{{ MACROS___make_json_table("json.eeg.EEGCoordsystemGeneral") }} Fields relating to the EEG electrode positions: @@ -402,7 +402,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("eeg.EEGCoordsystemPositions") }} +{{ MACROS___make_json_table("json.eeg.EEGCoordsystemPositions") }} Fields relating to the position of fiducials measured during an EEG session/run: @@ -414,7 +414,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("eeg.EEGCoordsystemFiducials") }} +{{ MACROS___make_json_table("json.eeg.EEGCoordsystemFiducials") }} Fields relating to the position of anatomical landmark measured during an EEG session/run: @@ -426,7 +426,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table(["eeg.EEGCoordsystemLandmark", "eeg.EEGCoordsystemLandmarkDescriptionRec"]) }} +{{ MACROS___make_json_table(["json.eeg.EEGCoordsystemLandmark", "json.eeg.EEGCoordsystemLandmarkDescriptionRec"]) }} If the position of anatomical landmarks is measured using the same system or device used to measure electrode positions, and if thereby the anatomical diff --git a/src/modality-specific-files/intracranial-electroencephalography.md b/src/modality-specific-files/intracranial-electroencephalography.md index 096b96f97d..dc15d9f92d 100644 --- a/src/modality-specific-files/intracranial-electroencephalography.md +++ b/src/modality-specific-files/intracranial-electroencephalography.md @@ -389,7 +389,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("ieeg.iEEGCoordsystemGeneral") }} +{{ MACROS___make_json_table("json.ieeg.iEEGCoordsystemGeneral") }} Fields relating to the iEEG electrode positions: @@ -401,7 +401,7 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("ieeg.iEEGCoordsystemPositions") }} +{{ MACROS___make_json_table("json.ieeg.iEEGCoordsystemPositions") }} ### Recommended 3D coordinate systems diff --git a/src/modality-specific-files/magnetic-resonance-imaging-data.md b/src/modality-specific-files/magnetic-resonance-imaging-data.md index d5e8e6abc9..7b1ae30908 100644 --- a/src/modality-specific-files/magnetic-resonance-imaging-data.md +++ b/src/modality-specific-files/magnetic-resonance-imaging-data.md @@ -160,9 +160,13 @@ The definitions of the fields specified in these tables may be found in A guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_sidecar_table("mri.MRIEchoPlanarImagingAndB0Mapping") }} +{{ MACROS___make_sidecar_table([ + "mri.MRIB0FieldIdentifier", + "mri.MRIEchoPlanarImagingAndB0FieldSource", + ]) +}} -#### Tissue description +### Tissue description {{ MACROS___make_sidecar_table("mri.MRISample") }} +### Deidentification information + +Describes the mechanism or method used to modify or remove metadata +and/or pixel data to protect the patient or participant's identity. + + +{{ MACROS___make_sidecar_table("mri.DeidentificationMethod") }} + +Each object in the `DeidentificationMethodCodeSequence` array includes the following RECOMMENDED keys: + + +{{ MACROS___make_subobject_table("metadata.DeidentificationMethodCodeSequence.items") }} + ## Anatomy imaging data Anatomy MRI sequences measure static, structural features of the brain. @@ -656,18 +685,13 @@ The definitions of these fields can be found in and a guide for using macros can be found at https://github.com/bids-standard/bids-specification/blob/master/macros_doc.md --> -{{ MACROS___make_suffix_table(["dwi", "sbref"]) }} - -Additionally, the following suffixes are used for scanner-generated images: - - -{{ MACROS___make_suffix_table(["ADC", "TRACE"]) }} +{{ MACROS___make_suffix_table( + [ + "dwi", + "sbref", + ] + ) +}} +{{ MACROS___make_filename_template("raw", datatypes=["mrs"]) }} + +MRS is a spectroscopic technique based on the phenomenon of nuclear magnetic resonance +that allows for the noninvasive detection and quantification of molecules in biochemical samples, such as brain tissue. +It can be conducted in humans using conventional MRI systems. + +Due to the diversity in manufacturers' MRS data file formats, source data MUST be converted into the +[NIfTI-MRS format](https://wtclarke.github.io/mrs_nifti_standard/) (`*.nii[.gz]`) ([doi:10.1002/mrm.29418](https://doi.org/10.1002/mrm.29418)). +This format is based on the NIfTI framework and is designed to accommodate the nuances of raw MRS data. +All necessary information to parse this `*.nii[.gz]` file (for example, spectrometer frequency, echo time, +repetition time, and so on) are stored in a JSON header extension. +Conversion of proprietary MRS file formats to NIfTI-MRS and extraction of some (but not all) BIDS-compliant metadata can be performed +using [spec2nii](https://github.com/wtclarke/spec2nii). +Note that the "rawness" of data stored in the NIfTI-MRS file will depend on the format of the source data. +It is RECOMMENDED that users export their source data from the scanner in an appropriately raw format prior to conversion. + +For MRSI data, "raw" signifies spatially reconstructed data (that is, data in image space rather than (*k*,*t*)-space), +given the complexity and diversity of sampling approaches. +Note that NIfTI-MRS is not designed to store data that has not been spatially reconstructed. + +Regarding source data, each manufacturer has its own file format (sometimes multiple formats) for exporting MRS data from +the MRI scanner console for offline processing. +GE exports a P-file (`*.7`) that stores unprocessed, un-coil-combined data with metadata embedded +in a proprietary data header. +Philips has multiple export formats, the most common being the SDAT/SPAR format. +The `*.sdat` file contains either each coil-combined transient stored separately +or all transients summed into a signal average. +The `*.spar` file is a plaintext file describing acquisition parameters. +It is also possible to export raw data as `*.data`/`*.list` or DICOM files. +Siemens scanners allow data export in four formats: + +1. a proprietary DICOM-structured file known as IMA (`*.ima`); +1. a conventional DICOM MR Spectroscopy Storage format (`*.dcm`); +1. RDA (`*.rda`), a proprietary file format with a text-formatted header followed by the binary data points; +1. TWIX (`*.dat`), a proprietary file format designed for storing unreconstructed, unprocessed MRS data from each individual coil element. + +The IMA, DICOM MRS, and RDA formats are typically used to export reconstructed and processed data; +however, the sequence designer may choose to also allow the export of un-averaged transients +or data from individual coil elements. +Bruker data are are exported as two binary files: one file stores each transient separately, +while the other stores the sum of the transients. +A separate plaintext file stores the sequence name, voxel position, voxel orientation, and other metadata. +All of these files are considered source data and, if present, MUST be stored in the +[`sourcedata`](../common-principles.md#source-vs-raw-vs-derived-data) directory. + +### Single-voxel spectroscopy and MRS imaging + +| **Name** | **`suffix`** | **Description** | +| ---------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Single-voxel spectroscopy | svs | MRS acquisitions where the detected MR signal is spatially localized to a single volume. | +| Magnetic resonance spectroscopic imaging | mrsi | MRS acquisitions where additional imaging gradients are used to detect the MR signal from 1, 2, or 3 spatial dimensions. | +| Unlocalized spectroscopy | unloc | MRS acquisitions run without localization. This includes signals detected using coil sensitivity only. | +| Concentration or calibration reference | mrsref | An MRS acquisition collected to serve as a concentration reference for absolute quantification or as a calibration reference for preprocessing (for example, eddy-current correction). | + +A major distinction between MRS acquisitions is whether the acquisition technique probes spectral +information from a single volume (single-voxel spectroscopy, SVS) or encodes this information along +1, 2, or 3 spatial dimensions resulting in multiple sub-volumes (MRS imaging, MRSI). +To avoid confusion, the suffixes `svs` and `mrsi` MUST be used to distinguish the two techniques. +For cases where localization is not used, the suffix `unloc` MUST be used. + +Furthermore, it is common to acquire an additional MRS dataset that may serve as a reference for +scaling metabolite signal levels (for example, to obtain concentrations) and/or for preprocessing steps (such as +eddy-current correction, RF coil combination, phasing, and frequency calibration). +This could be either an external reference (for example, a phantom or a synthetic signal) or, more typically, +an internal tissue water reference. +For such datasets, the suffix `mrsref` MUST be used. +Should multiple references exist for a given dataset, the user MAY use the `acq-