Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(schema): Minor issues #1893

Merged
merged 7 commits into from
Aug 20, 2024
Merged
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
9 changes: 5 additions & 4 deletions src/metaschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"versions": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
}
}
Expand Down Expand Up @@ -470,7 +471,7 @@
"properties": {
"datatypes": {
"type": "array",
"items": { "pattern": "^[a-z]+$" }
"items": { "type": "string", "pattern": "^[a-z]+$" }
}
},
"required": ["datatypes"],
Expand Down Expand Up @@ -661,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" } }
Expand All @@ -675,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": {
Expand Down
8 changes: 4 additions & 4 deletions src/schema/meta/context.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ properties:
events:
description: 'Events file'
type: object
required: [path, onset]
required: [path]
additionalProperties: false
properties:
path:
Expand All @@ -169,7 +169,7 @@ properties:
aslcontext:
description: 'ASL context file'
type: object
required: [path, n_rows, volume_type]
required: [path, n_rows]
additionalProperties: false
properties:
path:
Expand Down Expand Up @@ -248,7 +248,7 @@ properties:
channels:
description: 'Channels file'
type: object
required: [path, type]
required: [path]
additionalProperties: false
properties:
path:
Expand Down Expand Up @@ -292,7 +292,7 @@ properties:
gzip:
description: 'Parsed contents of gzip header'
type: object
required: [timestamp, filename]
required: [timestamp]
additionalProperties: false
properties:
timestamp:
Expand Down
4 changes: 3 additions & 1 deletion src/schema/rules/checks/func.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ RepetitionTimeMismatch:
- type(sidecar.RepetitionTime) != "null"
- type(nifti_header) != "null"
checks:
- sidecar.RepetitionTime == nifti_header.pixdim[4]
# Implement millisecond rounding via AND
- sidecar.RepetitionTime - nifti_header.pixdim[4] < 0.001
- sidecar.RepetitionTime - nifti_header.pixdim[4] > -0.001

# 54
BoldNot4d:
Expand Down
32 changes: 28 additions & 4 deletions src/schema/rules/checks/privacy.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
---
GzipHeaderFields:
GzipHeaderMtime:
issue:
code: GZIP_HEADER_DATA
code: GZIP_HEADER_MTIME
message: |
The gzip header contains a non-zero timestamp or a non-empty filename and/or comment field.
These may leak sensitive information or indicate a non-reproducible conversion process.
The gzip header contains a non-zero timestamp.
This may leak sensitive information or indicate a non-reproducible conversion process.
level: warning
selectors:
- match(extension, ".gz$")
- gzip != null
checks:
- gzip.timestamp == 0

GzipHeaderFilename:
issue:
code: GZIP_HEADER_FILENAME
message: |
The gzip header contains a non-empty filename.
This may leak sensitive information or indicate a non-reproducible conversion process.
level: warning
selectors:
- match(extension, ".gz$")
- gzip.filename
checks:
- gzip.filename == ""

GzipHeaderComment:
issue:
code: GZIP_HEADER_COMMENT
message: |
The gzip header contains a non-empty comment field.
This may leak sensitive information or indicate a non-reproducible conversion process.
level: warning
selectors:
- match(extension, ".gz$")
- gzip.comment
checks:
- gzip.comment == ""

CheckAge89:
Expand Down
2 changes: 2 additions & 0 deletions src/schema/rules/sidecars/beh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Metadata for either beh or events files
BEHTaskInformation:
selectors:
- datatype == "beh"
- intersects([suffix], ["beh", "events"])
fields:
TaskName: recommended
Expand All @@ -18,6 +19,7 @@ BEHTaskInformation:

BEHInstitutionInformation:
selectors:
- datatype == "beh"
- intersects([suffix], ["beh", "events"])
fields:
InstitutionName: recommended
Expand Down
6 changes: 6 additions & 0 deletions src/schema/rules/sidecars/entity_rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
EntitiesTaskMetadata:
selectors:
- '"task" in entities'
- suffix != 'events'
fields:
TaskName: recommended

EntitiesCeMetadata:
selectors:
- '"ce" in entities'
- match(extension, "^\.nii(\.gz)?$")
fields:
ContrastBolusIngredient: optional

Expand All @@ -30,24 +32,28 @@ EntitiesStainMetadata:
EntitiesEchoMetadata:
selectors:
- '"echo" in entities'
- match(extension, "^\.nii(\.gz)?$")
fields:
EchoTime: required

EntitiesFlipMetadata:
selectors:
- '"flip" in entities'
- match(extension, "^\.nii(\.gz)?$")
fields:
FlipAngle: required

EntitiesInvMetadata:
selectors:
- '"inv" in entities'
- match(extension, "^\.nii(\.gz)?$")
fields:
InversionTime: required

EntitiesMTMetadata:
selectors:
- '"mt" in entities'
- match(extension, "^\.nii(\.gz)?$")
fields:
MTState: required

