Skip to content

Commit

Permalink
[SCHEMA] Apply schema rules to entity values (#792)
Browse files Browse the repository at this point in the history
* Use `type` key from other parts of schema on entities.

By using the same tools, we can also use things like `enum` to limit values.

* Support the new approach in the tools.

The current solution is a bit of a hack but it's easy to adjust. Basically, when `format` is missing from the schema, default to "label".

* Update tools/schemacode/schema.py

Co-authored-by: Chris Markiewicz <effigies@gmail.com>

Co-authored-by: Chris Markiewicz <effigies@gmail.com>
  • Loading branch information
tsalo and effigies authored Jul 20, 2021
1 parent ed1357c commit 96131df
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
36 changes: 33 additions & 3 deletions src/schema/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ subject:
entity: sub
description: |
A person or animal participating in the study.
type: string
format: label
session:
name: Session
Expand All @@ -24,16 +25,18 @@ session:
data acquisitions are planned and performed on all -or most- subjects,
often in the case of some intervention between sessions
(for example, training).
type: string
format: label
task:
name: Task
entity: task
format: label
description: |
Each task has a unique label that MUST only consist of letters and/or
numbers (other characters, including spaces and underscores, are not
allowed).
Those labels MUST be consistent across subjects and sessions.
type: string
format: label
acquisition:
name: Acquisition
entity: acq
Expand All @@ -54,6 +57,7 @@ acquisition:
At what level of detail to make the distinction (for example,
just between RARE and FLASH, or between RARE, FLASH, and FLASHsubsampled)
remains at the discretion of the researcher.
type: string
format: label
ceagent:
name: Contrast Enhancing Agent
Expand All @@ -64,6 +68,7 @@ ceagent:
The label is the name of the contrast agent.
The key `ContrastBolusIngredient` MAY also be added in the JSON file,
with the same label.
type: string
format: label
tracer:
name: Tracer
Expand All @@ -73,6 +78,7 @@ tracer:
sequences using different tracers.
The key `TracerName` MUST also be included in the associated JSON file,
although the label may be different.
type: string
format: label
reconstruction:
name: Reconstruction
Expand All @@ -81,6 +87,7 @@ reconstruction:
The `rec-<label>` key/value can be used to distinguish
different reconstruction algorithms (for example ones using motion
correction).
type: string
format: label
direction:
name: Phase-Encoding Direction
Expand All @@ -89,6 +96,7 @@ direction:
The `dir-<label>` key/value can be set to an arbitrary alphanumeric label
(for example, `dir-LR` or `dir-AP`) to distinguish different phase-encoding
directions.
type: string
format: label
run:
name: Run
Expand All @@ -104,6 +112,7 @@ run:
or different acquisition parameters indicated by
[`acq-<label>`](../99-appendices/09-entities.md#acq),
then `run` is not needed to distinguish the scans and MAY be omitted.
type: string
format: index
modality:
name: Corresponding Modality
Expand All @@ -112,6 +121,7 @@ modality:
The `mod-<label>` key/value pair corresponds to modality label for defacing
masks, for example, T1w, inplaneT1, referenced by a defacemask image.
For example, `sub-01_mod-T1w_defacemask.nii.gz`.
type: string
format: label
echo:
name: Echo
Expand All @@ -124,6 +134,7 @@ echo:
denotes the number/index (in the form of a nonnegative integer), not the
`EchoTime` value which needs to be stored in the field `EchoTime` of the separate
JSON file.
type: string
format: index
flip:
name: Flip Angle
Expand All @@ -135,6 +146,7 @@ flip:
This entity represents the `FlipAngle` metadata field. Please note that the `<index>`
denotes the number/index (in the form of a nonnegative integer), not the `FlipAngle`
value which needs to be stored in the field `FlipAngle` of the separate JSON file.
type: string
format: index
inversion:
name: Inversion Time
Expand All @@ -146,6 +158,7 @@ inversion:
This entity represents the `InversionTime` metadata field. Please note that the `<index>`
denotes the number/index (in the form of a nonnegative integer), not the `InversionTime`
value which needs to be stored in the field `InversionTime` of the separate JSON file.
type: string
format: index
mtransfer:
name: Magnetization Transfer
Expand All @@ -157,7 +170,11 @@ mtransfer:
This entity represents the `MTState` metadata field. Allowed label values for this
entity are `on` and `off`, for images acquired in presence and absence of an MT pulse,
respectively.
format: label
type: string
# on/off map to True/False in YAML so they must be placed in quotes.
enum:
- "on"
- "off"
part:
name: Part
entity: part
Expand All @@ -176,7 +193,12 @@ part:
When there is only a magnitude image of a given type, the `part` key MAY be
omitted.
format: label
type: string
enum:
- mag
- phase
- real
- imag
recording:
name: Recording
entity: recording
Expand All @@ -185,6 +207,7 @@ recording:
sampling frequencies).
In such case use different labels.
For example: `_recording-contrast`, `_recording-saturation`.
type: string
format: label
processing:
name: Processed (on device)
Expand All @@ -197,6 +220,7 @@ processing:
which some installations impose to be run on raw data because of active
shielding software corrections before the MEG data can actually be
exploited.
type: string
format: label
space:
name: Space
Expand All @@ -214,6 +238,7 @@ space:
For EEG/MEG/iEEG data, this entity can be applied to raw data, but
for other data types, it is restricted to derivative data.
type: string
format: label
split:
name: Split
Expand All @@ -235,6 +260,7 @@ split:
remember to list all files separately in `scans.tsv` and that the entries for the
`acq_time` column in `scans.tsv` MUST all be identical, as described in
[Scans file](../03-modality-agnostic-files.md#scans-file).
type: string
format: index
resolution:
name: Resolution
Expand All @@ -245,6 +271,7 @@ resolution:
interpretation.
This entity is only applicable to derivative data.
type: string
format: label
density:
name: Density
Expand All @@ -255,6 +282,7 @@ density:
interpretation.
This entity is only applicable to derivative data.
type: string
format: label
label:
name: Label
Expand All @@ -265,6 +293,7 @@ label:
that describe a single tissue type.
This entity is only applicable to derivative data.
type: string
format: label
description:
name: Description
Expand All @@ -274,4 +303,5 @@ description:
distinguishing entity, the `_desc-<label>` keyword-value SHOULD be used.
This entity is only applicable to derivative data.
type: string
format: label
11 changes: 8 additions & 3 deletions tools/schemacode/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,14 @@ def make_entity_definitions(schema):
text += "Full name: {}".format(entity_info["name"])
text += "\n\n"
text += "Format: `{}-<{}>`".format(
entity_info["entity"], entity_info["format"]
entity_info["entity"],
entity_info.get("format", "label"),
)
text += "\n\n"
if "enum" in entity_info.keys():
text += "Allowed values: `{}`".format("`, `".join(entity_info["enum"]))
text += "\n\n"

text += "Definition: {}".format(entity_info["description"])
return text

Expand Down Expand Up @@ -219,7 +224,7 @@ def make_filename_template(schema, **kwargs):
for ent in entities:
ent_format = "{}-<{}>".format(
schema["entities"][ent]["entity"],
schema["entities"][ent]["format"],
schema["entities"][ent].get("format", "label")
)
if ent in group["entities"]:
if group["entities"][ent] == "required":
Expand Down Expand Up @@ -309,7 +314,7 @@ def make_entity_table(schema, tablefmt="github", **kwargs):
entity_shorthand = schema["entities"][entity]["entity"]
header.append(spec["name"])
formats.append(
f'[`{entity_shorthand}-<{spec["format"]}>`]'
f'[`{entity_shorthand}-<{spec.get("format", "label")}>`]'
f"({ENTITIES_FILE}#{entity_shorthand})"
)
entity_to_col[entity] = i + 1
Expand Down

0 comments on commit 96131df

Please sign in to comment.