Skip to content

Commit

Permalink
Merge branch 'master' into dwi_scanner_derivatives
Browse files Browse the repository at this point in the history
  • Loading branch information
effigies authored Sep 3, 2024
2 parents 97d6a94 + 27d2988 commit 4254491
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/schemacode_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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[tests]
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
Expand Down
71 changes: 45 additions & 26 deletions src/appendices/qmri.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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":"",
},
},
},
}
) }}

Expand All @@ -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

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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

Expand Down
27 changes: 26 additions & 1 deletion src/modality-specific-files/magnetic-resonance-imaging-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ A guide for using macros can be found at
])
}}

#### Tissue description
### Tissue description

<!-- This block generates a metadata table.
These tables are defined in
Expand All @@ -178,6 +178,31 @@ A guide for using macros can be found at
-->
{{ 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.

<!-- This block generates a metadata table.
These tables are defined in
src/schema/rules/sidecars
The definitions of the fields specified in these tables may be found in
src/schema/objects/metadata.yaml
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.DeidentificationMethod") }}

Each object in the `DeidentificationMethodCodeSequence` array includes the following RECOMMENDED keys:

<!-- This block generates a table describing subfields within a metadata field.
The definitions of these fields can be found in
src/schema/objects/metadata.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_subobject_table("metadata.DeidentificationMethodCodeSequence.items") }}

## Anatomy imaging data

Anatomy MRI sequences measure static, structural features of the brain.
Expand Down
29 changes: 21 additions & 8 deletions src/modality-specific-files/magnetic-resonance-spectroscopy.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ 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.
Several [example MRS datasets](https://github.com/bids-standard/bids-examples?tab=readme-ov-file#mrs) have
been formatted using this specification and can be used for practical guidance when curating a new dataset.

## MRS data

Expand Down Expand Up @@ -50,11 +49,13 @@ 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.
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.
Expand Down Expand Up @@ -153,6 +154,18 @@ A guide for using macros can be found at
-->
{{ MACROS___make_sidecar_table("mrs.MRSScannerHardware") }}

#### Institution information

<!-- This block generates a metadata table.
These tables are defined in
src/schema/rules/sidecars
The definitions of the fields specified in these tables may be found in
src/schema/objects/metadata.yaml
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("mrs.MRSInstitutionInformation") }}

#### Sequence specifics

<!-- This block generates a metadata table.
Expand Down
25 changes: 25 additions & 0 deletions src/modality-specific-files/positron-emission-tomography.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,31 @@ A guide for using macros can be found at
-->
{{ MACROS___make_sidecar_table("pet.PETSample") }}

#### 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.

<!-- This block generates a metadata table.
These tables are defined in
src/schema/rules/sidecars
The definitions of the fields specified in these tables may be found in
src/schema/objects/metadata.yaml
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.DeidentificationMethod") }}

Each object in the `DeidentificationMethodCodeSequence` array includes the following RECOMMENDED keys:

<!-- This block generates a table describing subfields within a metadata field.
The definitions of these fields can be found in
src/schema/objects/metadata.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_subobject_table("metadata.DeidentificationMethodCodeSequence.items") }}

#### Task