Expand Down
2 changes: 2 additions & 0 deletions src/schema/rules/sidecars/func.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ MRIFuncTimingParameters:
selectors:
- datatype == "func"
- suffix == "bold"
- match(extension, "^\.nii(\.gz)?$")
fields:
NumberOfVolumesDiscardedByScanner: recommended
NumberOfVolumesDiscardedByUser: recommended
Expand All @@ -64,6 +65,7 @@ MRIFuncTaskInformation:
selectors:
- datatype == "func"
- suffix == "bold"
- match(extension, "^\.nii(\.gz)?$")
fields:
Instructions:
level: recommended
Expand Down
42 changes: 22 additions & 20 deletions src/schema/rules/sidecars/mri.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
MRIHardware:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
Manufacturer:
level: recommended
Expand Down Expand Up @@ -57,6 +58,7 @@ MRIChunkPosition:
MRISample:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
BodyPart:
level: optional
Expand All @@ -69,12 +71,14 @@ MRIScannerHardwareASL:
- datatype == "perf"
- suffix == "asl"
- intersects([suffix], ["asl", "m0scan"])
- match(extension, "^\.nii(\.gz)?$")
fields:
MagneticFieldStrength: required

MRISequenceSpecifics:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
PulseSequenceType: recommended
ScanningSequence: recommended
Expand Down Expand Up @@ -105,13 +109,15 @@ PETMRISequenceSpecifics:
selectors:
- modality == "mri"
- intersects(dataset.modalities, ["pet"])
- match(extension, "^\.nii(\.gz)?$")
fields:
NonlinearGradientCorrection: required

ASLMRISequenceSpecifics:
selectors:
- datatype == "perf"
- suffix == "asl"
- match(extension, "^\.nii(\.gz)?$")
fields:
MRAcquisitionType: required

Expand Down Expand Up @@ -147,6 +153,7 @@ SpoilingGradient:
MRISpatialEncoding:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
NumberShots: recommended
ParallelReductionFactorInPlane: recommended
Expand All @@ -164,6 +171,7 @@ PhaseEncodingDirectionRec:
selectors:
- modality == "mri"
- suffix != "epi"
- match(extension, "^\.nii(\.gz)?$")
fields:
PhaseEncodingDirection:
level: recommended
Expand Down Expand Up @@ -201,27 +209,24 @@ PhaseEncodingDirectionReq:
MRITimingParameters:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
EchoTime:
level: recommended
level_addendum: |
required if corresponding fieldmap data is present,
or the data comes from a multi-echo sequence or Arterial Spin Labeling.
issue:
code: ECHO_TIME_NOT_DEFINED
message: |
You must define 'EchoTime' for this file. 'EchoTime' is the echo time (TE)
for the acquisition, specified in seconds. Corresponds to DICOM Tag
0018, 0081 Echo Time (please note that the DICOM term is in milliseconds
not seconds). The data type number may apply to files from any MRI modality
concerned with a single value for this field, or to the files in a file
collection where the value of this field is iterated using the echo entity.
The data type array provides a value for each volume in a 4D dataset and
should only be used when the volume timing is critical for interpretation
of the data, such as in ASL or variable echo time fMRI sequences.
InversionTime: recommended
DwellTime: recommended

EchoTimeRequiredASL:
selectors:
- modality == "mri"
- datatype == "perf"
- match(extension, "^\.nii(\.gz)?$")
fields:
EchoTime: required

SliceTimingMRI:
selectors:
- modality == "mri"
Expand All @@ -240,7 +245,6 @@ SliceTimingASL:
- intersects([suffix], ["asl", "m0scan"])
- sidecar.MRAcquisitionType == "2D"
fields:
EchoTime: required
SliceTiming:
level: required
issue:
Expand All @@ -260,16 +264,10 @@ SliceTimingASL:
final entry in the `SliceTiming` list is the time of acquisition of slice 0.
Without this parameter slice time correction will not be possible.

# This is technically for sparse sequences only, but I don't know how to encode that.
# SliceTimingSparse:
# selectors:
# - modality == "mri"
# fields:
# SliceTiming: required

MRIRFandContrast:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
NegativeContrast: optional

Expand Down Expand Up @@ -307,13 +305,15 @@ MRIFlipAngleLookLockerTrue:
MRISliceAcceleration:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
MultibandAccelerationFactor: recommended

MRIAnatomicalLandmarks:
selectors:
- datatype == "anat"
- intersects(dataset.datatypes, ["meg"])
- match(extension, "^\.nii(\.gz)?$")
fields:
AnatomicalLandmarkCoordinates__mri: recommended

Expand All @@ -328,12 +328,14 @@ MRIEchoPlanarImagingAndB0FieldSource:
selectors:
- intersects(datatype, ['dwi', 'func', 'perf'])
- intersects(dataset.datatypes, ['fmap'])
- match(extension, "^\.nii(\.gz)?$")
fields:
B0FieldSource: recommended

MRIInstitutionInformation:
selectors:
- modality == "mri"
- match(extension, "^\.nii(\.gz)?$")
fields:
InstitutionName:
level: recommended
Expand Down