diff --git a/.github/workflows/publish_schema.yml b/.github/workflows/publish_schema.yml new file mode 100644 index 0000000000..842c513eab --- /dev/null +++ b/.github/workflows/publish_schema.yml @@ -0,0 +1,91 @@ +name: "Publish schema" + +on: + push: + branches: + - "master" + tags: + - "schema-*" + +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..46c437826c 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[tests] 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 82122e77c7..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.1 + 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..d0991be72e 100644 --- a/src/appendices/qmri.md +++ b/src/appendices/qmri.md @@ -607,10 +607,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 113d77be73..fc1424d102 100644 --- a/src/modality-specific-files/magnetic-resonance-imaging-data.md +++ b/src/modality-specific-files/magnetic-resonance-imaging-data.md @@ -723,37 +723,46 @@ within the `[*_]dwi.bval` and `[*_]dwi.bvec` files) MAY change across DWI runs. **Gradient orientation file formats**. The `[*_]dwi.bval` and `[*_]dwi.bvec` files MUST follow the -[FSL format](https://fsl.fmrib.ox.ac.uk/fsl/docs/#/diffusion/index?id=diffusion-data-in-fsl): -The `[*_]dwi.bvec` file contains 3 rows with *N* space-delimited floating-point numbers -(corresponding to the *N* volumes in the corresponding NIfTI file.) -The first row contains the *x* elements, the second row contains the *y* elements and -the third row contains the *z* elements of a unit vector in the direction of the applied -diffusion gradient, where the *i*-th elements in each row correspond together to -the *i*-th volume, with `[0,0,0]` for *non-diffusion-weighted* (also called *b*=0 or *low-b*) -volumes. -Following the FSL format for the `[*_]dwi.bvec` specification, the coordinate system of -the *b* vectors MUST be defined with respect to the coordinate system defined by -the header of the corresponding `_dwi` NIfTI file and not the scanner's device -coordinate system (see [Coordinate systems](../appendices/coordinate-systems.md)). -The most relevant limitation imposed by this choice is that the gradient information cannot -be directly stored in this format if the scanner generates *b*-vectors in *scanner coordinates*. - -Example of `[*_]dwi.bvec` file, with *N*=6, with two *b*=0 volumes in the beginning: - -```Text -0 0 0.021828 -0.015425 -0.70918 -0.2465 -0 0 0.80242 0.22098 -0.00063106 0.1043 -0 0 -0.59636 0.97516 -0.70503 -0.96351 -``` - -The `[*_]dwi.bval` file contains the *b*-values (in s/mm2) corresponding to the -volumes in the relevant NIfTI file), with 0 designating *b*=0 volumes, space-delimited. - -Example of `[*_]dwi.bval` file, corresponding to the previous `[*_]dwi.bvec` example: - -```Text -0 0 2000 2000 1000 1000 -``` +[FSL format](https://fsl.fmrib.ox.ac.uk/fsl/docs/#/diffusion/index?id=diffusion-data-in-fsl). + +The `[*_]dwi.bvec` file contains 3 rows with *N* space-delimited floating-point numbers, +corresponding to the *N* volumes in the corresponding NIfTI file. +Across these three rows, +each column encodes three elements of a 3-vector for the corresponding image volume; +each vector MUST be either of unit norm, +or optionally the vector `[0.0,0.0,0.0]` +for *non-diffusion-weighted* (also called *b*=0 or *low-b*) volumes. +These values are to be interpreted as cosine values with respect to the image axis orientations +as defined by the corresponding NIfTI image header transformation; +*unless* the image axes defined in the corresponding NIfTI image header +form a right-handed coordinate system +(that is, the 3x3 matrix of direction cosines has a positive determinant), +in which case the sign of the first element of each 3-vector must be inverted +for this interpretation to be valid. +Note that this definition of orientations with respect to the NIfTI image axes +is *not* equivalent to the DICOM convention, +where orientations are instead defined with respect to the scanner device's coordinate system +(see [Coordinate systems](../appendices/coordinate-systems.md)). + +The `[*_]dwi.bval` file contains the *b*-values (in s/mm2) +corresponding to the volumes in the relevant NIfTI file, +with 0 designating *b*=0 volumes; space-delimited. + +Examples of `[*_]dwi.bvec` and `[*_]dwi.bval` files, +corresponding to a NIfTI image with 6 volumes +with the first two volumes having no diffusion sensitization: + +- `[*_]dwi.bvec`: + ```Text + 0 0 0.021828 -0.015425 -0.70918 -0.2465 + 0 0 0.80242 0.22098 -0.00063106 0.1043 + 0 0 -0.59636 0.97516 -0.70503 -0.96351 + ``` + +- `[_]dwi.bval`: + ```Text + 0 0 2000 2000 1000 1000 + ``` ### Multipart (split) DWI schemes diff --git a/src/modality-specific-files/magnetic-resonance-spectroscopy.md b/src/modality-specific-files/magnetic-resonance-spectroscopy.md new file mode 100644 index 0000000000..22ec6540e0 --- /dev/null +++ b/src/modality-specific-files/magnetic-resonance-spectroscopy.md @@ -0,0 +1,260 @@ +# Magnetic Resonance Spectroscopy + +Support for Magnetic Resonance Spectroscopy (MRS) was developed as a +[BIDS Extension Proposal](../extensions.md#bids-extension-proposals). +Please see [Citing BIDS](../introduction.md#citing-bids) +on how to appropriately credit this extension when referring to it in the +context of the academic literature. + +!!! example "Example datasets" + + Several [example MRS datasets](https://github.com/bids-standard/bids-examples/pull/425) have + been formatted using this specification and can be used for practical guidance when curating a new + dataset. + +## MRS data + + +{{ 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: i) a proprietary DICOM-structured file known as IMA (`*.ima`); +ii) a conventional DICOM MR Spectroscopy Storage format (`*.dcm`); iii) RDA (`*.rda`), +a proprietary file format with a text-formatted header followed by the binary data points; +and iv) 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-