If the OPTIONAL [`task-<label>`](../appendices/entities.md#task) is used,
Expand Down
2 changes: 1 addition & 1 deletion src/schema/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.11.1-dev
0.11.2-dev
49 changes: 49 additions & 0 deletions src/schema/objects/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,55 @@ DecayCorrectionFactor:
type: array
items:
type: number
DeidentificationMethod:
name: DeidentificationMethod
display_name: Deidentification Method
description: |
A description of the mechanism or method used to remove the Patient's identity.
Corresponds to DICOM Tag 0012, 0063 `De-identification Method`.
type: array
items:
type: string
DeidentificationMethodCodeSequence:
name: DeidentificationMethodCodeSequence
display_name: Deidentification Method Code Sequence
description: |
A sequence of code objects describing the mechanism or method use to remove the Patient's identity.
Corresponds to DICOM Tag 0012, 0064 `De-identification Method Code Sequence`.
type: array
items:
type: object
recommended_fields:
- CodeValue
- CodeMeaning
- CodingSchemeDesignator
- CodingSchemeVersion
properties:
CodeValue:
name: CodeValue
type: string
description: |
An identifier that is unambiguous within the Coding Scheme
denoted by Coding Scheme Designator and Coding Scheme Version.
Corresponds to DICOM Tag 0008, 0100 `Code Value`.
CodeMeaning:
name: CodeMeaning
type: string
description: |
Text that has meaning to a human and conveys the meaning of the term
Corresponds to DICOM Tag 0008, 0104 `Code Meaning`.
CodingSchemeDesignator:
name: CodingSchemeDesignator
type: string
description: |
The identifier of the coding scheme in which the coded entry is defined.
Corresponds to DICOM Tag 0008, 0102 `Coding Scheme Designator`.
CodingSchemeVersion:
name: CodingSchemeVersion
type: string
description: |
An identifier of the version of the coding scheme if necessary to resolve ambiguity.
Corresponds to DICOM Tag 0008, 0103 `Coding Scheme Version`.
DelayAfterTrigger:
name: DelayAfterTrigger
display_name: Delay After Trigger
Expand Down
5 changes: 0 additions & 5 deletions src/schema/objects/suffixes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ TwoPE:
display_name: 2-photon excitation microscopy
description: |
2-photon excitation microscopy imaging data
ADC:
value: ADC
display_name: Apparent diffusion coefficient (ADC)
description:
Apparent diffusion coefficient (ADC) map
BF:
value: BF
display_name: Bright-field microscopy
Expand Down
10 changes: 5 additions & 5 deletions src/schema/rules/checks/asl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,21 @@ ASLBackgroundSuppressionNumberPulses:
- length(sidecar.BackgroundSuppressionPulseTime) == sidecar.BackgroundSuppressionNumberPulses

# 181
ASLTotalAcquiredVolumesASLContextLength:
ASLTotalAcquiredPairsASLContextLength:
issue:
code: TOTAL_ACQUIRED_VOLUMES_NOT_CONSISTENT
message: |
The number of values for 'TotalAcquiredVolumes' for this file does not match number of
The number of values for 'TotalAcquiredPairs' for this file does not match number of
volumes in the associated 'aslcontext.tsv'.
'TotalAcquiredVolumes' is the original number of 3D volumes acquired for each volume defined in the
'TotalAcquiredPairs' is the original number of 3D volumes acquired for each volume defined in the
associated 'aslcontext.tsv'.
level: warning
selectors:
- suffix == "asl"
- type(associations.aslcontext) != "null"
- '"TotalAcquiredVolumes" in sidecar'
- '"TotalAcquiredPairs" in sidecar'
checks:
- aslcontext.n_rows == sidecar.TotalAcquiredVolumes
- aslcontext.n_rows == sidecar.TotalAcquiredPairs

# 184
PostLabelingDelayGreater:
Expand Down
31 changes: 24 additions & 7 deletions src/schema/rules/checks/micr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,34 @@ PixelSizeInconsistent:
selectors:
- ome != null
- sidecar.PixelSize != null
- sidecar.PixelSizeUnit != null
- sidecar.PixelSizeUnits != null
checks:
# Note that OME-XML uses µm for microns and BIDS uses um
# Accept an error up to .001 of the BIDS unit, to account for floating point error
- |
ome.PhysicalSizeX * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeXUnit))
== sidecar.PixelSize[0] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
ome.PhysicalSizeX * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeXUnit))
- sidecar.PixelSize[0] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- |
ome.PhysicalSizeY * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeYUnit))
== sidecar.PixelSize[1] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
sidecar.PixelSize[0] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- ome.PhysicalSizeX * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeXUnit))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- |
ome.PhysicalSizeZ * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeZUnit))
== sidecar.PixelSize[2] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
ome.PhysicalSizeY * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeYUnit))
- sidecar.PixelSize[1] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- |
sidecar.PixelSize[1] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- ome.PhysicalSizeY * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeYUnit))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- |
ome.PhysicalSizeZ * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeZUnit))
- sidecar.PixelSize[2] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- |
sidecar.PixelSize[2] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
- ome.PhysicalSizeZ * 10 ** (-3 * index(["mm", "µm", "nm"], ome.PhysicalSizeZUnit))
< 0.001 * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnits))
# 227
InconsistentTiffExtension:
Expand Down
Loading

0 comments on commit 4254491

Please sign in to comment.