Skip to content

Commit 9377b20

Browse files
authored
Merge pull request #1893 from effigies/fix/schema-types
fix(schema): Minor issues
2 parents b91d0e3 + c6bed8c commit 9377b20

File tree

8 files changed

+72
-33
lines changed

8 files changed

+72
-33
lines changed

src/metaschema.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"versions": {
6969
"type": "array",
7070
"items": {
71+
"type": "string",
7172
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
7273
}
7374
}
@@ -470,7 +471,7 @@
470471
"properties": {
471472
"datatypes": {
472473
"type": "array",
473-
"items": { "pattern": "^[a-z]+$" }
474+
"items": { "type": "string", "pattern": "^[a-z]+$" }
474475
}
475476
},
476477
"required": ["datatypes"],
@@ -661,7 +662,7 @@
661662
"level": { "enum": ["optional", "recommended", "required"] },
662663
"datatypes": {
663664
"type": "array",
664-
"items": { "pattern": "^[a-z]+$" }
665+
"items": { "type": "string", "pattern": "^[a-z]+$" }
665666
},
666667
"stem": { "type": "string" },
667668
"extensions": { "type": "array", "items": { "type": "string" } }
@@ -675,11 +676,11 @@
675676
"level": { "enum": ["optional", "recommended", "required"] },
676677
"datatypes": {
677678
"type": "array",
678-
"items": { "pattern": "^[a-z]+$" }
679+
"items": { "type": "string", "pattern": "^[a-z]+$" }
679680
},
680681
"suffixes": {
681682
"type": "array",
682-
"items": { "pattern": "^[a-zA-Z0-9]+$" }
683+
"items": { "type": "string", "pattern": "^[a-zA-Z0-9]+$" }
683684
},
684685
"extensions": { "type": "array", "items": { "type": "string" } },
685686
"entities": {

src/schema/meta/context.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ properties:
155155
events:
156156
description: 'Events file'
157157
type: object
158-
required: [path, onset]
158+
required: [path]
159159
additionalProperties: false
160160
properties:
161161
path:
@@ -169,7 +169,7 @@ properties:
169169
aslcontext:
170170
description: 'ASL context file'
171171
type: object
172-
required: [path, n_rows, volume_type]
172+
required: [path, n_rows]
173173
additionalProperties: false
174174
properties:
175175
path:
@@ -248,7 +248,7 @@ properties:
248248
channels:
249249
description: 'Channels file'
250250
type: object
251-
required: [path, type]
251+
required: [path]
252252
additionalProperties: false
253253
properties:
254254
path:
@@ -292,7 +292,7 @@ properties:
292292
gzip:
293293
description: 'Parsed contents of gzip header'
294294
type: object
295-
required: [timestamp, filename]
295+
required: [timestamp]
296296
additionalProperties: false
297297
properties:
298298
timestamp:

src/schema/rules/checks/func.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ RepetitionTimeMismatch:
4040
- type(sidecar.RepetitionTime) != "null"
4141
- type(nifti_header) != "null"
4242
checks:
43-
- sidecar.RepetitionTime == nifti_header.pixdim[4]
43+
# Implement millisecond rounding via AND
44+
- sidecar.RepetitionTime - nifti_header.pixdim[4] < 0.001
45+
- sidecar.RepetitionTime - nifti_header.pixdim[4] > -0.001
4446

4547
# 54
4648
BoldNot4d:

src/schema/rules/checks/privacy.yaml

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
11
---
2-
GzipHeaderFields:
2+
GzipHeaderMtime:
33
issue:
4-
code: GZIP_HEADER_DATA
4+
code: GZIP_HEADER_MTIME
55
message: |
6-
The gzip header contains a non-zero timestamp or a non-empty filename and/or comment field.
7-
These may leak sensitive information or indicate a non-reproducible conversion process.
6+
The gzip header contains a non-zero timestamp.
7+
This may leak sensitive information or indicate a non-reproducible conversion process.
88
level: warning
99
selectors:
1010
- match(extension, ".gz$")
1111
- gzip != null
1212
checks:
1313
- gzip.timestamp == 0
14+
15+
GzipHeaderFilename:
16+
issue:
17+
code: GZIP_HEADER_FILENAME
18+
message: |
19+
The gzip header contains a non-empty filename.
20+
This may leak sensitive information or indicate a non-reproducible conversion process.
21+
level: warning
22+
selectors:
23+
- match(extension, ".gz$")
24+
- gzip.filename
25+
checks:
1426
- gzip.filename == ""
27+
28+
GzipHeaderComment:
29+
issue:
30+
code: GZIP_HEADER_COMMENT
31+
message: |
32+
The gzip header contains a non-empty comment field.
33+
This may leak sensitive information or indicate a non-reproducible conversion process.
34+
level: warning
35+
selectors:
36+
- match(extension, ".gz$")
37+
- gzip.comment
38+
checks:
1539
- gzip.comment == ""
1640

1741
CheckAge89:

src/schema/rules/sidecars/beh.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# Metadata for either beh or events files
99
BEHTaskInformation:
1010
selectors:
11+
- datatype == "beh"
1112
- intersects([suffix], ["beh", "events"])
1213
fields:
1314
TaskName: recommended
@@ -18,6 +19,7 @@ BEHTaskInformation:
1819

1920
BEHInstitutionInformation:
2021
selectors:
22+
- datatype == "beh"
2123
- intersects([suffix], ["beh", "events"])
2224
fields:
2325
InstitutionName: recommended

src/schema/rules/sidecars/entity_rules.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
EntitiesTaskMetadata:
1111
selectors:
1212
- '"task" in entities'
13+
- suffix != 'events'
1314
fields:
1415
TaskName: recommended
1516

1617
EntitiesCeMetadata:
1718
selectors:
1819
- '"ce" in entities'
20+
- match(extension, "^\.nii(\.gz)?$")
1921
fields:
2022
ContrastBolusIngredient: optional
2123

@@ -30,24 +32,28 @@ EntitiesStainMetadata:
3032
EntitiesEchoMetadata:
3133
selectors:
3234
- '"echo" in entities'
35+
- match(extension, "^\.nii(\.gz)?$")
3336
fields:
3437
EchoTime: required
3538

3639
EntitiesFlipMetadata:
3740
selectors:
3841
- '"flip" in entities'
42+
- match(extension, "^\.nii(\.gz)?$")
3943
fields:
4044
FlipAngle: required
4145

4246
EntitiesInvMetadata:
4347
selectors:
4448
- '"inv" in entities'
49+
- match(extension, "^\.nii(\.gz)?$")
4550
fields:
4651
InversionTime: required
4752

4853
EntitiesMTMetadata:
4954
selectors:
5055
- '"mt" in entities'
56+
- match(extension, "^\.nii(\.gz)?$")
5157
fields:
5258
MTState: required
5359

src/schema/rules/sidecars/func.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ MRIFuncTimingParameters:
4747
selectors:
4848
- datatype == "func"
4949
- suffix == "bold"
50+
- match(extension, "^\.nii(\.gz)?$")
5051
fields:
5152
NumberOfVolumesDiscardedByScanner: recommended
5253
NumberOfVolumesDiscardedByUser: recommended
@@ -64,6 +65,7 @@ MRIFuncTaskInformation:
6465
selectors:
6566
- datatype == "func"
6667
- suffix == "bold"
68+
- match(extension, "^\.nii(\.gz)?$")
6769
fields:
6870
Instructions:
6971
level: recommended

src/schema/rules/sidecars/mri.yaml

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
MRIHardware:
1010
selectors:
1111
- modality == "mri"
12+
- match(extension, "^\.nii(\.gz)?$")
1213
fields:
1314
Manufacturer:
1415
level: recommended
@@ -57,6 +58,7 @@ MRIChunkPosition:
5758
MRISample:
5859
selectors:
5960
- modality == "mri"
61+
- match(extension, "^\.nii(\.gz)?$")
6062
fields:
6163
BodyPart:
6264
level: optional
@@ -69,12 +71,14 @@ MRIScannerHardwareASL:
6971
- datatype == "perf"
7072
- suffix == "asl"
7173
- intersects([suffix], ["asl", "m0scan"])
74+
- match(extension, "^\.nii(\.gz)?$")
7275
fields:
7376
MagneticFieldStrength: required
7477

7578
MRISequenceSpecifics:
7679
selectors:
7780
- modality == "mri"
81+
- match(extension, "^\.nii(\.gz)?$")
7882
fields:
7983
PulseSequenceType: recommended
8084
ScanningSequence: recommended
@@ -105,13 +109,15 @@ PETMRISequenceSpecifics:
105109
selectors:
106110
- modality == "mri"
107111
- intersects(dataset.modalities, ["pet"])
112+
- match(extension, "^\.nii(\.gz)?$")
108113
fields:
109114
NonlinearGradientCorrection: required
110115

111116
ASLMRISequenceSpecifics:
112117
selectors:
113118
- datatype == "perf"
114119
- suffix == "asl"
120+
- match(extension, "^\.nii(\.gz)?$")
115121
fields:
116122
MRAcquisitionType: required
117123

@@ -147,6 +153,7 @@ SpoilingGradient:
147153
MRISpatialEncoding:
148154
selectors:
149155
- modality == "mri"
156+
- match(extension, "^\.nii(\.gz)?$")
150157
fields:
151158
NumberShots: recommended
152159
ParallelReductionFactorInPlane: recommended
@@ -164,6 +171,7 @@ PhaseEncodingDirectionRec:
164171
selectors:
165172
- modality == "mri"
166173
- suffix != "epi"
174+
- match(extension, "^\.nii(\.gz)?$")
167175
fields:
168176
PhaseEncodingDirection:
169177
level: recommended
@@ -201,27 +209,24 @@ PhaseEncodingDirectionReq:
201209
MRITimingParameters:
202210
selectors:
203211
- modality == "mri"
212+
- match(extension, "^\.nii(\.gz)?$")
204213
fields:
205214
EchoTime:
206215
level: recommended
207216
level_addendum: |
208217
required if corresponding fieldmap data is present,
209218
or the data comes from a multi-echo sequence or Arterial Spin Labeling.
210-
issue:
211-
code: ECHO_TIME_NOT_DEFINED
212-
message: |
213-
You must define 'EchoTime' for this file. 'EchoTime' is the echo time (TE)
214-
for the acquisition, specified in seconds. Corresponds to DICOM Tag
215-
0018, 0081 Echo Time (please note that the DICOM term is in milliseconds
216-
not seconds). The data type number may apply to files from any MRI modality
217-
concerned with a single value for this field, or to the files in a file
218-
collection where the value of this field is iterated using the echo entity.
219-
The data type array provides a value for each volume in a 4D dataset and
220-
should only be used when the volume timing is critical for interpretation
221-
of the data, such as in ASL or variable echo time fMRI sequences.
222219
InversionTime: recommended
223220
DwellTime: recommended
224221

222+
EchoTimeRequiredASL:
223+
selectors:
224+
- modality == "mri"
225+
- datatype == "perf"
226+
- match(extension, "^\.nii(\.gz)?$")
227+
fields:
228+
EchoTime: required
229+
225230
SliceTimingMRI:
226231
selectors:
227232
- modality == "mri"
@@ -240,7 +245,6 @@ SliceTimingASL:
240245
- intersects([suffix], ["asl", "m0scan"])
241246
- sidecar.MRAcquisitionType == "2D"
242247
fields:
243-
EchoTime: required
244248
SliceTiming:
245249
level: required
246250
issue:
@@ -260,16 +264,10 @@ SliceTimingASL:
260264
final entry in the `SliceTiming` list is the time of acquisition of slice 0.
261265
Without this parameter slice time correction will not be possible.
262266
263-
# This is technically for sparse sequences only, but I don't know how to encode that.
264-
# SliceTimingSparse:
265-
# selectors:
266-
# - modality == "mri"
267-
# fields:
268-
# SliceTiming: required
269-
270267
MRIRFandContrast:
271268
selectors:
272269
- modality == "mri"
270+
- match(extension, "^\.nii(\.gz)?$")
273271
fields:
274272
NegativeContrast: optional
275273

@@ -307,13 +305,15 @@ MRIFlipAngleLookLockerTrue:
307305
MRISliceAcceleration:
308306
selectors:
309307
- modality == "mri"
308+
- match(extension, "^\.nii(\.gz)?$")
310309
fields:
311310
MultibandAccelerationFactor: recommended
312311

313312
MRIAnatomicalLandmarks:
314313
selectors:
315314
- datatype == "anat"
316315
- intersects(dataset.datatypes, ["meg"])
316+
- match(extension, "^\.nii(\.gz)?$")
317317
fields:
318318
AnatomicalLandmarkCoordinates__mri: recommended
319319

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

334335
MRIInstitutionInformation:
335336
selectors:
336337
- modality == "mri"
338+
- match(extension, "^\.nii(\.gz)?$")
337339
fields:
338340
InstitutionName:
339341
level: recommended

0 commit comments

Comments
 (0)