From fcb0b9120bf35166fea4524206f941ba9c196b96 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 2 Nov 2021 13:45:20 -0400 Subject: [PATCH 1/5] Use two underscores for multi-sense metadata entries. --- .../01-magnetic-resonance-imaging-data.md | 4 ++-- src/schema/objects/metadata.yaml | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/04-modality-specific-files/01-magnetic-resonance-imaging-data.md b/src/04-modality-specific-files/01-magnetic-resonance-imaging-data.md index 87b2fb42f7..982c617b2a 100644 --- a/src/04-modality-specific-files/01-magnetic-resonance-imaging-data.md +++ b/src/04-modality-specific-files/01-magnetic-resonance-imaging-data.md @@ -148,7 +148,7 @@ Useful for multimodal co-registration with MEG, (S)EEG, TMS, and so on. {{ MACROS___make_metadata_table( { - "AnatomicalLandmarkCoordinates_mri": "RECOMMENDED", + "AnatomicalLandmarkCoordinates__mri": "RECOMMENDED", } ) }} @@ -1050,7 +1050,7 @@ Required fields: {{ MACROS___make_metadata_table( { - "EchoTime_fmap": "REQUIRED", + "EchoTime__fmap": "REQUIRED", } ) }} diff --git a/src/schema/objects/metadata.yaml b/src/schema/objects/metadata.yaml index 873f69a357..f8118c6351 100644 --- a/src/schema/objects/metadata.yaml +++ b/src/schema/objects/metadata.yaml @@ -104,7 +104,8 @@ AnatomicalLandmarkCoordinates: type: number minItems: 3 maxItems: 3 -AnatomicalLandmarkCoordinates_mri: +# Redefinition of AnatomicalLandmarkCoordinates for MRI data +AnatomicalLandmarkCoordinates__mri: name: AnatomicalLandmarkCoordinates description: | Key:value pairs of any number of additional anatomical landmarks and their @@ -682,7 +683,8 @@ EchoTime2: type: number unit: s exclusiveMinimum: 0 -EchoTime_fmap: +# Redefinition of EchoTime for fieldmap data +EchoTime__fmap: name: EchoTime description: | The time (in seconds) when the echo corresponding to this map was acquired. From e7e5d6f3f50d9ffeeb87a0768df95230407207b3 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 2 Nov 2021 13:45:33 -0400 Subject: [PATCH 2/5] Fill in missing object descriptions. --- src/schema/objects/associated_data.yaml | 3 ++- src/schema/objects/datatypes.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/schema/objects/associated_data.yaml b/src/schema/objects/associated_data.yaml index 50fa80247c..901e17bdac 100644 --- a/src/schema/objects/associated_data.yaml +++ b/src/schema/objects/associated_data.yaml @@ -10,7 +10,8 @@ code: source data. derivatives: name: Derivative data - description: + description: | + Derivative data sourcedata: name: Source data description: | diff --git a/src/schema/objects/datatypes.yaml b/src/schema/objects/datatypes.yaml index f17e8feb9f..1366f66da9 100644 --- a/src/schema/objects/datatypes.yaml +++ b/src/schema/objects/datatypes.yaml @@ -37,4 +37,5 @@ perf: Blood perfusion imaging data, including arterial spin labeling (ASL) pet: name: Positron Emission Tomography - description: + description: | + Positron emission tomography data From 48c795ca2e31ae0c1e53e34e25e10a10c27e55d2 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 2 Nov 2021 13:45:52 -0400 Subject: [PATCH 3/5] Draft glossary page. --- mkdocs.yml | 1 + src/99-appendices/14-glossary.md | 9 ++++ tools/mkdocs_macros_bids/macros.py | 17 ++++++- tools/mkdocs_macros_bids/main.py | 1 + tools/schemacode/schema.py | 76 ++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/99-appendices/14-glossary.md diff --git a/mkdocs.yml b/mkdocs.yml index 3411357c61..bf5f87917d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -57,6 +57,7 @@ nav: - Quantitative MRI: 99-appendices/11-qmri.md - Arterial Spin Labeling: 99-appendices/12-arterial-spin-labeling.md - Cross modality correspondence: 99-appendices/13-cross-modality-correspondence.md + - Glossary: 99-appendices/14-glossary.md - Changelog: CHANGES.md - The BIDS Starter Kit: - GitHub repository: https://github.com/bids-standard/bids-starter-kit diff --git a/src/99-appendices/14-glossary.md b/src/99-appendices/14-glossary.md new file mode 100644 index 0000000000..8f9affb6f1 --- /dev/null +++ b/src/99-appendices/14-glossary.md @@ -0,0 +1,9 @@ +# Appendix XIV: Glossary of schema objects + +This section compiles the object definitions in the schema. + + +{{ MACROS___make_glossary() }} diff --git a/tools/mkdocs_macros_bids/macros.py b/tools/mkdocs_macros_bids/macros.py index 9a3cf15cc2..a621fcef55 100644 --- a/tools/mkdocs_macros_bids/macros.py +++ b/tools/mkdocs_macros_bids/macros.py @@ -5,8 +5,8 @@ code_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.append(code_path) -from schemacode import schema, utils from examplecode import example +from schemacode import schema, utils def make_filename_template(**kwargs): @@ -70,6 +70,21 @@ def make_entity_definitions(): return text +def make_glossary(): + """Generate glossary. + + Returns + ------- + text : str + A multiline string containing descriptions and some formatting + information about the entities in the schema. + """ + schemapath = utils.get_schema_path() + schema_obj = schema.load_schema(schemapath) + text = schema.make_glossary(schema_obj) + return text + + def make_suffix_table(suffixes): """Generate a markdown table of suffix information. diff --git a/tools/mkdocs_macros_bids/main.py b/tools/mkdocs_macros_bids/main.py index 05ec392201..6429d8bc18 100644 --- a/tools/mkdocs_macros_bids/main.py +++ b/tools/mkdocs_macros_bids/main.py @@ -35,6 +35,7 @@ def define_env(env): macros.make_entity_definitions, "MACROS___make_entity_definitions", ) + env.macro(macros.make_glossary, "MACROS___make_glossary") env.macro(macros.make_suffix_table, "MACROS___make_suffix_table") env.macro(macros.make_metadata_table, "MACROS___make_metadata_table") env.macro(macros.make_filetree_example, "MACROS___make_filetree_example") diff --git a/tools/schemacode/schema.py b/tools/schemacode/schema.py index daa9011a83..d6f1b880ed 100644 --- a/tools/schemacode/schema.py +++ b/tools/schemacode/schema.py @@ -13,6 +13,9 @@ from . import utils +# import utils + + lgr = utils.get_logger() # Basic settings for output, for now just basic utils.set_logger_level( @@ -208,6 +211,79 @@ def make_entity_definitions(schema): return text +def make_glossary(schema): + """Generate glossary. + + Parameters + ---------- + schema : dict + The schema object, which is a dictionary with nested dictionaries and + lists stored within it. + + Returns + ------- + text : str + A string containing descriptions and some formatting + information about the entities in the schema. + """ + all_objects = {} + + for group, group_objects in schema["objects"].items(): + group_obj_keys = list(group_objects.keys()) + # Remove private objects + group_obj_keys = [k for k in group_obj_keys if not k.startswith("_")] + + multi_sense_objects = [] + # Identify multi-sense objects (multiple entries, some with __ in them) + for key in group_obj_keys: + if "__" in key: + temp_key = key.split("__")[0] + multi_sense_objects.append(temp_key) + + multi_sense_objects = sorted(list(set(multi_sense_objects))) + sense_keys = {mso: [] for mso in multi_sense_objects} + + for key in group_obj_keys: + for sense_key in sense_keys.keys(): + if (key == sense_key) or (key.startswith(sense_key + "__")): + sense_keys[sense_key].append(key) + + sense_names = {} + for sense_key, key_list in sense_keys.items(): + for i_key, key in enumerate(key_list): + new_key_name = f"{sense_key} _sense {i_key + 1}_" + sense_names[key] = new_key_name + + for key in group_obj_keys: + new_name = sense_names.get(key, key) + new_name = f"{new_name} ({group})" + all_objects[new_name] = {} + all_objects[new_name]["key"] = key + all_objects[new_name]["definition"] = group_objects[key] + + text = "" + for obj_key in sorted(all_objects.keys()): + obj = all_objects[obj_key] + obj_def = obj["definition"] + obj_name = obj_def["name"] + obj_desc = obj_def["description"] + # A backslash before a newline means continue a string + obj_desc = obj_desc.replace("\\\n", "") + # Two newlines should be respected + obj_desc = obj_desc.replace("\n\n", "
") + # Otherwise a newline corresponds to a space + obj_desc = obj_desc.replace("\n", " ") + + text += f"\n## {obj_key}\n\n" + text += f"name: {obj_name}\n\n" + text += f"description:\n>{obj_desc}\n\n" + + temp_obj_def = {k: v for k, v in obj_def.items() if k not in ("description", "name")} + text += f"schema information:\n```yaml\n{temp_obj_def}\n```" + + return text + + def _add_entity(filename_template, entity_pattern, requirement_level): """Add entity pattern to filename template based on requirement level.""" if requirement_level == "required": From 81108ad80374cb8168839f415b53bfb7836c1409 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 2 Nov 2021 13:49:17 -0400 Subject: [PATCH 4/5] Use better key. --- tools/schemacode/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/schemacode/schema.py b/tools/schemacode/schema.py index d6f1b880ed..c3b7abdc49 100644 --- a/tools/schemacode/schema.py +++ b/tools/schemacode/schema.py @@ -258,7 +258,7 @@ def make_glossary(schema): new_name = sense_names.get(key, key) new_name = f"{new_name} ({group})" all_objects[new_name] = {} - all_objects[new_name]["key"] = key + all_objects[new_name]["key"] = f"objects.{group}.{key}" all_objects[new_name]["definition"] = group_objects[key] text = "" From a29d69296bb311b3130fb2e85106a85d9f4d7b1b Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Tue, 2 Nov 2021 13:53:17 -0400 Subject: [PATCH 5/5] Place marker. --- tools/schemacode/schema.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/schemacode/schema.py b/tools/schemacode/schema.py index c3b7abdc49..fe764a23af 100644 --- a/tools/schemacode/schema.py +++ b/tools/schemacode/schema.py @@ -264,6 +264,7 @@ def make_glossary(schema): text = "" for obj_key in sorted(all_objects.keys()): obj = all_objects[obj_key] + obj_marker = obj["key"] obj_def = obj["definition"] obj_name = obj_def["name"] obj_desc = obj_def["description"] @@ -274,6 +275,7 @@ def make_glossary(schema): # Otherwise a newline corresponds to a space obj_desc = obj_desc.replace("\n", " ") + text += f'\n' text += f"\n## {obj_key}\n\n" text += f"name: {obj_name}\n\n" text += f"description:\n>{obj_desc}\n\n"