diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..13566b81
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/DigLabTools.iml b/.idea/DigLabTools.iml
new file mode 100644
index 00000000..57c2c965
--- /dev/null
+++ b/.idea/DigLabTools.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..eff0e8d7
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..0ab07188
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..770a7849
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24_[Changes]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24_[Changes]/shelved.patch
new file mode 100644
index 00000000..83892eb4
--- /dev/null
+++ b/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24_[Changes]/shelved.patch
@@ -0,0 +1,17 @@
+Index: bep32v01/BidsDatatype.py
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
+<+>import yaml\n\n\ndef _load_data_types(yaml_path=\"ressources/schema/objects/datatypes.yaml\"):\n \"\"\"\n Load data types from a YAML file.\n\n Args:\n yaml_path (str): The path to the YAML file containing data type data.\n\n Returns:\n dict: A dictionary containing data type data.\n \"\"\"\n with open(yaml_path, 'r') as file:\n data_types_data = yaml.safe_load(file)\n return data_types_data\n\n\nclass DataTypes:\n def __init__(self):\n \"\"\"\n Initialize a DataTypes object and load data types from a YAML file.\n \"\"\"\n self.data_types = _load_data_types()\n\n def get_data_type_value(self, data_type_name):\n \"\"\"\n Get the value of a specific data type.\n\n Args:\n data_type_name (str): The name of the data type to retrieve.\n\n Returns:\n str: The value of the data type, or None if the data type does not exist.\n \"\"\"\n return self.data_types.get(data_type_name, {}).get(\"value\")\n\n\ndef main():\n \"\"\"\n Main function to demonstrate the usage of the DataTypes class.\n \"\"\"\n data_types = DataTypes()\n data_type_name = \"anat\"\n data_type = data_types.get_data_type_value(data_type_name)\n if data_type:\n print(f\"Données de type '{data_type_name}':\")\n print(data_type)\n else:\n print(f\"Le type de données '{data_type_name}' n'existe pas.\")\n\n\nif __name__ == \"__main__\":\n main()\n
+===================================================================
+diff --git a/bep32v01/BidsDatatype.py b/bep32v01/BidsDatatype.py
+--- a/bep32v01/BidsDatatype.py
++++ b/bep32v01/BidsDatatype.py
+@@ -41,7 +41,7 @@
+ Main function to demonstrate the usage of the DataTypes class.
+ """
+ data_types = DataTypes()
+- data_type_name = "anat"
++ data_type_name = "mri"
+ data_type = data_types.get_data_type_value(data_type_name)
+ if data_type:
+ print(f"Données de type '{data_type_name}':")
diff --git a/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24_[Changes]1/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24_[Changes]1/shelved.patch
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24__Changes_.xml b/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24__Changes_.xml
new file mode 100644
index 00000000..35eddc03
--- /dev/null
+++ b/.idea/shelf/Uncommitted_changes_before_Checkout_at_23_04_2024_10_24__Changes_.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 00000000..33616f73
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,247 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 0
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1712147092346
+
+
+ 1712147092346
+
+
+
+
+
+
+
+
+
+
+
+ 1712150009848
+
+
+
+ 1712150009848
+
+
+
+ 1712226328132
+
+
+
+ 1712226328132
+
+
+
+ 1712322239976
+
+
+
+ 1712322239976
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/=2.0.0 b/=2.0.0
new file mode 100644
index 00000000..0fd27fec
--- /dev/null
+++ b/=2.0.0
@@ -0,0 +1,6 @@
+Channels:
+ - conda-forge
+ - defaults
+Platform: linux-64
+Collecting package metadata (repodata.json): ...working... done
+Solving environment: ...working... failed
diff --git a/bep32v01/BidsDatatype.py b/bep32v01/BidsDatatype.py
new file mode 100644
index 00000000..900cea5a
--- /dev/null
+++ b/bep32v01/BidsDatatype.py
@@ -0,0 +1,54 @@
+import yaml
+
+
+def _load_data_types(yaml_path="ressources/schema/objects/datatypes.yaml"):
+ """
+ Load data types from a YAML file.
+
+ Args:
+ yaml_path (str): The path to the YAML file containing data type data.
+
+ Returns:
+ dict: A dictionary containing data type data.
+ """
+ with open(yaml_path, 'r') as file:
+ data_types_data = yaml.safe_load(file)
+ return data_types_data
+
+
+class DataTypes:
+ def __init__(self):
+ """
+ Initialize a DataTypes object and load data types from a YAML file.
+ """
+ self.data_types = _load_data_types()
+
+ def get_data_type_value(self, data_type_name):
+ """
+ Get the value of a specific data type.
+
+ Args:
+ data_type_name (str): The name of the data type to retrieve.
+
+ Returns:
+ str: The value of the data type, or None if the data type does not exist.
+ """
+ return self.data_types.get(data_type_name, {}).get("value")
+
+
+def main():
+ """
+ Main function to demonstrate the usage of the DataTypes class.
+ """
+ data_types = DataTypes()
+ data_type_name = "anat"
+ data_type = data_types.get_data_type_value(data_type_name)
+ if data_type:
+ print(f"Données de type '{data_type_name}':")
+ print(data_type)
+ else:
+ print(f"Le type de données '{data_type_name}' n'existe pas.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/BidsDirectoryStructure.py b/bep32v01/BidsDirectoryStructure.py
new file mode 100644
index 00000000..f61f77cd
--- /dev/null
+++ b/bep32v01/BidsDirectoryStructure.py
@@ -0,0 +1,144 @@
+from pathlib import Path
+import yaml
+import helper
+
+
+class DirectoryStructure:
+ def __init__(self):
+ """
+ Initialize a DirectoryStructure object with default parameters.
+ """
+ self.relative_path = "ressources/schema/rules/directories.yaml"
+ self.entity_directory = []
+ self.all_directory = None
+ self.value_directory = None
+ self.required_directory = None
+ self.optional_directory = None
+ self.recommended_directory = None
+ self.top_level_directory = None
+ self.sub_directory = None
+ self.get_detail()
+
+ def load_all_directories(self, relative_path):
+ """
+ Load all directories from a YAML file.
+
+ Args:
+ relative_path (str): The relative path to the YAML file.
+
+ Returns:
+ list: A list of all directories.
+ """
+ # Retrieve absolute path
+ absolute_path = Path(relative_path).resolve()
+
+ # Check if the file exists
+ if absolute_path.exists():
+ with open(absolute_path, 'r') as file:
+ directory_rules = yaml.safe_load(file)
+
+ if directory_rules:
+ self.all_directory = list(set(helper.find_keys_in_dict(directory_rules, 'level')))
+ else:
+ print("Le fichier de règles des répertoires est vide.")
+ else:
+ print("Le fichier YAML spécifié n'existe pas :", absolute_path)
+ return self.all_directory
+
+ def load_all_directoires_all_details(self, relative_path):
+ """
+ Load all directory details from a YAML file.
+
+ Args:
+ relative_path (str): The relative path to the YAML file.
+ """
+ self.entity_directory, self.value_directory, self.required_directory, self.optional_directory, self.recommended_directory, self.top_level_directory = helper.get_directories_with_details(
+ relative_path)
+
+ def get_detail(self):
+ """
+ Get details of all directories.
+ """
+ self.load_all_directories(self.relative_path)
+ self.load_all_directoires_all_details(self.relative_path)
+ return self
+
+ # Getters for attributes
+
+ def get_all_directory(self):
+ """
+ Get all directories.
+
+ Returns:
+ list: A list of all directories.
+ """
+ return self.all_directory
+
+ def get_entity_directory(self):
+ """
+ Get entity directories.
+
+ Returns:
+ list: A list of entity directories.
+ """
+ return self.entity_directory
+
+ def get_value_directory(self):
+ """
+ Get value directories.
+
+ Returns:
+ list: A list of value directories.
+ """
+ return self.value_directory
+
+ def get_required_directory(self):
+ """
+ Get required directories.
+
+ Returns:
+ list: A list of required directories.
+ """
+ return self.required_directory
+
+ def get_optional_directory(self):
+ """
+ Get optional directories.
+
+ Returns:
+ list: A list of optional directories.
+ """
+ return self.optional_directory
+
+ def get_recommended_directory(self):
+ """
+ Get recommended directories.
+
+ Returns:
+ list: A list of recommended directories.
+ """
+ return self.recommended_directory
+
+ def get_top_level_directory(self):
+ """
+ Get top-level directories.
+
+ Returns:
+ list: A list of top-level directories.
+ """
+ return self.top_level_directory
+
+
+if __name__ == "__main__":
+ relative_path = "ressources/schema/rules/directories.yaml"
+
+ common_structure = DirectoryStructure()
+ common_structure.get_detail()
+
+ print("All:", common_structure.get_all_directory())
+ print("Entity:", common_structure.get_entity_directory())
+ print("par Valeur :", common_structure.get_value_directory())
+ print("REQUIRED :", common_structure.get_required_directory())
+ print("optional :", common_structure.get_optional_directory())
+ print("top level:", common_structure.get_top_level_directory())
+ print("recomende:", common_structure.get_recommended_directory())
diff --git a/bep32v01/BidsEmptyRepositoryGenerator.py b/bep32v01/BidsEmptyRepositoryGenerator.py
new file mode 100644
index 00000000..447dff9d
--- /dev/null
+++ b/bep32v01/BidsEmptyRepositoryGenerator.py
@@ -0,0 +1,42 @@
+import sys
+from Createfile import CreatFile
+from Createdirectory import Createdirectory
+
+
+class Generator:
+ def __init__(self, output, sub_id=1, session_id=1, modality=None):
+ """
+ Initialize a Generator object.
+
+ Args:
+ output (str): The output folder path.
+ sub_id (int): Subject ID.
+ session_id (int): Session ID.
+ modality (str, optional): The modality name.
+ """
+ self.output = output
+ self.modality = modality.strip() if modality else None
+ if self.modality:
+ self.directory_builder = Createdirectory(output, sub_id, session_id, self.modality)
+ self.file_builder = CreatFile(output)
+ self.generate()
+ else:
+ print("No modality provided. Please specify a modality.")
+
+ def generate(self):
+ """Generate files and directories."""
+ self.directory_builder.build()
+ self.file_builder.build()
+
+
+if __name__ == "__main__":
+ output = input("Enter the output folder path: ").strip()
+ if output:
+ sub_id = input("Enter the subject ID (default is 1): ").strip()
+ session_id = input("Enter the session ID (default is 1): ").strip()
+ modality = input("Enter the modality (optional): ").strip()
+ sub_id = int(sub_id) if sub_id.isdigit() else 1
+ session_id = int(session_id) if session_id.isdigit() else 1
+ generator = Generator(output, sub_id, session_id, modality)
+ else:
+ print("Output folder path is required.")
diff --git a/bep32v01/BidsEntity.py b/bep32v01/BidsEntity.py
new file mode 100644
index 00000000..bce8329d
--- /dev/null
+++ b/bep32v01/BidsEntity.py
@@ -0,0 +1,55 @@
+import yaml
+
+
+class Entity:
+ def __init__(self):
+ """
+ Initialize an Entity object and load entities from a YAML file.
+ """
+ self.entities = self._load_entities()
+
+ def _load_entities(self, yaml_path="ressources/schema/objects/entities.yaml"):
+ """
+ Load entities from a YAML file.
+
+ Args:
+ yaml_path (str): The path to the YAML file containing entity data.
+
+ Returns:
+ dict: A dictionary containing entity data.
+ """
+ with open(yaml_path, 'r') as file:
+ entities_data = yaml.safe_load(file)
+ return entities_data
+
+ def get_entity_name(self, entity_name):
+ """
+ Get the name of a specific entity.
+
+ Args:
+ entity_name (str): The name of the entity to retrieve.
+
+ Returns:
+ str: The name of the entity, or None if the entity does not exist.
+ """
+ if entity_name in self.entities:
+ return self.entities[entity_name].get("name")
+ else:
+ return None
+
+
+def main():
+ """
+ Main function to demonstrate the usage of the Entity class.
+ """
+ entities = Entity()
+ entity_name = "acquisition" # Example entity name
+ entity_name_output = entities.get_entity_name(entity_name)
+ if entity_name_output:
+ print(f"Nom de l'entité '{entity_name}': {entity_name_output}")
+ else:
+ print(f"L'entité '{entity_name}' n'existe pas.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/BidsFilestructure.py b/bep32v01/BidsFilestructure.py
new file mode 100644
index 00000000..4a071415
--- /dev/null
+++ b/bep32v01/BidsFilestructure.py
@@ -0,0 +1,148 @@
+import yaml
+
+class FileStructure:
+ def __init__(self, relative_path="ressources/schema/rules/files/common/core.yaml"):
+ """
+ Initialize a FileStructure object with a relative path to a YAML file.
+
+ Args:
+ relative_path (str): The relative path to the YAML file containing file structure rules.
+ """
+ self.relative_path = relative_path
+ self.all_files = []
+ self.top_level_files = []
+ self.top_level_directory = []
+ self.top_level_file_details = {}
+ self.top_level_directory_detail = {}
+ self.get_detail()
+
+ def get_all_files(self):
+ """
+ Retrieve all file names from the YAML file containing file structure rules.
+ """
+ with open("ressources/schema/objects/files.yaml", 'r') as file:
+ file_rules = yaml.safe_load(file)
+ if file_rules:
+ for key in file_rules:
+ self.all_files.append(key)
+ if file_rules.get(key).get("file_type") == "regular":
+ self.top_level_files.append(key)
+ else:
+ self.top_level_directory.append(key)
+
+ def get_all_files_detail(self, relative_path):
+ """
+ Retrieve details for all files and directories from a specified YAML file.
+
+ Args:
+ relative_path (str): The relative path to the YAML file containing file structure details.
+ """
+ with open(relative_path, 'r') as file:
+ file_rules = yaml.safe_load(file)
+ if file_rules:
+ for key, value in file_rules.items():
+ if key in self.top_level_files:
+ self.top_level_file_details[key] = value
+ else:
+ self.top_level_directory_detail[key] = value
+
+ def get_detail(self):
+ """
+ Retrieve file structure details and store them in class attributes.
+ """
+ self.get_all_files()
+ self.get_all_files_detail(self.relative_path)
+ self.get_all_files_detail("ressources/schema/rules/files/common/tables.yaml")
+ return self
+
+ def get_detail_for_file(self, file_name):
+ """
+ Retrieve details for a specific file.
+
+ Args:
+ file_name (str): The name of the file.
+
+ Returns:
+ dict: Details of the file.
+ """
+ return self.top_level_file_details.get(file_name)
+
+ def get_detail_for_directory(self, directory_name):
+ """
+ Retrieve details for a specific directory.
+
+ Args:
+ directory_name (str): The name of the directory.
+
+ Returns:
+ dict: Details of the directory.
+ """
+ return self.top_level_directory_detail.get(directory_name)
+
+ # Attributes Getters
+ def get_relative_path(self):
+ """
+ Get the relative path to the YAML file containing file structure rules.
+
+ Returns:
+ str: The relative path.
+ """
+ return self.relative_path
+
+ def get_all_files_list(self):
+ """
+ Get the list of all files.
+
+ Returns:
+ list: List of all file names.
+ """
+ return self.all_files
+
+ def get_top_level_files_list(self):
+ """
+ Get the list of top-level files.
+
+ Returns:
+ list: List of top-level file names.
+ """
+ return self.top_level_files
+
+ def get_top_level_directory_list(self):
+ """
+ Get the list of top-level directories.
+
+ Returns:
+ list: List of top-level directory names.
+ """
+ return self.top_level_directory
+
+ def get_top_level_file_details(self):
+ """
+ Get details of top-level files.
+
+ Returns:
+ dict: Dictionary containing details of top-level files.
+ """
+ return self.top_level_file_details
+
+ def get_top_level_directory_details(self):
+ """
+ Get details of top-level directories.
+
+ Returns:
+ dict: Dictionary containing details of top-level directories.
+ """
+ return self.top_level_directory_detail
+
+
+def main():
+ """
+ Main function to demonstrate the usage of the FileStructure class.
+ """
+ file_structure = FileStructure()
+ file_structure.get_detail()
+ print(file_structure.get_all_files_list())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/BidsModality.py b/bep32v01/BidsModality.py
new file mode 100644
index 00000000..6a2019ea
--- /dev/null
+++ b/bep32v01/BidsModality.py
@@ -0,0 +1,31 @@
+import yaml
+
+
+class Modality:
+ def __init__(self, relative_path="ressources/schema/objects/modalities.yaml"):
+ """
+ Initialize a Modality object with a relative path to a YAML file containing modalities.
+
+ Args:
+ relative_path (str): The relative path to the YAML file containing modalities.
+ """
+ self.relative_path = relative_path
+ self.modalities = []
+
+ with open(relative_path, "r") as file:
+ modalities_yaml = yaml.safe_load(file)
+ if modalities_yaml:
+ self.modalities = list(modalities_yaml.keys())
+
+
+def main():
+ """
+ Main function to demonstrate the usage of the Modality class.
+ """
+ modality = Modality()
+ print("Modalités :")
+ print(modality.modalities)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/Createdirectory.py b/bep32v01/Createdirectory.py
new file mode 100644
index 00000000..4a2f1044
--- /dev/null
+++ b/bep32v01/Createdirectory.py
@@ -0,0 +1,90 @@
+import json
+import os
+from BidsFilestructure import FileStructure
+from BidsDirectoryStructure import DirectoryStructure
+from BidsEntity import Entity
+from BidsDatatype import DataTypes
+from pathlib import Path
+
+class Createdirectory:
+ def __init__(self, output_path, sub_id=1, session_id=1, modality="micr"):
+ """
+ Initialize a Createdirectory object with output path, subject ID, session ID, and modality.
+
+ Args:
+ output_path (str): The path where directories will be created.
+ sub_id (int): Subject ID.
+ session_id (int): Session ID.
+ modality (str): Modality name.
+ """
+ self.session_path = None
+ self.output_path = output_path
+ self.dir_name = []
+ self.filestructure = FileStructure()
+ self.filestructure.get_detail()
+ self.directorystructure = DirectoryStructure()
+ self.entity = Entity()
+ self.dataType = DataTypes()
+ self.sub_id = sub_id
+ self.session_id = session_id
+ self.modality = modality
+ sub_directory = []
+
+ def layout_folder(self):
+ """
+ Create directory layout based on BIDS directory structure.
+ """
+ top_level_dir = self.directorystructure.get_top_level_directory()
+ entity_dir = self.directorystructure.get_entity_directory()
+ value_dir = self.directorystructure.get_value_directory()
+ all_dir = self.directorystructure.get_all_directory()
+ for dir in all_dir:
+
+ path = ""
+ if dir in top_level_dir:
+ if dir in entity_dir:
+ path = self.entity.get_entity_name(dir) + f'-{str(self.sub_id)}'
+
+ elif dir in value_dir:
+ path = self.dataType.get_data_type_value(dir)
+
+ else:
+ path = dir
+
+ self.dir_name.append(path)
+
+ def build(self):
+ """
+ Build the directory structure.
+ """
+ for dir in self.dir_name:
+ first_level_dir = os.path.join(self.output_path, dir)
+ print("path: ", first_level_dir)
+ if not os.path.exists(first_level_dir):
+ os.makedirs(first_level_dir)
+
+ # subdirectory session
+ subject_dir = os.path.join(self.output_path, f'sub-{self.sub_id}')
+ session_dir = os.path.join(subject_dir, f'ses-{self.session_id}')
+ print("subject_dir: ", session_dir)
+ if not os.path.exists(session_dir):
+ os.makedirs(session_dir)
+ # subdirectory_modality
+ modality_dir = os.path.join(session_dir, self.modality)
+ if not os.path.exists(modality_dir):
+ os.makedirs(modality_dir)
+
+
+def main():
+ """
+ Main function to create directory layout.
+ """
+ output_path = "Essaie" # Change this to your desired output path
+ creator = Createdirectory(output_path)
+ creator.layout_folder()
+ creator.build()
+ print("Directory layout created successfully.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/Createfile.py b/bep32v01/Createfile.py
new file mode 100644
index 00000000..a8f10d60
--- /dev/null
+++ b/bep32v01/Createfile.py
@@ -0,0 +1,137 @@
+import json
+import os
+from BidsFilestructure import FileStructure
+
+
+class CreatFile:
+ def __init__(self, output_path):
+ """
+ Initialize a CreatFile object with the output path and initialize filestructure.
+
+ Args:
+ output_path (str): The path where files will be created.
+ """
+ self.output_path = output_path
+ self.file_name = []
+ self.filestructure = FileStructure()
+
+ def create_empty_file(self, filename):
+ """
+ Create an empty file.
+
+ Args:
+ filename (str): The name of the file to create.
+ """
+ file_path = os.path.join(self.output_path, filename)
+ with open(file_path, 'w'):
+ pass
+
+ def write_json_to_file(self, filename, data):
+ """
+ Write JSON data to a file.
+
+ Args:
+ filename (str): The name of the file to write.
+ data (dict): The JSON data to write to the file.
+ """
+ file_path = os.path.join(self.output_path, filename)
+ with open(file_path, 'w') as file:
+ json.dump(data, file)
+
+ def dataset_structure(self, input_data):
+ """
+ Write dataset description JSON data to a file.
+
+ Args:
+ input_data (dict): The dataset description data.
+ """
+ self.write_json_to_file('dataset_description.json', input_data)
+
+ def readme_change_licence(self):
+ """
+ Create empty README, CHANGES, and LICENSES files.
+ """
+ for filename in ['README', 'CHANGES', 'LICENSES']:
+ self.create_empty_file(filename)
+
+ def create_file(self, filename):
+ """
+ Create an empty file.
+
+ Args:
+ filename (str): The name of the file to create.
+ """
+ self.create_empty_file(filename)
+
+ def citation_file(self):
+ """
+ Create a CITATION.cff file.
+ """
+ self.create_file('CITATION.cff')
+
+ def participant_file(self):
+ """
+ Create participant.tsv and participant.json files.
+ """
+ self.create_file('participants.tsv')
+ self.create_file('participants.json')
+
+ def sample_file(self):
+ """
+ Create sample.tsv and sample.json files.
+ """
+ self.create_file('sample.tsv')
+ self.create_file('sample.json')
+
+ def dataset_description(self):
+ """
+ Create a dataset_description.json file.
+ """
+ self.create_file('dataset_description.json')
+
+ def build(self):
+ """
+ Build files based on file structure.
+ """
+ self.layout_file()
+ for filename in self.file_name:
+ self.create_empty_file(filename)
+
+ def get_file_structure(self):
+ """
+ Get the file structure.
+
+ Returns:
+ FileStructure: The file structure.
+ """
+ return self.filestructure
+
+ def layout_file(self):
+ """
+ Layout files based on file structure.
+ """
+ all_file = self.filestructure.get_top_level_files_list()
+
+ for filename in all_file:
+
+ info = self.filestructure.get_detail_for_file(filename)
+
+ if 'path' in info:
+ self.file_name.append(info['path'])
+
+ elif 'stem' in info:
+
+ path = " "
+ path = info['stem']
+
+ for extension in info['extensions']:
+ path = path + extension
+ self.file_name.append(path)
+ if extension != '':
+ path = path[:-len(extension)]
+
+ return self.file_name
+
+
+if __name__ == "__main__":
+ pass
diff --git a/bep32v01/Essaie/CHANGES b/bep32v01/Essaie/CHANGES
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/CITATION.cff b/bep32v01/Essaie/CITATION.cff
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/LICENSE b/bep32v01/Essaie/LICENSE
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/README b/bep32v01/Essaie/README
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/README.md b/bep32v01/Essaie/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/README.rst b/bep32v01/Essaie/README.rst
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/README.txt b/bep32v01/Essaie/README.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/dataset_description.json b/bep32v01/Essaie/dataset_description.json
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/fichier.csv b/bep32v01/Essaie/fichier.csv
new file mode 100644
index 00000000..25de6e16
--- /dev/null
+++ b/bep32v01/Essaie/fichier.csv
@@ -0,0 +1,2 @@
+id,age,sex,group,EEG cap,TaskName,acq_time,EEGGround,EEG system,TaskName 2,TaskName 3,TaskName 4,TaskName 5,TaskName 6,handedness,session_id,Run comment,EEGReference,Run comment 2,Run comment 3,Run comment 4,Run comment 5,Run comment 6,Experimenter 1,Experimenter 2,Experimenter 3,Experiment name,SoftwareFilters,TaskDescription,EEG cap position,Hardware comment,HeadCircumference,SamplingFrequency,TaskDescription 2,TaskDescription 3,TaskDescription 4,TaskDescription 5,TaskDescription 6
+01,6,F,control under 2 years,,facesnback,2024-02-17T17:00,IDK,,Rest,,,,,right,002,Pretty well,Single electrode,good,,,,,Toto,,,EEG_TEST_SUB2001,N/A,more task,CZ at 20cm from nasion,,53.5,3000,just to see,,,,
diff --git a/bep32v01/Essaie/genetic_info.json b/bep32v01/Essaie/genetic_info.json
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/participants.json b/bep32v01/Essaie/participants.json
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/participants.tsv b/bep32v01/Essaie/participants.tsv
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/samples.json b/bep32v01/Essaie/samples.json
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/Essaie/samples.tsv b/bep32v01/Essaie/samples.tsv
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/__init__.py b/bep32v01/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/bep32v01/helper.py b/bep32v01/helper.py
new file mode 100644
index 00000000..16d0f850
--- /dev/null
+++ b/bep32v01/helper.py
@@ -0,0 +1,110 @@
+import os
+import yaml
+
+
+def find_keys_in_dict(dictionary, target_value):
+ """
+ Search for keys corresponding to the given value in a dictionary.
+
+ Args:
+ dictionary (dict): The dictionary to search in.
+ target_value: The value to search for.
+
+ Returns:
+ list: A list of keys corresponding to the value, or an empty list if the value is not found.
+ """
+ keys = []
+
+ for key, value in dictionary.items():
+ if target_value in value:
+ keys.append(key)
+ elif isinstance(value, dict):
+ nested_keys = find_keys_in_dict(value, target_value)
+ keys.extend(nested_keys)
+
+ return keys
+
+
+def find_value_in_dict(dictionary, target_key):
+ """
+ Search for a value corresponding to the given key in a dictionary.
+
+ Args:
+ dictionary (dict): The dictionary to search in.
+ target_key: The key to search for.
+
+ Returns:
+ The value corresponding to the key, or None if the key is not found.
+ """
+ for key, value in dictionary.items():
+ if key == target_key:
+ return value
+ elif isinstance(value, dict):
+ result = find_value_in_dict(value, target_key)
+ if result is not None:
+ return result
+ return None
+
+
+def find_keys_with_value(dictionary, target_value):
+ """
+ Find keys containing the given value in a dictionary.
+
+ Args:
+ dictionary (dict): The dictionary to search in.
+ target_value: The value to search for.
+
+ Returns:
+ list: A list of keys containing the value, or an empty list if the value is not found.
+ """
+ keys = []
+
+ for key, value in dictionary.items():
+ if isinstance(value, list):
+ if target_value in value:
+ keys.append(key)
+ elif value == target_value:
+ keys.append(key)
+ elif isinstance(value, dict):
+ nested_keys = find_keys_with_value(value, target_value)
+ keys.extend(nested_keys)
+
+ return keys
+
+
+def get_directories_with_details(yaml_file):
+ """
+ Get directories with the 'entity' attribute from a YAML file.
+
+ Args:
+ yaml_file (str): Path to the YAML file containing directory information.
+
+ Returns:
+ tuple: A tuple containing lists of directory names categorized based on different criteria.
+ """
+ directories_entities = []
+ directories_values = []
+ directory_required = []
+ directory_optional = []
+ directory_recommended = []
+ top_level_directory = []
+
+ with open(yaml_file, 'r') as file:
+ data = yaml.safe_load(file)
+
+ for directory, info in data.get('raw', {}).items():
+ if 'entity' in info:
+ directories_entities.append(directory)
+ if 'value' in info:
+ directories_values.append(directory)
+ if 'level' in info and info.get('level') == 'required':
+ directory_required.append(directory)
+ if 'level' in info and info.get('level') == 'optional':
+ directory_optional.append(directory)
+ if 'recommended' in info:
+ directory_recommended.append(directory)
+ for directory in data.get('raw', {}).get('root', {}).get('subdirs', {}):
+ top_level_directory.append(directory)
+
+ return (directories_entities, directories_values, directory_required,
+ directory_optional, directory_recommended, top_level_directory)
diff --git a/bep32v01/launch.py b/bep32v01/launch.py
new file mode 100644
index 00000000..83630806
--- /dev/null
+++ b/bep32v01/launch.py
@@ -0,0 +1,34 @@
+from pathlib import Path
+
+from pandas import read_csv
+
+import elab_bridge
+import json
+from elab_bridge import server_interface
+from BidsEmptyRepositoryGenerator import Generator
+import os
+
+from diglab_utils.test_utils import (test_directory, initialize_test_dir)
+
+project_dir = test_directory / 'test files_elab' / 'TestProject'
+SERVER_CONFIG_YAML = ('/home/pourtoi/PycharmProjects/DigLabTools/elab_bridge/tests/'
+ 'testfiles_elab/TestProject/project'
+ '.json')
+
+
+def main():
+ output = input(
+ "Enter the output folder path: :"
+ " ex : /home/pourtoi/PycharmProjects/DigLabTools/bep32v01/Essaie")
+
+ csv_file = os.path.join(output, 'fichier.csv')
+
+ jsonformat = elab_bridge.server_interface.download_experiment(csv_file,
+ SERVER_CONFIG_YAML, 247, format='csv')
+ df = read_csv(csv_file)
+
+ generator = Generator(output, df['id'][0], df['session_id'][0], "micr")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bep32v01/ressources/.idea/inspectionProfiles/Project_Default.xml b/bep32v01/ressources/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..e94858f7
--- /dev/null
+++ b/bep32v01/ressources/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml b/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/misc.xml b/bep32v01/ressources/.idea/misc.xml
new file mode 100644
index 00000000..6eeaaf25
--- /dev/null
+++ b/bep32v01/ressources/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/modules.xml b/bep32v01/ressources/.idea/modules.xml
new file mode 100644
index 00000000..8efbbeb2
--- /dev/null
+++ b/bep32v01/ressources/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/ressources.iml b/bep32v01/ressources/.idea/ressources.iml
new file mode 100644
index 00000000..d0876a78
--- /dev/null
+++ b/bep32v01/ressources/.idea/ressources.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/vcs.xml b/bep32v01/ressources/.idea/vcs.xml
new file mode 100644
index 00000000..b2bdec2d
--- /dev/null
+++ b/bep32v01/ressources/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/.idea/workspace.xml b/bep32v01/ressources/.idea/workspace.xml
new file mode 100644
index 00000000..258be40d
--- /dev/null
+++ b/bep32v01/ressources/.idea/workspace.xml
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 8
+}
+
+
+
+
+
+ {
+ "keyToString": {
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "SHARE_PROJECT_CONFIGURATION_FILES": "true",
+ "git-widget-placeholder": "elab/testexportbids",
+ "last_opened_file_path": "/home/pourtoi/PycharmProjects/DigLabTools/bep32v01/ressources",
+ "node.js.detected.package.eslint": "true",
+ "node.js.detected.package.tslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "node.js.selected.package.tslint": "(autodetect)",
+ "nodejs_package_manager_path": "npm",
+ "vue.rearranger.settings.migration": "true"
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+ 1712044823700
+
+
+ 1712044823700
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bep32v01/ressources/schema/BIDS_VERSION b/bep32v01/ressources/schema/BIDS_VERSION
new file mode 100644
index 00000000..a01185b4
--- /dev/null
+++ b/bep32v01/ressources/schema/BIDS_VERSION
@@ -0,0 +1 @@
+1.10.0-dev
diff --git a/bep32v01/ressources/schema/README.md b/bep32v01/ressources/schema/README.md
new file mode 100644
index 00000000..d8013145
--- /dev/null
+++ b/bep32v01/ressources/schema/README.md
@@ -0,0 +1,1025 @@
+# BIDS schema description
+
+Portions of the BIDS specification are defined using YAML files in order to
+make the specification machine-readable.
+
+Currently the portions of the specification that rely on this schema are:
+- the entity tables,
+- entity definitions,
+- filename templates,
+- metadata tables.
+
+Any changes to the specification should be mirrored in the schema.
+
+## Organization and syntax
+
+At the time of this writing, the schema has the following file layout:
+
+```plain
+├── meta
+│ ├── ...
+│ └── versions.yaml
+├── objects
+│ ├── ...
+│ └── suffixes.yaml
+├── rules
+│ ├── checks
+│ │ ├── ...
+│ │ └── references.yaml
+│ ├── files
+│ │ ├── common
+│ │ │ ├── core.yaml
+│ │ │ └── tables.yaml
+│ │ ├── deriv
+│ │ │ ├── imaging.yaml
+│ │ │ └── preprocessed_data.yaml
+│ │ └── raw
+│ │ ├── ...
+│ │ └── task.yaml
+│ ├── sidecars
+│ │ ├── derivatives
+│ │ │ └── common_derivatives.yaml
+│ │ ├── ...
+│ │ └── pet.yaml
+│ ├── tabular_data
+│ │ ├── derivatives
+│ │ │ └── common_derivatives.yaml
+│ │ ├── ...
+│ │ └── task.yaml
+│ ├── ...
+│ └── modalities.yaml
+├── BIDS_VERSION
+└── SCHEMA_VERSION
+```
+
+The top-level organization includes `objects`, where terms are defined;
+`rules`, where constraints (such as valid filenames or required metadata fields)
+are defined;
+and `meta`, where definitions useful for interpreting the schema are defined.
+
+Each file is made up of YAML data, most often an *object*.
+For example, the file `rules/checks/mri.yaml` contains the contents:
+
+```YAML
+PhasePartUnits:
+ issue:
+ code: PHASE_UNITS
+ message: |
+ Phase images (with the `part-phase` entity) must have units
+ "rad" or "arbitrary".
+ level: error
+ selectors:
+ - modality == "mri"
+ - entities.part == "phase"
+ - '"Units" in sidecar'
+ checks:
+ - intersects([sidecar.Units], ["rad", "arbitrary"])
+```
+
+When we wish to refer to a file we might write `rules/checks/mri.yaml`.
+Alternately, we can use `rules.checks.mri` to refer to the object contained by the
+file.
+Using this notation, the *qualified name*, the contents of an entire directory or a
+portion of a file can be referred to unambiguously.
+For example, the entire `rules/checks/` directory is referred to as `rules.checks`,
+and `rules.checks.mri.PhasePartUnits.issue` refers to the object:
+
+```JSON
+{
+ "code": "PHASE_UNITS",
+ "message": "Phase images (with the `part-phase` [...]\n\"rad\" or \"arbitrary\".\n",
+ "level": "error"
+}
+```
+
+These qualified names may be used in this README, as well as in *references* and
+*expressions*.
+
+### Description formatting
+
+Many objects throughout the schema have a `description` field,
+which will typically be rendered somewhere in the specification.
+Because the specification is written in [Markdown](https://en.wikipedia.org/wiki/Markdown),
+these `description` fields may also contain Markdown,
+including links to other locations in the specification.
+
+Because the same description may be used in multiple locations,
+a mechanism is needed to ensure that the correct path is discovered
+to render the description in each location.
+To do this, the path should follow the form `SPEC_ROOT/path/within/source.md#anchor`.
+For example, to link to the
+[Definitions](https://bids-specification.readthedocs.io/en/stable/common-principles.html#definitions)
+section of
+[Common principles](https://bids-specification.readthedocs.io/en/stable/common-principles.html),
+use the path `SPEC_ROOT/common-principles.md#definitions`:
+
+```Markdown
+[Common principles - Definitions](SPEC_ROOT/common-principles.md#definitions)
+```
+
+Note that the Markdown extension `.md` MUST be used for this to render correctly.
+
+For more information please see the following pull request and linked discussions:
+[#1096](https://github.com/bids-standard/bids-specification/pull/1096)
+
+### References
+
+Some schema entries take the form:
+
+```YAML
+ObjectName:
+ $ref: objects.metadata.OtherObjectName
+```
+
+This object may be *dereferenced* by replacing the `$ref` entry
+with the object being referenced.
+The following two prototypical examples are presented to clarify the semantics of
+references (the cases in which they are used will be presented later):
+
+1. In `objects.enums`:
+ ```YAML
+ _GeneticLevelEnum:
+ type: string
+ enum:
+ - $ref: objects.enums.Genetic.value
+ - $ref: objects.enums.Genomic.value
+ - $ref: objects.enums.Epigenomic.value
+ - $ref: objects.enums.Transcriptomic.value
+ - $ref: objects.enums.Metabolomic.value
+ - $ref: objects.enums.Proteomic.value
+ ```
+ and in `objects.metadata`:
+ ```YAML
+ GeneticLevel:
+ name: GeneticLevel
+ display_name: Genetic Level
+ description: |
+ Describes the level of analysis.
+ Values MUST be one of `"Genetic"`, `"Genomic"`, `"Epigenomic"`,
+ `"Transcriptomic"`, `"Metabolomic"`, or `"Proteomic"`.
+ anyOf:
+ - $ref: objects.enums._GeneticLevelEnum
+ - type: array
+ items:
+ $ref: objects.enums._GeneticLevelEnum
+ ```
+ Here `_GeneticLevelEnum` is used to describe the valid values of `GeneticLevel`,
+ (which are in turn references to individual values), and the references inside `GeneticLevel.anyOf` indicate that there may be a single
+ such value or a list of values.
+
+1. In [`rules.files.deriv.preprocessed_data`](./rules/files/deriv/preprocessed_data.yaml):
+ ```YAML
+ anat_nonparametric_common:
+ $ref: rules.files.raw.anat.nonparametric
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ description: optional
+ ```
+ Here, the derivative datatype rule starts by copying the raw datatype rule
+ `rules.files.raw.anat.nonparametric`.
+ It then *overrides* the `entities` portion of that rule with a new object.
+ To *extend* the original `entities`, it again begins
+ by referencing `rules.files.raw.anat.nonparametric.entities`,
+ and adding the new entities `space` and `description`.
+
+### Expressions
+
+Rules definitions make use of a limited language of expressions that always evaluate to `true` or `false`.
+These expressions may be used as `selectors`, determining whether a rule applies,
+or `checks`, determining whether a rule is satisfied.
+
+Re-examining `rules.checks.mri.PhasePartUnits` from above:
+
+```YAML
+PhasePartUnits:
+ issue:
+ code: PHASE_UNITS
+ message: |
+ Phase images (with the `part-phase` entity) must have units
+ "rad" or "arbitrary".
+ level: error
+ selectors:
+ - modality == "mri"
+ - entities.part == "phase"
+ - '"Units" in sidecar'
+ checks:
+ - intersects([sidecar.Units], ["rad", "arbitrary"])
+```
+
+We see expressions may contain:
+
+- fields such as `modality`, `entities` (which has a `.part` subfield), `sidecar`
+- String literals such as `"mri"`, `"Units"` or `"rad"`
+- Lists containing fields or strings
+- Comparison operators such as `==` (equality) or `in` (subfield exists in field)
+- Functions such as `intersects()`
+
+In fact, the full list of fields is defined in the `meta.context.context` object,
+which (currently) contains at the top level:
+
+- `schema`: access to the schema itself
+- `dataset`: attributes of the whole dataset
+- `subject`: attributes of the current subject
+- `path`: the full path of the current file (relative to dataset root)
+- `entities`: an object of entities parsed from the path
+- `datatype`: the datatype, parsed from the path
+- `suffix`: the suffix, parsed from the path
+- `extension`: the file extension
+- `modality`: the file modality, determined by datatype
+- `sidecar`: the metadata values, accumulated by the inheritance principle
+- `associations`: associated files, discovered by the inheritance principle
+- `columns`: the columns in the current TSV file
+- `json`: the contents of the current JSON file
+- `gzip`: the contents of the current file GZIP header
+- `nifti_header`: selected contents of the current NIfTI file's header
+- `ome`: the contents of the current OME-XML metadata
+- `tiff`: the contents of the current TIFF file's header
+
+Some of these are strings, while others are nested objects.
+These are to be populated by an *interpreter* of the schema,
+and provide the *namespace* in which expressions are evaluated.
+
+The following operators should be defined by an interpreter:
+
+| Operator | Definition | Example |
+| ----------- | ------------------------------------------------------------- | --------------------------------------------- |
+| `==` | equality | `suffix == "T1w"` |
+| `!=` | inequality | `entities.task != "rest"` |
+| `<`/`>` | less-than / greater-than | `sidecar.EchoTime < 0.5` |
+| `<=`/`>=` | less-than-or-equal / greater-than-or-equal | `0 <= 4` |
+| `in` | object lookup, true if RHS is a subfield of LHS | `"Units" in sidecar` |
+| `!` | negation, true if the following value is false, or vice versa | `!true == false` |
+| `&&` | conjunction, true if both RHS and LHS are true | `"Units" in sidecar && sidecar.Units == "mm"` |
+| `\|\|` | disjunction, true if either RHS or LHS is true | `a < mn \|\| a > mx` |
+| `.` | object query, returns value of subfield | `sidecar.Units` |
+| `[]` | array/string index, returns value of Nth element (0-indexed) | `columns.participant_label[0]` |
+| `+` | numeric addition / string concatenation | `x + 1`, `stem + "suffix"` |
+| `-`/`*`/`/` | numeric operators (division coerces to float) | `length(array) - 2`, `x * 2`, `1 / 2 == 0.5` |
+
+The following functions should be defined by an interpreter:
+
+| Function | Definition | Example | Note |
+| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ |
+| `count(arg: array, val: any)` | Number of elements in an array equal to `val` | `count(columns.type, "EEG")` | The number of times "EEG" appears in the column "type" of the current TSV file |
+| `exists(arg: str \| array, rule: str) -> int` | Count of files in an array that exist in the dataset. String is array with length 1. Rules include `"bids-uri"`, `"dataset"`, `"subject"` and `"stimuli"`. | `exists(sidecar.IntendedFor, "subject")` | True if all files in `IntendedFor` exist, relative to the subject directory. |
+| `index(arg: array, val: any)` | Index of first element in an array equal to `val`, `null` if not found | `index(["i", "j", "k"], axis)` | The number, from 0-2 corresponding to the string `axis` |
+| `intersects(a: array, b: array) -> bool` | `true` if arguments contain any shared elements | `intersects(dataset.modalities, ["pet", "mri"])` | True if either PET or MRI data is found in dataset |
+| `length(arg: array) -> int` | Number of elements in an array | `length(columns.onset) > 0` | True if there is at least one value in the onset column |
+| `match(arg: str, pattern: str) -> bool` | `true` if `arg` matches the regular expression `pattern` (anywhere in string) | `match(extension, ".gz$")` | True if the file extension ends with `.gz` |
+| `max(arg: array) -> number` | The largest non-`n/a` value in an array | `max(columns.onset)` | The time of the last onset in an events.tsv file |
+| `min(arg: array) -> number` | The smallest non-`n/a` value in an array | `min(sidecar.SliceTiming) == 0` | A check that the onset of the first slice is 0s |
+| `sorted(arg: array) -> array` | The sorted values of the input array | `sorted(sidecar.VolumeTiming) == sidecar.VolumeTiming` | True if `sidecar.VolumeTiming` is sorted |
+| `substr(arg: str, start: int, end: int) -> str` | The portion of the input string spanning from start position to end position | `substr(path, 0, length(path) - 3)` | `path` with the last three characters dropped |
+| `type(arg: Any) -> str` | The name of the type, including `"array"`, `"object"`, `"null"` | `type(datatypes)` | Returns `"array"` |
+
+#### The special value `null`
+
+Missing values in the context object have the special value `null`.
+This value propagates through all of the above operations in a fully-defined,
+hopefully intuitive way.
+Most operations involving `null` simply resolve to `null`:
+
+| Operation | Result |
+| -------------------------- | ------ |
+| `sidecar.MissingValue` | `null` |
+| `null.anything` | `null` |
+| `null[0]` | `null` |
+| `null && true` | `null` |
+| `null \|\| true` | `null` |
+| `!null` | `null` |
+| `null + 1` | `null` |
+| `null - 1` | `null` |
+| `null * 1` | `null` |
+| `null / 1` | `null` |
+| `match(null, pattern)` | `null` |
+| `intersects(list, null)` | `null` |
+| `substr(null, 0, 1)` | `null` |
+| `substr(str, null, 1)` | `null` |
+| `substr(str, 0, null)` | `null` |
+| `length(null)` | `null` |
+| `count(null, val)` | `null` |
+| `count(list, null)` | `null` |
+| `index(null, val)` | `null` |
+| `index([0], null)` | `null` |
+| `index([], val)` | `null` |
+| `min(null)` | `null` |
+| `max(null)` | `null` |
+| `exists(null, "bids-uri")` | `null` |
+| `exists("/path", null)` | `null` |
+
+The following operators have boolean results:
+
+| Operation | Result | Comment |
+| ------------------------ | ------- | ---------------------------- |
+| `null == false` | `false` | |
+| `null == true` | `false` | |
+| `null != false` | `true` | |
+| `null != true` | `true` | |
+| `null == null` | `true` | |
+| `null == 1` | `false` | Also `<`, `>`, `<=` and `>=` |
+| `"VolumeTiming" in null` | `false` | |
+
+The `type()` function returns a string:
+
+| Operation | Result |
+| ------------ | -------- |
+| `type(null)` | `"null"` |
+
+Finally, if an expression (selector or check) evaluates to `null`,
+the `null` will be interpreted equivalent to `false`.
+That is, a `null` selector will not apply the current rule, and a `null`
+check will fail.
+
+## Object files
+
+Object files define "objects" or "terms", which are semantic descriptions of
+concepts used in BIDS. These reside under the `object.*` namespace in the schema.
+These files **do not** describe how objects of different types
+(for example file suffixes and file entities) interact with one another,
+or whether objects are required in a given dataset or file.
+
+### Overview
+
+There are currently 12 sub-namespaces, which fall into five rough categories.
+
+The namespaces are:
+
+| Namespace | Description | Group |
+| --------------------------- | ----------------------------------------------------------------------------------- | ---------------- |
+| `objects.common_principles` | Terms that are used throughout BIDS | General terms |
+| `objects.modalities` | Broad categories of data represented in BIDS, roughly matching recording instrument | General terms |
+| `objects.entities` | Name-value pairs appearing in filenames | Name/value terms |
+| `objects.metadata` | Name-value pairs appearing in JSON files | Name/value terms |
+| `objects.columns` | Column headings and values appearing in TSV files | Name/value terms |
+| `objects.datatypes` | Subdirectories that organize files by type (such as `anat`, `eeg`) | Value terms |
+| `objects.suffixes` | Filename suffixes that describe the contents of the file | Value terms |
+| `objects.extensions` | Filename component that describe the format of the file | Value terms |
+| `objects.formats` | Terms that define the forms values (for example, in metadata) might take | Formats |
+| `objects.files` | Files and directories that may appear at the root of a dataset | Files |
+| `objects.enums` | Full descriptions of enumerated values used in other sub-namespaces | Value terms |
+
+Because these objects vary, the contents of each namespace can vary.
+
+Common fields to all objects:
+
+| Field | Description |
+| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
+| `description` | A description of the term that can be understood that should not depend on particular surrounding text; may contain markdown for rendering |
+| `display_name` | A human-friendly name, for tools to display; may include spaces |
+
+The name/value terms groups (`entities`, `metadata` and `columns`) define terms where
+a name, when present, has a given meaning, and its value may be restricted.
+
+These objects additionally have the field:
+
+| Field | Description |
+| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `name` | For terms that can take on multiple values (such as entities, metadata fields), the name of the term as it appears in the specification and in a dataset; must be alphanumeric; mutually exclusive with `value` |
+| `type` | The type (such as `string`, `integer`, `object`) of values the term describes |
+| `format` | The format of the term (defined in `objects.formats`) |
+
+Value terms groups (`datatypes`, `suffixes`, `extensions`) define terms where a field
+can take on multiple values.
+For example, a file has one datatype, as compared to a collection of entities.
+
+These objects may have the fields:
+
+| Field | Description |
+| ------- | ---------------------------------------------------------------------------------------------------------------- |
+| `value` | For terms that cannot take on multiple values (for example suffixes or extensions), the string value of the term |
+
+The `formats` terms provide one additional field:
+
+| Field | Description |
+| --------- | ----------------------------------------------------------- |
+| `pattern` | Regular expression validating a string rendering of a value |
+
+#### Value constraints
+
+For name/value terms, the `type` and `format` fields allow constraints to be placed on
+the values described by the names.
+
+Additional fields may apply to further constrain the type:
+
+| Field | Description |
+| -------------------------------------- | --------------------------------------------- |
+| `maximum`/`minimum`/`exclusiveMinimum` | Value ranges for `integer` and `number` types |
+| `maxValue`/`minValue` | Value ranges for `integer` and `number` types |
+| `maxItems`/`minItems` | Size ranges for `array` types |
+| `enum` | List of accepted values for `string` types |
+
+Some values may be more flexible, allowing multiple possible values, or may be
+arrays or objects:
+
+| Field | Description |
+| ---------------------- | --------------------------------------------------------------------------------------------- |
+| `anyOf` | A list of constraints, any of which could apply |
+| `items` | The array described contains values whose types are constrained |
+| `properties` | The object described has a given set of fields; the values of these fields may be constrained |
+| `additionalProperties` | The object described has constraints on its values, but not the names |
+
+### On re-used objects with different definitions
+
+In a few cases, two objects with the same name appear multiple times in the specification.
+When this happens, it is preferred to find a common definition, and clarify it in the rules (see below).
+However, in some cases, the object description and permissible values differ, and it needs to be defined
+as two separate objects.
+
+Consider the following examples:
+
+```yaml
+# reference column for channels.tsv files for EEG data
+reference__eeg:
+ name: reference
+ display_name: Electrode reference
+ description: |
+ Name of the reference electrode(s).
+ This column is not needed when it is common to all channels.
+ In that case the reference electrode(s) can be specified in `*_eeg.json` as `EEGReference`).
+ type: string
+# reference column for channels.tsv files for iEEG data
+reference__ieeg:
+ name: reference
+ display_name: Electrode reference
+ description: |
+ Specification of the reference (for example, `mastoid`, `ElectrodeName01`, `intracranial`, `CAR`, `other`, `n/a`).
+ If the channel is not an electrode channel (for example, a microphone channel) use `n/a`.
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+```
+
+Here, the TSV column `"reference"` means different things when used for EEG data,
+as compared to iEEG data, so two definitions are needed.
+Because columns use `snake_case` (meaning they can be expected to contain underscores),
+two underscores are needed to separate the column name from the string that indicates the use of the term.
+
+The convention can be summed up in the following rules:
+
+1. Each specific term takes on the form `_`, where `` is the common name that
+ the two (or more) terms share, `` indicates when the specific term applies.
+
+1. If the `` appears in `snake_case` then `` begins with an extra `_`.
+
+#### Valid fields for definitions by sub-namespace
+
+- `objects.common_principles`
+ | Field | Description |
+ | -------------- | ------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+
+- `objects.modalities`
+ | Field | Description |
+ | -------------- | ------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+
+- `objects.entities`
+
+ | Field | Description |
+ | -------------- | ------------------------------------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `name` | Key of entity, such as `sub` or `ses` |
+ | `type` | Type of value (always `string`) |
+ | `format` | Permissible format of values, either `label` or `index` |
+ | `enum` | Exclusive list of valid values, if present |
+
+ Note that descriptions should apply to *all* uses of the entity; if additional information
+ applies in certain contexts, that should be written in the specification, and not the schema.
+
+- `objects.metadata`
+ | Field | Description |
+ | -------------- | ------------------------------------------------------------------------------------ |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `name` | Name of field in JSON object (in `CamelCase`) |
+ | `unit` | Interpretation of numeric values |
+ | `type` | Type of value (one of `array`, `string`, `integer`, `number`, `object` or `boolean`) |
+ | `format` | Permissible format of values, from definitions in `objects.formats` |
+ | `enum` | Exclusive list of valid values, if present |
+ | `maximum` | Maximum for numeric values |
+ | `minimum` | Minimum for numeric values |
+ | `*` | JSON-schema fields to further constrain values |
+
+- `objects.columns`
+ | Field | Description |
+ | -------------- | ------------------------------------------------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `name` | Name of column in TSV file (in `snake_case`) |
+ | `unit` | Interpretation of numeric values |
+ | `type` | Type of value |
+ | `format` | Permissible format of values, from definitions in `objects.formats` |
+ | `pattern` | Regular expression constraining string values |
+ | `enum` | Exclusive list of valid values, if present |
+ | `maximum` | Maximum for numeric values |
+ | `minimum` | Minimum for numeric values |
+ | `*` | JSON-schema fields to further constrain values |
+
+- `objects.datatypes`
+ | Field | Description |
+ | -------------- | -------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `value` | String value of `datatype` |
+
+- `objects.suffixes`
+ | Field | Description |
+ | -------------- | -------------------------------------------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `value` | String value of `suffix` |
+ | `unit` | Interpretation of values in a data file with the given suffix |
+ | `maxValue` | Maximum permissible value in a data file with the given suffix |
+ | `minValue` | Minimum permissible value in a data file with the given suffix |
+ | `anyOf` | Used to describe multiple permissible units |
+
+- `objects.extensions`
+ | Field | Description |
+ | -------------- | --------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `value` | String value of `extension` |
+
+- `objects.formats`
+ | Field | Description |
+ | -------------- | ---------------------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `pattern` | Regular expression defining format |
+
+- `objects.files`
+ | Field | Description |
+ | -------------- | ------------------------------------------------------------------------------------ |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `file_type` | Indicator that the file is a regular file (`"regular"`) or directory (`"directory"`) |
+
+- `objects.enums`
+ | Field | Description |
+ | -------------- | ---------------------- |
+ | `display_name` | Human-friendly name |
+ | `description` | Term definition |
+ | `value` | String value of `enum` |
+
+## Rule files
+
+The `rules.*` namespace contains most of the validatable content of the schema,
+apart from value constraints that can be encoded in `objects`.
+
+There are several types of rule, and this section is subject to reconsolidation as
+patterns are found.
+
+### Core concepts
+
+Core concepts are [expressions](#expressions) (defined above), requirement levels and issues.
+
+#### Requirement levels and severity
+
+BIDS follows RFC 2119 and has three requirement levels: OPTIONAL, RECOMMENDED and REQUIRED.
+In the schema, we use `optional`, `recommended` and `required`.
+
+A rule interpreter (validator) is expected to treat:
+- missing REQUIRED data/metadata as an error,
+- missing RECOMMENDED data/metadata as a warning,
+- and silently pass over missing OPTIONAL data.
+
+BIDS also defines a level `DEPRECATED`, rendered in the schema as `deprecated`,
+and corresponding to a warning if the data/metadata is present.
+
+#### Issues
+
+Issues are messages intended to be communicated to a dataset curator to indicate an issue
+with their dataset.
+
+They have a code and severity as well:
+
+| Field | Description |
+| --------- | ---------------------------------------------- |
+| `code` | Issue identifier, such as `EVENTS_TSV_MISSING` |
+| `level` | Issue severity (`warning` or `error`) |
+| `message` | Message for display to a user |
+
+A level of `warning` corresponds to a rule in the specification that is RECOMMENDED,
+while a level of `error` corresponds to a rule that is REQUIRED.
+
+In some cases, an issue is contained next to a `level: required` or `level: recommended`
+as part of a larger rule.
+In these cases, the `level` field should be omitted from the issue
+to avoid duplication or conflict.
+
+### Filename construction rules
+
+A significant portion of BIDS is devoted to the naming of files,
+and almost all filenames consist of entities, a suffix, an extension, and a data type.
+Exceptions will be noted below.
+
+`rules.files` contains the following subdivisions.
+
+| Namespace | Description |
+| --------------------------- | ----------------------------------------------------------------------------------------- |
+| `rules.files.common.core` | Files and directories that reside at the top level of datasets |
+| `rules.files.common.tables` | Tabular metadata files that associate metadata with entities |
+| `rules.files.raw.*` | Raw data and metadata files that have entities, suffixes, datatypes and extensions |
+| `rules.files.deriv.*` | Derivative data and metadata files that have entities, suffixes, datatypes and extensions |
+
+#### Core files and directories
+
+`rules.files.common.core` describes files that have little-to-no variability in their form.
+These either have a single `path` field, or a `stem` field and a list of `extensions`:
+
+| Field | Description |
+| ------------ | ------------------------------------------------------------------------------------------------------------- |
+| `level` | Requirement level of file, one of (`optional`, `recommended`, `required`, `deprecated`) |
+| `path` | Location of file, relative to dataset root; mutually exclusive with `stem` and `extensions` |
+| `stem` | Name of file, relative to dataset root, up to but not including the extension; mutually exclusive with `path` |
+| `extensions` | List of valid extension strings, including the initial dot (`.`); mutually exclusive with `path` |
+
+These are the entries for `dataset_description.json` and `README`:
+
+```YAML
+dataset_description:
+ level: required
+ path: dataset_description.json
+README:
+ level: required
+ stem: README
+ extensions:
+ - ''
+ - .md
+ - .rst
+ - .txt
+```
+
+Here, `README` and `README.md` are both valid, while only `dataset_description.json` is permitted.
+
+#### Tabular metadata files
+
+`rules.files.common.tables` describes TSV files and their associated metadata,
+including `participants.tsv`, `samples.tsv`, `*_sessions.tsv` and `*_scans.tsv`.
+The first two use the `stem` field, while the latter two specify the entities used
+to construct the filename.
+
+The valid fields are:
+
+| Field | Description |
+| ------------ | ----------------------------------------------------------------------------------------------------------------- |
+| `level` | Requirement level of file, one of (`optional`, `recommended`, `required`, `deprecated`) |
+| `stem` | Name of file, relative to dataset root, up to but not including the extension; mutually exclusive with `entities` |
+| `entities` | Object where the keys are entries in `objects.entities`. The value is a requirement level. |
+| `extensions` | List of valid extension strings, including the initial dot (`.`) |
+
+For example:
+
+```YAML
+participants:
+ level: optional
+ stem: participants
+ extensions:
+ - .tsv
+ - .json
+sessions:
+ suffixes:
+ - sessions
+ extensions:
+ - .tsv
+ - .json
+ entities:
+ subject: required
+```
+
+Note that these files do not have a `datatype`, but otherwise follow the same rules as above.
+
+#### BIDS filenames
+
+`rules.files.raw` and `rules.files.deriv` contain series of related rules.
+These are largely grouped by datatype, but file types that appear in multiple locations may be grouped together.
+
+The files described take the form:
+
+```plain
+[sub-/][ses-/]/_
+```
+
+Rules have the following fields:
+
+| Field | Description |
+| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
+| `suffixes` | List of suffixes found in `objects.suffixes` |
+| `extensions` | List of valid extension strings, including initial dot (`.`) |
+| `datatypes` | List of datatypes found in `objects.datatypes` |
+| `entities` | Object where the keys are entries in `objects.entities`. The value is either a requirement level or an object described by the following table. |
+
+| Field | Requirement level | Description |
+| -------- | ----------------- | ---------------------------------------------------------------------------------------- |
+| `level` | REQUIRED | Requirement level of field, one of (`optional`, `recommended`, `required`, `deprecated`) |
+| `format` | OPTIONAL | Override of entity field - Permissible format of values, either `label` or `index` |
+| `enum` | OPTIONAL | Override of entity field - Exclusive list of valid values, if present |
+
+As an example, let us look at a (modified) part of `meg.yaml`:
+
+```yaml
+meg:
+ suffixes:
+ - meg
+ extensions:
+ - .fif
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+ processing: optional
+ split: optional
+
+crosstalk:
+ suffixes:
+ - meg
+ extensions:
+ - .fif
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ acquisition:
+ level: required
+ enum:
+ - crosstalk
+```
+
+In this case, the first group has one suffix: `meg`.
+The second group has the same suffix (`meg`), but describes different rules for files with that suffix.
+While the valid extension is the same for both groups (`.fif`), the entities are not.
+
+Specifically, files in the first group may have `task`, `run`, `processing`, and `split` entities,
+while files in the second group may not.
+Also, when files in the second group have the `acq` entity, the associated value MUST be `crosstalk`.
+
+A common derivatives type is preprocessed data, where the type of the generated data is the same
+as the input data.
+BIDS Derivatives specifies that these files may be distinguished from raw data
+with the new entities `space-` or `desc-`.
+
+This rule is encoded:
+
+```yaml
+meg_meg_common:
+ $ref: rules.files.raw.meg.meg
+ entities:
+ $ref: rules.files.raw.meg.meg.entities
+ space: optional
+ description: optional
+```
+
+When expanded, this becomes:
+
+```yaml
+meg_meg_common:
+ suffixes:
+ - meg
+ extensions:
+ - .fif
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+ processing: optional
+ split: optional
+ space: optional
+ description: optional
+```
+
+### Sidecar and tabular data rules
+
+Tabular data and JSON sidecar files follow a similar pattern:
+
+| | Name | Value |
+| ---- | ------------- | ------------- |
+| JSON | field | value |
+| TSV | column header | column values |
+
+In the specification, groups of fields/columns are described together in a table
+that includes the name of the field/column, the requirement level and a description.
+The definitions, including name and description, appear in `objects.metadata`,
+and the columns appear in `objects.columns`.
+
+Here, we define YAML "tables" that can be rendered in the specification. These
+take the form:
+
+```YAML
+RuleName:
+ selectors:
+ - expression1
+ - expression2
+ fields:
+ - FieldName1:
+ level: recommended
+ level_addendum: required if XYZ
+ description_addendum: Additional text following object description.
+ - FieldName2: optional
+
+RuleNameReq:
+ selectors:
+ - expression1
+ - expression2
+ - expression3
+ fields:
+ - FieldName1:
+ level: required
+ issue:
+ code: ISSUE_NAME
+ message: A description of the problem for a user
+```
+
+Here we show an example of two fields, one that is RECOMMENDED in most cases
+but REQUIRED in another, the other of which is OPTIONAL.
+
+`selectors` indicate whether the current rule applies to a given file.
+This is not rendered in the text, but may be used by a validator.
+`fields` is an object with keys that appear in `objects.metadata`/`objects.columns`.
+If the value is a string, then it is a requirement level.
+If it is an object, then the it has the following fields
+
+| Field | Requirement level | Description |
+| ---------------------- | ----------------- | ---------------------------------------------------------------------------------------- |
+| `level` | REQUIRED | Requirement level of field, one of (`optional`, `recommended`, `required`, `deprecated`) |
+| `level_addendum` | OPTIONAL | Additional text to describe cases where requirement level changes |
+| `description_addendum` | OPTIONAL | Additional text to follow the `objects.metadata..description` |
+| `issue` | OPTIONAL | [issue object](#issues), if additional communication is warranted |
+
+The second table implements the change in the first table's `level_addendum`.
+The `expression3` selector indicates the additional case where the more stringent
+rule is applied.
+
+#### Valid fields for definitions
+
+1. `rules.sidecars.*`
+
+ | Field | Description |
+ | ----------- | -------------------------------------------------------------------------------------------------------- |
+ | `selectors` | List of expressions; any evaluating false indicate rule does not apply |
+ | `fields` | Object with keys that may be found in `objects.metadata`, values either a requirement level or an object |
+
+1. `rules.tabular_data.*`
+
+ | Field | Description |
+ | -------------------- | -------------------------------------------------------------------------------------------------------------- |
+ | `selectors` | List of expressions; any evaluating false indicate rule does not apply |
+ | `columns` | Object with keys that may be found in `objects.columns`, values either a requirement level or an object |
+ | `initial_columns` | An optional list of columns that must be the first N columns of a file |
+ | `index_columns` | An optional list of columns that uniquely identify a row. |
+ | `additional_columns` | Indicates whether additional columns may be defined. One of `allowed`, `allowed_if_defined` and `not_allowed`. |
+
+The following tables demonstrate how mutual exclusive, required fields,
+may be set in `rules.sidecars.*`:
+
+```YAML
+MRIFuncRepetitionTime:
+ selectors:
+ - modality == "mri"
+ - datatype == "func"
+ - '!("VolumeTiming" in sidecar)'
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ RepetitionTime:
+ level: required
+ level_addendum: mutually exclusive with `VolumeTiming`
+
+MRIFuncVolumeTiming:
+ selectors:
+ - modality == "mri"
+ - datatype == "func"
+ - '!("RepetitionTime" in sidecar)'
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ VolumeTiming:
+ level: required
+ level_addendum: mutually exclusive with `RepetitionTime`
+```
+
+An additional check will be required to assert that both are not present,
+but these tables may be combined for rendering purposes.
+
+Here we present an example rule in `rules.tabular_data.eeg`:
+
+```YAML
+EEGChannels:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - type__channels
+ - units
+ columns:
+ name__channels: required
+ type__channels: required
+ units: required
+ description: optional
+ sampling_frequency: optional
+ reference: optional
+ low_cutoff: optional
+ high_cutoff: optional
+ notch: optional
+ status: optional
+ status_descriptions: optional
+ additional_columns: allowed_if_defined
+```
+
+### Checks
+
+`rules.checks` can contain more complex rules. Structurally, these are similar to sidecar rules,
+in that they have selectors.
+They additionally have a `checks` list, and an explicit issue.
+
+| Field | Description |
+| ----------- | ---------------------------------------------------------------------------------------------- |
+| `issue` | Issue code object (see [Issues](#issues) |
+| `selectors` | List of expressions; any evaluating false indicate rule does not apply |
+| `checks` | List of expressions; any evaluating false indicate rule is violated and issue should be raised |
+
+```YAML
+EventsMissing:
+ issue:
+ code: EVENTS_TSV_MISSING
+ message: |
+ Task scans should have a corresponding events.tsv file.
+ If this is a resting state scan you can ignore this warning or rename the task to include the word "rest".
+ level: warning # could be an error with the proper selectors, I think
+ selectors:
+ - '"task" in entities'
+ - '!match(entities.task, "rest")'
+ - suffix != "events"
+ checks:
+ - '"events" in associations'
+```
+
+### Ordering rules
+
+- `rules.entities` - This file contains a list of keys into `objects.entities` and
+ simply defines the order in which entities, when present, MUST appear in filenames
+
+- `rules.common_principles` - This file contains a list of terms that appear in `objects.common_principles`
+ that determines the order they appear in the specification
+
+### One-off rules
+
+- `rules.modalities` - The keys in this file are the modalities, the values objects with the following field:
+ | Field | Description |
+ | ----------- | ------------------------------------- |
+ | `datatypes` | List of datatypes mapping to modality |
+
+- `rules.dataset_metadata` - These are similar to `rules.sidecars.*`, for JSON files at the root level.
+ This is likely to go away in favor of other approaches.
+
+- `rules.errors` - This file describes errors that cannot be expressed in the schema. This provides common
+ codes and language that implementing validators can use to ensure the same problems are reported to
+ users in the same way.
+
+## Version of the schema
+
+File `SCHEMA_VERSION` in the top of the directory contains a semantic
+version (`MAJOR.MINOR.PATCH`) for the schema (how it is organized).
+Note that while in `0.` series, breaking changes are
+permitted without changing the `MAJOR` (leading) component of the version.
+Going forward, the 2nd, `MINOR` indicator should be
+incremented whenever schema organization introduces "breaking changes":
+changes which would cause existing tools reading schema to
+adjust their code to be able to read it again.
+Additions of new components to the schema should increment the last,
+`PATCH`, component of the version so that tools could selectively
+enable/disable loading specific components of the schema.
+With the release of `1.0.0` version of the schema,
+we expect that the `MAJOR` component
+will be incremented whenever schema organization introduces "breaking changes",
+`MINOR` - when adding new components to the schema,
+and `PATCH` - when fixing errors in existing components.
+
+## Schema publication
+
+The BIDS Schema is compiled into a single, dereferenced object during
+the ReadTheDocs build of the specification.
+This object is published as a JSON document that can be found at `/schema.json`
+at the root of the specification.
+For example, the schema used to construct the 1.8.0 release of BIDS can be found at
+,
+and the latest version that includes unreleased changes to BIDS and the schema may
+be found at .
+
+The JSON version of the schema contains `schema_version` and `bids_version` keys
+that identify the state of both the schema and the specification at the time it was
+compiled.
diff --git a/bep32v01/ressources/schema/SCHEMA_VERSION b/bep32v01/ressources/schema/SCHEMA_VERSION
new file mode 100644
index 00000000..d182dc91
--- /dev/null
+++ b/bep32v01/ressources/schema/SCHEMA_VERSION
@@ -0,0 +1 @@
+0.8.1-dev
diff --git a/bep32v01/ressources/schema/meta/associations.yaml b/bep32v01/ressources/schema/meta/associations.yaml
new file mode 100644
index 00000000..f7dafed9
--- /dev/null
+++ b/bep32v01/ressources/schema/meta/associations.yaml
@@ -0,0 +1,92 @@
+# These rules indicate whether an association (defined in meta.context.context.associations)
+# applies to a given file. These are hints to allow implementations to avoid unnecessary
+# directory and file reads.
+#
+# Structure:
+#
+# - "selectors" is a sequence of expressions that apply to a file that may have an association.
+# If matched, a tool MUST attempt to find the associated file.
+# - "target" contains a set of path components that may be used to search for the associated file.
+# These override the path components of the original file and MUST match for the associated file.
+# A list of values, such as extensions, indicates multiple possible matches.
+# - "inherit" is a boolean indicating whether the associated file may be found at a shallower level
+# of the hierarchy.
+---
+events:
+ selectors:
+ - 'task in entities'
+ - extension != '.json'
+ target:
+ suffix: events
+ extension: .tsv
+ inherit: true
+
+aslcontext:
+ selectors:
+ - suffix == 'asl'
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ suffix: aslcontext
+ extension: .tsv
+ inherit: true
+
+m0scan:
+ selectors:
+ - suffix == 'asl'
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ suffix: m0scan
+ extension: [.nii, .nii.gz]
+ inherit: false
+
+magnitude:
+ selectors:
+ - suffix == 'fieldmap'
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ suffix: magnitude
+ extension: [.nii, .nii.gz]
+ inherit: false
+
+magnitude1:
+ selectors:
+ - match(suffix, 'phase(diff|1)$')
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ suffix: magnitude1
+ extension: [.nii, .nii.gz]
+ inherit: false
+
+bval:
+ selectors:
+ - suffix == 'dwi'
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ extension: .bval
+ inherit: true
+
+bvec:
+ selectors:
+ - suffix == 'dwi'
+ - match(extension, '\.nii(\.gz)?$')
+ target:
+ extension: .bvec
+ inherit: true
+
+channels:
+ selectors:
+ - intersects([suffix], ['eeg', 'ieeg', 'meg', 'nirs', 'motion', 'optodes'])
+ - extension != '.json'
+ target:
+ suffix: channels
+ extension: .tsv
+ inherit: true
+
+coordsystem:
+ selectors:
+ - intersects([suffix], ['eeg', 'ieeg', 'meg', 'nirs', 'motion', 'electrodes', 'optodes'])
+ - extension != '.json'
+ target:
+ suffix: coordsystem
+ extension: .json
+ inherit: true
diff --git a/bep32v01/ressources/schema/meta/context.yaml b/bep32v01/ressources/schema/meta/context.yaml
new file mode 100644
index 00000000..4404e390
--- /dev/null
+++ b/bep32v01/ressources/schema/meta/context.yaml
@@ -0,0 +1,364 @@
+#
+# The context provides the namespaces available to rules.
+# These namespaces are used by selectors to define the scope of application
+# for a rule, as well as assertions, to determine whether the rule is satisfied.
+#
+# Not all components of the context will be defined; for example a NIfTI header
+# will only be defined when examining a NIfTI file.
+#
+# The dataset namespace is constructed once and is available when visiting all
+# files.
+#
+# The subject namespace is constructed once per subject, and is available when
+# visiting all files within that subject.
+#
+# All other (current) namespaces are defined on individual files.
+# Sidecar metadata and file associations are built according to the inheritance
+# principle.
+#
+---
+context:
+ type: object
+ properties:
+ schema:
+ description: 'The BIDS specification schema'
+ type: object
+ dataset:
+ description: 'Properties and contents of the entire dataset'
+ type: object
+ properties:
+ dataset_description:
+ description: 'Contents of /dataset_description.json'
+ type: object
+ files:
+ description: 'List of all files in dataset'
+ type: array
+ tree:
+ description: 'Tree view of all files in dataset'
+ type: object
+ ignored:
+ description: 'Set of ignored files'
+ type: array
+ datatypes:
+ description: 'Data types present in the dataset'
+ type: array
+ modalities:
+ description: 'Modalities present in the dataset'
+ type: array
+ subjects:
+ description: 'Collections of subjects in dataset'
+ type: object
+ properties:
+ sub_dirs:
+ description: 'Subjects as determined by sub-*/ directories'
+ type: array
+ items:
+ type: string
+ participant_id:
+ description: 'The participant_id column of participants.tsv'
+ type: array
+ items:
+ type: string
+ phenotype:
+ description: 'The union of participant_id columns in phenotype files'
+ type: array
+ items:
+ type: string
+ subject:
+ description: 'Properties and contents of the current subject'
+ type: object
+ properties:
+ sessions:
+ description: 'Collections of sessions in subject'
+ type: object
+ properties:
+ ses_dirs:
+ description: 'Sessions as determined by ses-*/ directories'
+ type: array
+ items:
+ type: string
+ session_id:
+ description: 'The session_id column of sessions.tsv'
+ type: array
+ items:
+ type: string
+ phenotype:
+ description: 'The union of session_id columns in phenotype files'
+ type: array
+ items:
+ type: string
+
+ # Properties of the current file
+ path:
+ description: 'Path of the current file'
+ type: string
+ size:
+ description: 'Length of the current file in bytes'
+ type: int
+ entities:
+ description: 'Entities parsed from the current filename'
+ type: object
+ datatype:
+ description: 'Datatype of current file, for examples, anat'
+ type: string
+ suffix:
+ description: 'Suffix of current file'
+ type: string
+ extension:
+ description: 'Extension of current file including initial dot'
+ type: string
+ modality:
+ description: 'Modality of current file, for examples, MRI'
+ type: string
+
+ sidecar:
+ description: 'Sidecar metadata constructed via the inheritance principle'
+ type: object
+ associations:
+ # Note that this is not intended to be an exhaustive list of associated files
+ # or to expose every attribute of those files. It is specifically those files
+ # and attributes for which a rule needs to be applied from an originating file.
+ description: |
+ Associated files, indexed by suffix, selected according to the inheritance principle
+ type: object
+ properties:
+ events:
+ description: 'Events file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated events file'
+ type: string
+ onset:
+ description: 'Contents of the onset column'
+ type: array
+ items:
+ type: string
+ aslcontext:
+ description: 'ASL context file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated aslcontext file'
+ type: string
+ n_rows:
+ description: 'Number of rows in aslcontext.tsv'
+ type: integer
+ volume_type:
+ description: 'Contents of the volume_type column'
+ type: array
+ items:
+ type: string
+ m0scan:
+ description: 'M0 scan file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated M0 scan file'
+ type: string
+ magnitude:
+ description: 'Magnitude image file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated magnitude file'
+ type: string
+ magnitude1:
+ description: 'Magnitude1 image file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated magnitude1 file'
+ type: string
+ bval:
+ description: 'B value file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated bval file'
+ type: string
+ n_cols:
+ description: 'Number of columns in bval file'
+ type: integer
+ n_rows:
+ description: 'Number of rows in bval file'
+ type: integer
+ bvec:
+ description: 'B vector file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated bvec file'
+ type: string
+ n_cols:
+ description: 'Number of columns in bvec file'
+ type: integer
+ n_rows:
+ description: 'Number of rows in bvec file'
+ type: integer
+ channels:
+ description: 'Channels file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated channels file'
+ type: string
+ type:
+ description: 'Contents of the type column'
+ type: array
+ items:
+ type: string
+ coordsystem:
+ description: 'Coordinate system file'
+ type: object
+ properties:
+ path:
+ description: 'Path to associated coordsystem file'
+ type: string
+ # The following properties are populated if the current file is of an appropriate type
+ columns:
+ description: 'TSV columns, indexed by column header, values are arrays with column contents'
+ type: object
+ additionalProperties:
+ type: array
+ json:
+ description: 'Contents of the current JSON file'
+ type: object
+ gzip:
+ description: 'Parsed contents of gzip header'
+ type: object
+ properties:
+ timestamp:
+ description: 'Modification time, unix timestamp'
+ type: number
+ filename:
+ description: 'Filename'
+ type: string
+ comment:
+ description: 'Comment'
+ type: string
+ nifti_header:
+ name: 'NIfTI Header'
+ description: 'Parsed contents of NIfTI header referenced elsewhere in schema.'
+ type: object
+ properties:
+ dim_info:
+ name: 'Dimension Information'
+ description: 'Metadata about dimensions data.'
+ type: object
+ properties:
+ freq:
+ name: 'Frequency'
+ description: 'These fields encode which spatial dimension (1, 2, or 3).'
+ type: integer
+ phase:
+ name: 'Phase'
+ description: 'Corresponds to which acquisition dimension for MRI data.'
+ type: integer
+ slice:
+ name: 'Slice'
+ description: 'Slice dimensions.'
+ type: integer
+ dim:
+ name: 'Data Dimensions'
+ description: 'Data seq dimensions.'
+ type: array
+ minItems: 8
+ maxItems: 8
+ items:
+ type: integer
+ pixdim:
+ name: 'Pixel Dimension'
+ description: 'Grid spacings (unit per dimension).'
+ type: array
+ minItems: 8
+ maxItems: 8
+ items:
+ type: number
+ shape:
+ name: 'Data shape'
+ description: 'Data array shape, equal to dim[1:dim[0] + 1]'
+ type: array
+ minItems: 0
+ maxItems: 7
+ items:
+ type: integer
+ voxel_sizes:
+ name: 'Voxel sizes'
+ description: 'Voxel sizes, equal to pixdim[1:dim[0] + 1]'
+ type: array
+ minItems: 0
+ maxItems: 7
+ items:
+ type: number
+ xyzt_units:
+ name: 'XYZT Units'
+ description: 'Units of pixdim[1..4]'
+ type: object
+ properties:
+ xyz:
+ name: 'XYZ Units'
+ description: 'String representing the unit of voxel spacing.'
+ type: string
+ enum:
+ - $ref: objects.enums.unknown.value
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ - 'meter'
+ - 'mm'
+ - 'um'
+ t:
+ name: 'Time Unit'
+ description: 'String representing the unit of inter-volume intervals.'
+ type: string
+ enum:
+ - $ref: objects.enums.unknown.value
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ - 'sec'
+ - 'msec'
+ - 'usec'
+ qform_code:
+ name: 'qform code'
+ description: 'Use of the quaternion fields.'
+ type: integer
+ sform_code:
+ name: 'sform code'
+ description: 'Use of the affine fields.'
+ type: integer
+ ome:
+ name: 'Open Microscopy Environment fields'
+ description: 'Parsed contents of OME-XML header, which may be found in OME-TIFF or OME-ZARR files'
+ type: object
+ properties:
+ PhysicalSizeX:
+ name: 'PhysicalSizeX'
+ description: 'Pixels / @PhysicalSizeX'
+ type: float
+ PhysicalSizeY:
+ name: 'PhysicalSizeY'
+ description: 'Pixels / @PhysicalSizeY'
+ type: float
+ PhysicalSizeZ:
+ name: 'PhysicalSizeZ'
+ description: 'Pixels / @PhysicalSizeZ'
+ type: float
+ PhysicalSizeXUnit:
+ name: 'PhysicalSizeXUnit'
+ description: 'Pixels / @PhysicalSizeXUnit'
+ type: string
+ PhysicalSizeYUnit:
+ name: 'PhysicalSizeYUnit'
+ description: 'Pixels / @PhysicalSizeYUnit'
+ type: string
+ PhysicalSizeZUnit:
+ name: 'PhysicalSizeZUnit'
+ description: 'Pixels / @PhysicalSizeZUnit'
+ type: string
+ tiff:
+ name: 'TIFF'
+ description: 'TIFF file format metadata'
+ type: object
+ properties:
+ version:
+ name: 'Version'
+ description: 'TIFF file format version (the second 2-byte block)'
+ type: int
diff --git a/bep32v01/ressources/schema/meta/expression_tests.yaml b/bep32v01/ressources/schema/meta/expression_tests.yaml
new file mode 100644
index 00000000..e1f06fde
--- /dev/null
+++ b/bep32v01/ressources/schema/meta/expression_tests.yaml
@@ -0,0 +1,116 @@
+---
+# null fall-through logic
+- expression: sidecar.MissingValue
+ result: null
+- expression: null.anything
+ result: null
+- expression: (null)
+ result: null
+- expression: null[0]
+ result: null
+- expression: null && true
+ result: null
+- expression: true && null
+ result: null
+- expression: false && null
+ result: false
+- expression: true || null
+ result: true
+- expression: null || true
+ result: true
+- expression: false || null
+ result: null
+- expression: '!null'
+ result: true
+- expression: intersects([], null)
+ result: false
+- expression: intersects(null, [])
+ result: false
+- expression: match(null, 'pattern')
+ result: null
+- expression: match('string', null)
+ result: false
+- expression: substr(null, 1, 4)
+ result: null
+- expression: substr('string', null, 4)
+ result: null
+- expression: substr('string', 1, null)
+ result: null
+- expression: min(null)
+ result: null
+- expression: max(null)
+ result: null
+- expression: length(null)
+ result: null
+- expression: type(null)
+ result: 'null'
+- expression: null == false
+ result: false
+- expression: null == true
+ result: false
+- expression: null != false
+ result: true
+- expression: null != true
+ result: true
+- expression: null != 1.5
+ result: true
+- expression: null == null
+ result: true
+- expression: null == 1
+ result: false
+- expression: '"VolumeTiming" in null'
+ result: null
+- expression: exists(null, "bids-uri")
+ result: 0
+- expression: exists([], null)
+ result: 0
+- expression: true || sidecar.MissingValue
+ result: true
+
+# General expressions
+- expression: 1 + 2
+ result: 3
+- expression: '"cat" + "dog"'
+ result: 'catdog'
+- expression: match('string', '.*')
+ result: true
+- expression: match('', '.')
+ result: false
+- expression: substr('string', 1, 4)
+ result: 'tri'
+- expression: substr('string', 0, 20)
+ result: 'string'
+- expression: type(1)
+ result: 'number'
+- expression: type([])
+ result: 'array'
+- expression: type({})
+ result: 'object'
+- expression: type(true)
+ result: 'boolean'
+- expression: intersects([1], [1, 2])
+ result: true
+- expression: intersects([1], [])
+ result: false
+- expression: length([1, 2, 3])
+ result: 3
+- expression: length([])
+ result: 0
+- expression: count([1, 2, 3], 1)
+ result: 1
+- expression: index(["i", "j", "k"], "i")
+ result: 0
+- expression: index(["i", "j", "k"], "j")
+ result: 1
+- expression: index(["i", "j", "k"], "x")
+ result: null
+- expression: sorted([3, 2, 1])
+ result: [1, 2, 3]
+- expression: min([-1, "n/a", 1])
+ result: -1
+- expression: max([-1, "n/a", 1])
+ result: 1
+- expression: '[3, 2, 1][0]'
+ result: 3
+- expression: '"string"[0]'
+ result: 's'
diff --git a/bep32v01/ressources/schema/meta/versions.yaml b/bep32v01/ressources/schema/meta/versions.yaml
new file mode 100644
index 00000000..06285c7e
--- /dev/null
+++ b/bep32v01/ressources/schema/meta/versions.yaml
@@ -0,0 +1,19 @@
+---
+# A list of released BIDS versions as of the next schema release
+- '1.9.0'
+- '1.8.0'
+- '1.7.0'
+- '1.6.0'
+- '1.5.0'
+- '1.4.1'
+- '1.4.0'
+- '1.3.0'
+- '1.2.2'
+- '1.2.1'
+- '1.2.0'
+- '1.1.2'
+- '1.1.1'
+- '1.1.0'
+- '1.0.2'
+- '1.0.1'
+- '1.0.0'
diff --git a/bep32v01/ressources/schema/objects/columns.yaml b/bep32v01/ressources/schema/objects/columns.yaml
new file mode 100644
index 00000000..bc11e7de
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/columns.yaml
@@ -0,0 +1,872 @@
+---
+HED:
+ name: HED
+ display_name: HED Tag
+ description: |
+ Hierarchical Event Descriptor (HED) Tag.
+ See the [HED Appendix](SPEC_ROOT/appendices/hed.md) for details.
+ type: string
+abbreviation:
+ name: abbreviation
+ display_name: Abbreviation
+ description: |
+ The unique label abbreviation
+ type: string
+acq_time__scans:
+ name: acq_time
+ display_name: Scan acquisition time
+ description: |
+ Acquisition time refers to when the first data point in each run was acquired.
+ Furthermore, if this header is provided, the acquisition times of all files
+ from the same recording MUST be identical.
+ Datetime format and their anonymization are described in
+ [Units](SPEC_ROOT/common-principles.md#units).
+ type: string
+ format: datetime
+acq_time__sessions:
+ name: acq_time
+ display_name: Session acquisition time
+ description: |
+ Acquisition time refers to when the first data point of the first run was acquired.
+ Datetime format and their anonymization are described in
+ [Units](SPEC_ROOT/common-principles.md#units).
+ type: string
+ format: datetime
+age:
+ name: age
+ display_name: Subject age
+ description: |
+ Numeric value in years (float or integer value).
+
+ It is recommended to tag participant ages that are 89 or higher as 89+,
+ for privacy purposes.
+ type: number
+ unit: year
+cardiac:
+ name: cardiac
+ display_name: Cardiac measurement
+ description: |
+ continuous pulse measurement
+ type: number
+channel:
+ name: channel
+ display_name: Channel
+ description: |
+ Channel(s) associated with an event.
+ If multiple channels are specified, they MUST be separated by a delimiter
+ specified in the `"Delimiter"` field describing the `channel` column.
+ For example, channels separated with a comma (`,`) require the `events.json`
+ file to contain `"channel": {"Delimiter": ","}`.
+ In the absence of a delimiter, tools MUST interpret any character as being part
+ of a channel name.
+ type: string
+color:
+ name: color
+ display_name: Color label
+ description: |
+ Hexadecimal. Label color for visualization.
+ type: string
+ unit: hexadecimal
+component:
+ name: component
+ display_name: Component
+ description: |
+ Description of the spatial axis or label of quaternion component associated with the channel.
+ For example, `x`,`y`,`z` for position channels,
+ or `quat_x`, `quat_y`, `quat_z`, `quat_w` for quaternion orientation channels.
+ type: string
+ enum:
+ - $ref: objects.enums.x.value
+ - $ref: objects.enums.y.value
+ - $ref: objects.enums.z.value
+ - $ref: objects.enums.quat_x.value
+ - $ref: objects.enums.quat_y.value
+ - $ref: objects.enums.quat_z.value
+ - $ref: objects.enums.quat_w.value
+ - n/a
+detector__channels:
+ name: detector
+ display_name: Detector Name
+ description: |
+ Name of the detector as specified in the `*_optodes.tsv` file.
+ `n/a` for channels that do not contain NIRS signals (for example, acceleration).
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+detector_type:
+ name: detector_type
+ display_name: Detector Type
+ description: |
+ The type of detector. Only to be used if the field `DetectorType` in `*_nirs.json` is set to `mixed`.
+ anyOf:
+ - type: string
+derived_from:
+ name: derived_from
+ display_name: Derived from
+ description: |
+ `sample-` entity from which a sample is derived,
+ for example a slice of tissue (`sample-02`) derived from a block of tissue (`sample-01`).
+ type: string
+ pattern: ^sample-[0-9a-zA-Z]+$
+description:
+ name: description
+ display_name: Description
+ description: |
+ Brief free-text description of the channel, or other information of interest.
+ type: string
+description__optode:
+ name: description
+ display_name: Description
+ description: |
+ Free-form text description of the optode, or other information of interest.
+ type: string
+dimension:
+ name: dimension
+ display_name: Dimension
+ description: |
+ Size of the group (grid/strip/probe) that this electrode belongs to.
+ Must be of form `[AxB]` with the smallest dimension first (for example, `[1x8]`).
+ type: string
+duration:
+ name: duration
+ display_name: Event duration
+ description: |
+ Duration of the event (measured from onset) in seconds.
+ Must always be either zero or positive (or `n/a` if unavailable).
+ A "duration" value of zero implies that the delta function or event is so
+ short as to be effectively modeled as an impulse.
+ anyOf:
+ - type: number
+ unit: s
+ minimum: 0
+ - type: string
+ enum:
+ - n/a
+filename:
+ name: filename
+ display_name: Filename
+ description: |
+ Relative paths to files.
+ type: string
+ format: participant_relative
+group__channel:
+ name: group
+ display_name: Channel group
+ description: |
+ Which group of channels (grid/strip/seeg/depth) this channel belongs to.
+ This is relevant because one group has one cable-bundle and noise can be shared.
+ This can be a name or number.
+ anyOf:
+ - type: string
+ - type: number
+handedness:
+ name: handedness
+ display_name: Subject handedness
+ description: |
+ String value indicating one of "left", "right", "ambidextrous".
+
+ For "left", use one of these values: `left`, `l`, `L`, `LEFT`, `Left`.
+
+ For "right", use one of these values: `right`, `r`, `R`, `RIGHT`, `Right`.
+
+ For "ambidextrous", use one of these values: `ambidextrous`, `a`, `A`, `AMBIDEXTROUS`,
+ `Ambidextrous`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - left
+ - l
+ - L
+ - LEFT
+ - Left
+ - right
+ - r
+ - R
+ - RIGHT
+ - Right
+ - ambidextrous
+ - a
+ - A
+ - AMBIDEXTROUS
+ - Ambidextrous
+ - n/a
+hemisphere:
+ name: hemisphere
+ display_name: Electrode hemisphere
+ description: |
+ The hemisphere in which the electrode is placed.
+ type: string
+ enum:
+ - $ref: objects.enums.left_hemisphere.value
+ - $ref: objects.enums.right_hemisphere.value
+high_cutoff:
+ name: high_cutoff
+ display_name: High cutoff
+ description: |
+ Frequencies used for the low-pass filter applied to the channel in Hz.
+ If no low-pass filter applied, use `n/a`.
+ Note that hardware anti-aliasing in A/D conversion of all MEG/EEG electronics
+ applies a low-pass filter; specify its frequency here if applicable.
+ anyOf:
+ - type: number
+ unit: Hz
+ minimum: 0
+ - type: string
+ enum:
+ - n/a
+hplc_recovery_fractions:
+ name: hplc_recovery_fractions
+ display_name: HPLC recovery fractions
+ description: |
+ HPLC recovery fractions (the fraction of activity that gets loaded onto the HPLC).
+ type: number
+ unit: arbitrary
+impedance:
+ name: impedance
+ display_name: Electrode impedance
+ description: |
+ Impedance of the electrode, units MUST be in `kOhm`.
+ type: number
+ unit: kOhm
+index:
+ name: index
+ display_name: Label index
+ description: |
+ The label integer index.
+ type: integer
+low_cutoff:
+ name: low_cutoff
+ display_name: Low cutoff
+ description: |
+ Frequencies used for the high-pass filter applied to the channel in Hz.
+ If no high-pass filter applied, use `n/a`.
+ anyOf:
+ - type: number
+ unit: Hz
+ - type: string
+ enum:
+ - n/a
+manufacturer:
+ name: manufacturer
+ display_name: Manufacturer
+ description: |
+ The manufacturer for each electrode.
+ Can be used if electrodes were manufactured by more than one company.
+ type: string
+mapping:
+ name: mapping
+ display_name: Label mapping
+ description: |
+ Corresponding integer label in the standard BIDS label lookup.
+ type: integer
+material:
+ name: material
+ display_name: Electrode material
+ description: |
+ Material of the electrode (for example, `Tin`, `Ag/AgCl`, `Gold`).
+ type: string
+metabolite_parent_fraction:
+ name: metabolite_parent_fraction
+ display_name: Metabolite parent fraction
+ description: |
+ Parent fraction of the radiotracer (0-1).
+ type: number
+ minimum: 0
+ maximum: 1
+metabolite_polar_fraction:
+ name: metabolite_polar_fraction
+ display_name: Metabolite polar fraction
+ description: |
+ Polar metabolite fraction of the radiotracer (0-1).
+ type: number
+ minimum: 0
+ maximum: 1
+# name column for channels.tsv files
+name__channels:
+ name: name
+ display_name: Channel name
+ description: |
+ Label of the channel.
+ type: string
+# name column for electrodes.tsv files
+name__electrodes:
+ name: name
+ display_name: Electrode name
+ description: |
+ Name of the electrode contact point.
+ type: string
+name__optodes:
+ name: name
+ display_name: Optode name
+ description: |
+ Name of the optode, must be unique.
+ type: string
+# name column for dseg.tsv files
+name__segmentations:
+ name: name
+ display_name: Label name
+ description: |
+ The unique label name.
+ type: string
+notch:
+ name: notch
+ display_name: Notch frequencies
+ description: |
+ Frequencies used for the notch filter applied to the channel, in Hz.
+ If notch filters are applied at multiple frequencies,
+ these frequencies MAY be specified as a list,
+ for example, `[60, 120, 180]`.
+ If no notch filter was applied, use `n/a`.
+ type: string
+onset:
+ name: onset
+ display_name: Event onset
+ description: |
+ Onset (in seconds) of the event, measured from the beginning of the acquisition
+ of the first data point stored in the corresponding task data file.
+ Negative onsets are allowed, to account for events that occur prior to the first
+ stored data point.
+ For example, in case there is an in-scanner training phase that begins before
+ the scanning sequence has started events from this sequence should have
+ negative onset time counting down to the beginning of the acquisition of the
+ first volume.
+
+ If any data points have been discarded before forming the data file
+ (for example, "dummy volumes" in BOLD fMRI),
+ a time of 0 corresponds to the first stored data point and not the first
+ acquired data point.
+ type: number
+ unit: s
+pathology:
+ name: pathology
+ display_name: Pathology
+ description: |
+ String value describing the pathology of the sample or type of control.
+ When different from `healthy`, pathology SHOULD be specified.
+ The pathology may be specified in either `samples.tsv` or
+ `sessions.tsv`, depending on whether the pathology changes over time.
+ type: string
+participant_id:
+ name: participant_id
+ display_name: Participant ID
+ description: |
+ A participant identifier of the form `sub-`,
+ matching a participant entity found in the dataset.
+ type: string
+ pattern: ^sub-[0-9a-zA-Z]+$
+placement__motion:
+ name: placement
+ display_name: Placement
+ description: |
+ Placement of the tracked point on the body (for example,
+ participant, avatar centroid, torso, left arm).
+ It can refer to an external vocabulary for describing body parts.
+ type: string
+plasma_radioactivity:
+ name: plasma_radioactivity
+ display_name: Plasma radioactivity
+ description: |
+ Radioactivity in plasma, in unit of plasma radioactivity (for example, `kBq/mL`).
+ type: number
+# reference column for channels.tsv files for EEG data
+reference__eeg:
+ name: reference
+ display_name: Electrode reference
+ description: |
+ Name of the reference electrode(s).
+ This column is not needed when it is common to all channels.
+ In that case the reference electrode(s) can be specified in `*_eeg.json` as `EEGReference`).
+ type: string
+# reference column for channels.tsv files for iEEG data
+reference__ieeg:
+ name: reference
+ display_name: Electrode reference
+ description: |
+ Specification of the reference (for example, `mastoid`, `ElectrodeName01`, `intracranial`, `CAR`, `other`, `n/a`).
+ If the channel is not an electrode channel (for example, a microphone channel) use `n/a`.
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+reference_frame:
+ name: reference_frame
+ display_name: Reference frame
+ description: |
+ Specification of a reference frame in which the motion data are to be interpreted.
+ The description of the levels in `*_channels.json` SHOULD use `RotationRule`,
+ `RotationOrder`, and `SpatialAxes`, and MAY use `Description` for the specification.
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+respiratory:
+ name: respiratory
+ display_name: Respiratory measurement
+ description: |
+ continuous breathing measurement
+ type: number
+response_time:
+ name: response_time
+ display_name: Response time
+ description: |
+ Response time measured in seconds.
+ A negative response time can be used to represent preemptive responses and
+ `n/a` denotes a missed response.
+ anyOf:
+ - type: number
+ unit: s
+ - type: string
+ enum:
+ - n/a
+sample_id:
+ name: sample_id
+ display_name: Sample ID
+ description: |
+ A sample identifier of the form `sample-`,
+ matching a sample entity found in the dataset.
+ type: string
+ pattern: ^sample-[0-9a-zA-Z]+$
+sample_type:
+ name: sample_type
+ display_name: Sample type
+ description: |
+ Biosample type defined by
+ [ENCODE Biosample Type](https://www.encodeproject.org/profiles/biosample_type).
+ type: string
+ enum:
+ - $ref: objects.enums.cell_line.value
+ - $ref: objects.enums.in_vitro_differentiated_cells.value
+ - $ref: objects.enums.primary_cell.value
+ - $ref: objects.enums.cell_free_sample.value
+ - $ref: objects.enums.cloning_host.value
+ - $ref: objects.enums.tissue.value
+ - $ref: objects.enums.whole_organisms.value
+ - $ref: objects.enums.organoid.value
+ - $ref: objects.enums.technical_sample.value
+sampling_frequency:
+ name: sampling_frequency
+ display_name: Channel sampling frequency
+ description: |
+ Sampling rate of the channel in Hz.
+ type: number
+ unit: Hz
+session_id:
+ name: session_id
+ display_name: Session ID
+ description: |
+ A session identifier of the form `ses-`,
+ matching a session found in the dataset.
+ type: string
+ pattern: ^ses-[0-9a-zA-Z]+$
+sex:
+ name: sex
+ display_name: Sex
+ description: |
+ String value indicating phenotypical sex, one of "male", "female", "other".
+
+ For "male", use one of these values: `male`, `m`, `M`, `MALE`, `Male`.
+
+ For "female", use one of these values: `female`, `f`, `F`, `FEMALE`, `Female`.
+
+ For "other", use one of these values: `other`, `o`, `O`, `OTHER`, `Other`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - male
+ - m
+ - M
+ - MALE
+ - Male
+ - female
+ - f
+ - F
+ - FEMALE
+ - Female
+ - other
+ - o
+ - O
+ - OTHER
+ - Other
+ - n/a
+short_channel:
+ name: short_channel
+ display_name: Short Channel
+ description: |
+ Is the channel designated as short.
+ The total number of channels listed as short channels
+ SHOULD be stored in `ShortChannelCount` in `*_nirs.json`.
+ type: boolean
+size:
+ name: size
+ display_name: Electrode size
+ description: |
+ Surface area of the electrode, units MUST be in `mm^2`.
+ type: number
+ unit: 'mm^2'
+software_filters:
+ name: software_filters
+ display_name: Software filters
+ description: |
+ List of temporal and/or spatial software filters applied
+ (for example, `SSS`, `SpatialCompensation`).
+ Note that parameters should be defined in the general MEG sidecar .json file.
+ Indicate `n/a` in the absence of software filters applied.
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+source__channels:
+ name: source
+ display_name: Source name
+ description: |
+ Name of the source as specified in the `*_optodes.tsv` file.
+ `n/a` for channels that do not contain fNIRS signals (for example, acceleration).
+ anyOf:
+ - type: string
+ - type: string
+ enum:
+ - n/a
+source__optodes:
+ name: source_type
+ display_name: Source type
+ description: |
+ The type of source. Only to be used if the field `SourceType` in `*_nirs.json` is set to `mixed`.
+ anyOf:
+ - type: string
+species:
+ name: species
+ display_name: Species
+ description: |
+ The `species` column SHOULD be a binomial species name from the
+ [NCBI Taxonomy](https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi)
+ (for example, `homo sapiens`, `mus musculus`, `rattus norvegicus`).
+ For backwards compatibility, if `species` is absent, the participant is assumed to be
+ `homo sapiens`.
+ type: string
+status:
+ name: status
+ display_name: Channel status
+ description: |
+ Data quality observed on the channel.
+ A channel is considered `bad` if its data quality is compromised by excessive noise.
+ If quality is unknown, then a value of `n/a` may be used.
+ Description of noise type SHOULD be provided in `[status_description]`.
+ type: string
+ enum:
+ - $ref: objects.enums.good.value
+ - $ref: objects.enums.bad.value
+ - n/a
+status_description:
+ name: status_description
+ display_name: Channel status description
+ description: |
+ Freeform text description of noise or artifact affecting data quality on the channel.
+ It is meant to explain why the channel was declared bad in the `status` column.
+ type: string
+stim_file:
+ name: stim_file
+ display_name: Stimulus file
+ description: |
+ Represents the location of the stimulus file (such as an image, video, or
+ audio file) presented at the given onset time.
+ There are no restrictions on the file formats of the stimuli files,
+ but they should be stored in the `/stimuli` directory
+ (under the root directory of the dataset; with optional subdirectories).
+ The values under the `stim_file` column correspond to a path relative to
+ `/stimuli`.
+ For example `images/cat03.jpg` will be translated to `/stimuli/images/cat03.jpg`.
+ type: string
+ format: stimuli_relative
+strain:
+ name: strain
+ display_name: Strain
+ description: |
+ For species different from `homo sapiens`, string value indicating
+ the strain of the species, for example: `C57BL/6J`.
+ type: string
+strain_rrid:
+ name: strain_rrid
+ display_name: Strain RRID
+ description: |
+ For species different from `homo sapiens`, research resource identifier
+ ([RRID](https://scicrunch.org/resources/data/source/nlx_154697-1/search))
+ of the strain of the species, for example: `RRID:IMSR_JAX:000664`.
+ type: string
+ format: rrid
+time:
+ name: time
+ display_name: Time
+ description: |
+ Time, in seconds, relative to `TimeZero` defined by the `*_pet.json`.
+ For example, 5.
+ type: number
+ unit: s
+tracked_point__channels:
+ name: tracked_point
+ display_name: Tracked point channel
+ description: |
+ Label of the point that is being tracked, for example, label of a tracker
+ or a marker (for example,`"LeftFoot"`, `"RightWrist"`).
+ type: string
+trial_type:
+ name: trial_type
+ display_name: Trial type
+ description: |
+ Primary categorisation of each trial to identify them as instances of the
+ experimental conditions.
+ For example: for a response inhibition task, it could take on values `go` and
+ `no-go` to refer to response initiation and response inhibition experimental
+ conditions.
+ type: string
+trigger:
+ name: trigger
+ display_name: Trigger
+ description: |
+ continuous measurement of the scanner trigger signal
+ type: number
+# type column in channels.tsv files
+type__channels:
+ name: type
+ display_name: Channel type
+ description: |
+ Type of channel; MUST use the channel types listed below.
+ Note that the type MUST be in upper-case.
+ type: string
+ enum:
+ - $ref: objects.enums.ACCEL.value
+ - $ref: objects.enums.ADC.value
+ - $ref: objects.enums.ANGACCEL.value
+ - $ref: objects.enums.AUDIO.value
+ - $ref: objects.enums.DAC.value
+ - $ref: objects.enums.DBS.value
+ - $ref: objects.enums.ECG.value
+ - $ref: objects.enums.ECOG.value
+ - $ref: objects.enums.EEG.value
+ - $ref: objects.enums.EMG.value
+ - $ref: objects.enums.EOG.value
+ - $ref: objects.enums.EYEGAZE.value
+ - $ref: objects.enums.FITERR.value
+ - $ref: objects.enums.GSR.value
+ - $ref: objects.enums.GYRO.value
+ - $ref: objects.enums.HEOG.value
+ - $ref: objects.enums.HLU.value
+ - $ref: objects.enums.JNTANG.value
+ - $ref: objects.enums.LATENCY.value
+ - $ref: objects.enums.MAGN.value
+ - $ref: objects.enums.MEGGRADAXIAL.value
+ - $ref: objects.enums.MEGGRADPLANAR.value
+ - $ref: objects.enums.MEGMAG.value
+ - $ref: objects.enums.MEGOTHER.value
+ - $ref: objects.enums.MEGREFGRADAXIAL.value
+ - $ref: objects.enums.MEGREFGRADPLANAR.value
+ - $ref: objects.enums.MEGREFMAG.value
+ - $ref: objects.enums.MISC.value
+ - $ref: objects.enums.NIRSCWAMPLITUDE.value
+ - $ref: objects.enums.NIRSCWFLUORESCENSEAMPLITUDE.value
+ - $ref: objects.enums.NIRSCWHBO.value
+ - $ref: objects.enums.NIRSCWHBR.value
+ - $ref: objects.enums.NIRSCWMUA.value
+ - $ref: objects.enums.NIRSCWOPTICALDENSITY.value
+ - $ref: objects.enums.ORNT.value
+ - $ref: objects.enums.OTHER.value
+ - $ref: objects.enums.PD.value
+ - $ref: objects.enums.POS.value
+ - $ref: objects.enums.PPG.value
+ - $ref: objects.enums.PUPIL.value
+ - $ref: objects.enums.REF.value
+ - $ref: objects.enums.RESP.value
+ - $ref: objects.enums.SEEG.value
+ - $ref: objects.enums.SYSCLOCK.value
+ - $ref: objects.enums.TEMP.value
+ - $ref: objects.enums.TRIG.value
+ - $ref: objects.enums.VEL.value
+ - $ref: objects.enums.VEOG.value
+# type column for electrodes.tsv files
+type__electrodes:
+ name: type
+ display_name: Electrode type
+ description: |
+ Type of the electrode (for example, cup, ring, clip-on, wire, needle).
+ type: string
+type__optodes:
+ name: type
+ display_name: Type
+ description: |
+ The type of the optode.
+ type: string
+ enum:
+ - $ref: objects.enums.source.value
+ - $ref: objects.enums.detector.value
+ - n/a
+units:
+ name: units
+ display_name: Units
+ description: |
+ Physical unit of the value represented in this channel,
+ for example, `V` for Volt, or `fT/cm` for femto Tesla per centimeter
+ (see [Units](SPEC_ROOT/common-principles.md#units)).
+ type: string
+ format: unit
+units__nirs:
+ name: units
+ display_name: Units
+ description: |
+ Physical unit of the value represented in this channel,
+ specified according to the SI unit symbol and possibly prefix symbol,
+ or as a derived SI unit (for example, `V`, or unitless for changes in optical densities).
+ For guidelines about units see the [Appendix](SPEC_ROOT/appendices/units.md)
+ and [Common Principles](SPEC_ROOT/common-principles.md#units) pages.
+ type: string
+ format: unit
+units__motion:
+ name: units
+ display_name: Units
+ description: |
+ Physical or virtual unit of the value represented in this channel,
+ for example, '"rad"' or '"deg"' for angular quantities or '"m"' for position data.
+ If motion data is recorded in a virtual space and deviate from standard SI units,
+ the unit used MUST be specified in the sidecar `*_motion.json`
+ file (for example `"vm"` for virtual meters). `"rad"` is used for Euler angles
+ and `"n/a"` for quaternions.
+ For guidelines about units see the [Appendix](SPEC_ROOT/appendices/units.md)
+ and [Common Principles](SPEC_ROOT/common-principles.md#units) pages.
+ type: string
+ format: unit
+volume_type:
+ name: volume_type
+ display_name: ASL volume type
+ description: |
+ The `*_aslcontext.tsv` table consists of a single column of labels identifying
+ the `volume_type` of each volume in the corresponding `*_asl.nii[.gz]` file.
+ type: string
+ enum:
+ - $ref: objects.enums.control.value
+ - $ref: objects.enums.label.value
+ - $ref: objects.enums.m0scan.value
+ - $ref: objects.enums.deltam.value
+ - $ref: objects.enums.cbf.value
+wavelength_nominal:
+ name: wavelength_nominal
+ display_name: Wavelength nominal
+ description: |
+ Specified wavelength of light in nm.
+ `n/a` for channels that do not contain raw NIRS signals (for example, acceleration).
+ This field is equivalent to `/nirs(i)/probe/wavelengths` in the SNIRF specification.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+wavelength_actual:
+ name: wavelength_actual
+ display_name: Wavelength actual
+ description: |
+ Measured wavelength of light in nm.
+ `n/a` for channels that do not contain raw NIRS signals (acceleration).
+ This field is equivalent to `measurementList.wavelengthActual` in the SNIRF specification.
+ type: number
+wavelength_emission_actual:
+ name: wavelength_emission_actual
+ display_name: Wavelength emission actual
+ description: |
+ Measured emission wavelength of light in nm.
+ `n/a` for channels that do not contain raw NIRS signals (acceleration).
+ This field is equivalent to `measurementList.wavelengthEmissionActual` in the SNIRF specification.
+ type: number
+whole_blood_radioactivity:
+ name: whole_blood_radioactivity
+ display_name: Whole blood radioactivity
+ description: |
+ Radioactivity in whole blood samples,
+ in unit of radioactivity measurements in whole blood samples (for example, `kBq/mL`).
+ type: number
+x:
+ name: x
+ display_name: X position
+ description: |
+ Recorded position along the x-axis.
+ type: number
+y:
+ name: y
+ display_name: Y position
+ description: |
+ Recorded position along the y-axis.
+ type: number
+z:
+ name: z
+ display_name: Z position
+ description: |
+ Recorded position along the z-axis.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+x__optodes:
+ name: x
+ display_name: X position
+ description: |
+ Recorded position along the x-axis.
+ `"n/a"` if not available.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+y__optodes:
+ name: y
+ display_name: Y position
+ description: |
+ Recorded position along the y-axis.
+ `"n/a"` if not available.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+z__optodes:
+ name: z
+ display_name: Z position
+ description: |
+ Recorded position along the z-axis.
+ `"n/a"` if not available.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+template_x:
+ name: template_x
+ display_name: X template position
+ description: |
+ Assumed or ideal position along the x axis.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+template_y:
+ name: template_y
+ display_name: Y template position
+ description: |
+ Assumed or ideal position along the y axis.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+template_z:
+ name: template_z
+ display_name: Z template position
+ description: |
+ Assumed or ideal position along the z axis.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
diff --git a/bep32v01/ressources/schema/objects/common_principles.yaml b/bep32v01/ressources/schema/objects/common_principles.yaml
new file mode 100644
index 00000000..7e669efb
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/common_principles.yaml
@@ -0,0 +1,156 @@
+---
+# This file describes terms defined in the specification as "Common Principles".
+# WARNING: The terms are presented here in alphabetical order!
+# The order in which these terms are presented in the specification is defined in `rules/common_principles.yaml`,
+# rather than this file (`objects/common_principles.yaml`).
+data_acquisition:
+ display_name: Data acquisition
+ description: |
+ A continuous uninterrupted block of time during which a brain scanning instrument was acquiring data according to
+ particular scanning sequence/protocol.
+data_type:
+ display_name: Data type
+ description: |
+ A functional group of different types of data.
+ Data files are contained in a directory named for the data type.
+ In raw datasets, the data type directory is nested inside subject and (optionally) session directories.
+ BIDS defines the following data types:
+
+ 1. `func` (task based and resting state functional MRI)
+
+ 2. `dwi` (diffusion weighted imaging)
+
+ 3. `fmap` (field inhomogeneity mapping data such as field maps)
+
+ 4. `anat` (structural imaging such as T1, T2, PD, and so on)
+
+ 5. `perf` (perfusion)
+
+ 6. `meg` (magnetoencephalography)
+
+ 7. `eeg` (electroencephalography)
+
+ 8. `ieeg` (intracranial electroencephalography)
+
+ 9. `beh` (behavioral)
+
+ 10. `pet` (positron emission tomography)
+
+ 11. `micr` (microscopy)
+
+ 12. `nirs` (near infrared spectroscopy)
+
+ 13. `motion` (motion)
+dataset:
+ display_name: Dataset
+ description: |
+ A set of neuroimaging and behavioral data acquired for a purpose of a particular study.
+ A dataset consists of data acquired from one or more subjects, possibly from multiple sessions.
+deprecated:
+ display_name: DEPRECATED
+ description: |
+ A "deprecated" entity or metadata field SHOULD NOT be used in the generation of new datasets.
+ It remains in the standard in order to preserve the interpretability of existing datasets.
+ Validating software SHOULD warn when deprecated practices are detected
+ and provide a suggestion for updating the dataset to preserve the curator's intent.
+event:
+ display_name: Event
+ description: |
+ Something that happens or may be perceived by a test subject as happening
+ at a particular instant during the recording.
+ Events are most commonly associated with on- or offset of stimulus presentations,
+ or with the distinct marker of on- or offset of a subject's response or motor action.
+ Other events may include unplanned incidents
+ (for example, sudden onset of noise and vibrations due to construction work,
+ laboratory device malfunction),
+ changes in task instructions (for example, switching the response hand),
+ or experiment control parameters (for example, changing the stimulus presentation rate over experimental blocks),
+ and noted data feature occurrences (for example, a recording electrode producing noise).
+ In BIDS, each event has an onset time and duration.
+ Note that not all tasks will have recorded events (for example, "resting state").
+extension:
+ display_name: File extension
+ description: |
+ A portion of the filename after the left-most period (`.`) preceded by any other alphanumeric.
+ For example, `.gitignore` does not have a file extension,
+ but the file extension of `test.nii.gz` is `.nii.gz`.
+ Note that the left-most period is included in the file extension.
+index:
+ display_name: index
+ description: |
+ A nonnegative integer, possibly prefixed with arbitrary number of 0s for consistent indentation,
+ for example, it is `01` in `run-01` following `run-` specification.
+label:
+ display_name: label
+ description: |
+ An alphanumeric value, possibly prefixed with arbitrary number of 0s for consistent indentation,
+ for example, it is `rest` in `task-rest` following `task-` specification.
+ Note that labels MUST not collide when casing is ignored
+ (see [Case collision intolerance](SPEC_ROOT/common-principles.md#case-collision-intolerance)).
+modality:
+ display_name: Modality
+ description: |
+ The category of brain data recorded by a file.
+ For MRI data, different pulse sequences are considered distinct modalities,
+ such as `T1w`, `bold` or `dwi`.
+ For passive recording techniques, such as EEG, MEG or iEEG,
+ the technique is sufficiently uniform to define the modalities `eeg`, `meg` and `ieeg`.
+ When applicable, the modality is indicated in the **suffix**.
+ The modality may overlap with, but should not be confused with the **data type**.
+run:
+ display_name: Run
+ description: |
+ An uninterrupted repetition of data acquisition that has the same acquisition parameters and task
+ (however events can change from run to run due to different subject response
+ or randomized nature of the stimuli).
+ Run is a synonym of a data acquisition.
+ Note that "uninterrupted" may look different by modality due to the nature of the recording.
+ For example, in [MRI](SPEC_ROOT/modality-specific-files/magnetic-resonance-imaging-data.md)
+ or [MEG](SPEC_ROOT/modality-specific-files/magnetoencephalography.md),
+ if a subject leaves the scanner, the acquisition must be restarted.
+ For some types of [PET](SPEC_ROOT/modality-specific-files/positron-emission-tomography.md) acquisitions,
+ a subject may leave and re-enter the scanner without interrupting the scan.
+sample:
+ display_name: Sample
+ description: |
+ A sample pertaining to a subject such as tissue, primary cell or cell-free sample.
+ Sample labels MUST be unique within a subject and it is RECOMMENDED
+ that they be unique throughout the dataset.
+session:
+ display_name: Session
+ description: |
+ A logical grouping of neuroimaging and behavioral data consistent across subjects.
+ Session can (but doesn't have to) be synonymous to a visit in a longitudinal study.
+ In general, subjects will stay in the scanner during one session.
+ However, for example, if a subject has to leave the scanner room
+ and then be re-positioned on the scanner bed,
+ the set of MRI acquisitions will still be considered as a session
+ and match sessions acquired in other subjects.
+ Similarly, in situations where different data types are obtained over several visits
+ (for example fMRI on one day followed by DWI the day after) those can be grouped in one session.
+ Defining multiple sessions is appropriate when several identical or similar data acquisitions
+ are planned and performed on all -or most- subjects,
+ often in the case of some intervention between sessions (for example, training).
+ In the [PET](SPEC_ROOT/modality-specific-files/positron-emission-tomography.md) context,
+ a session may also indicate a group of related scans, taken in one or more visits.
+suffix:
+ display_name: suffix
+ description: |
+ An alphanumeric string that forms part of a filename, located after all
+ [entities](SPEC_ROOT/common-principles.md#entities) and
+ following a final `_`, right before the **file extension**;
+ for example, it is `eeg` in `sub-05_task-matchingpennies_eeg.vhdr`.
+subject:
+ display_name: Subject
+ description: |
+ A person or animal participating in the study.
+ Used interchangeably with term **Participant**.
+task:
+ display_name: Task
+ description: |
+ A set of structured activities performed by the participant.
+ Tasks are usually accompanied by stimuli and responses, and can greatly vary in complexity.
+ For the purpose of this specification we consider the so-called "resting state" a task.
+ In the context of brain scanning, a task is always tied to one data acquisition.
+ Therefore, even if during one acquisition the subject performed multiple conceptually different behaviors
+ (with different sets of instructions) they will be considered one (combined) task.
diff --git a/bep32v01/ressources/schema/objects/datatypes.yaml b/bep32v01/ressources/schema/objects/datatypes.yaml
new file mode 100644
index 00000000..c51fa413
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/datatypes.yaml
@@ -0,0 +1,63 @@
+---
+# This file defines valid BIDS datatypes, along with their full names and descriptions.
+# For rules regarding how suffixes relate to datatypes, see files in `rules/files/raw/`.
+anat:
+ value: anat
+ display_name: Anatomical Magnetic Resonance Imaging
+ description: |
+ Magnetic resonance imaging sequences designed to characterize static, anatomical features.
+beh:
+ value: beh
+ display_name: Behavioral Data
+ description: |
+ Behavioral data.
+dwi:
+ value: dwi
+ display_name: Diffusion-Weighted Imaging
+ description: |
+ Diffusion-weighted imaging (DWI).
+eeg:
+ value: eeg
+ display_name: Electroencephalography
+ description: Electroencephalography
+fmap:
+ value: fmap
+ display_name: Field maps
+ description: |
+ MRI scans for estimating B0 inhomogeneity-induced distortions.
+func:
+ value: func
+ display_name: Task-Based Magnetic Resonance Imaging
+ description: |
+ Task (including resting state) imaging data
+ieeg:
+ value: ieeg
+ display_name: Intracranial electroencephalography
+ description: |
+ Intracranial electroencephalography (iEEG) or electrocorticography (ECoG) data
+meg:
+ value: meg
+ display_name: Magnetoencephalography
+ description: Magnetoencephalography
+micr:
+ value: micr
+ display_name: Microscopy
+ description: Microscopy
+motion:
+ value: motion
+ display_name: Motion
+ description: Motion data from a tracking system
+perf:
+ value: perf
+ display_name: Perfusion imaging
+ description: |
+ Blood perfusion imaging data, including arterial spin labeling (ASL)
+pet:
+ value: pet
+ display_name: Positron Emission Tomography
+ description: |
+ Positron emission tomography data
+nirs:
+ value: nirs
+ display_name: Near-Infrared Spectroscopy
+ description: Near-Infrared Spectroscopy data organized around the SNIRF format
diff --git a/bep32v01/ressources/schema/objects/entities.yaml b/bep32v01/ressources/schema/objects/entities.yaml
new file mode 100644
index 00000000..6facc34c
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/entities.yaml
@@ -0,0 +1,424 @@
+---
+# This file describes entities present in BIDS filenames.
+# WARNING: The entities are presented here in alphabetical order!
+# The appropriate order of entities in filenames is defined in `rules/entities.yaml`,
+# rather than this file (`objects/entities.yaml`).
+acquisition:
+ name: acq
+ display_name: Acquisition
+ description: |
+ The `acq-` entity corresponds to a custom label the user MAY use to distinguish
+ a different set of parameters used for acquiring the same modality.
+
+ For example, this should be used when a study includes two T1w images -
+ one full brain low resolution and one restricted field of view but high resolution.
+ In such case two files could have the following names:
+ `sub-01_acq-highres_T1w.nii.gz` and `sub-01_acq-lowres_T1w.nii.gz`;
+ however, the user is free to choose any other label than `highres` and `lowres` as long
+ as they are consistent across subjects and sessions.
+
+ In case different sequences are used to record the same modality
+ (for example, `RARE` and `FLASH` for T1w)
+ this field can also be used to make that distinction.
+ The level of detail at which the distinction is made
+ (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: ce
+ display_name: Contrast Enhancing Agent
+ description: |
+ The `ce-` entity can be used to distinguish sequences using different contrast enhanced images.
+ The label is the name of the contrast agent.
+
+ This entity represents the `"ContrastBolusIngredient"` metadata field.
+ Therefore, if the `ce-` entity is present in a filename,
+ `"ContrastBolusIngredient"` MAY also be added in the JSON file, with the same label.
+ type: string
+ format: label
+chunk:
+ name: chunk
+ display_name: Chunk
+ description: |
+ The `chunk-` key/value pair is used to distinguish between images of
+ the same physical sample with different fields of view acquired in the same
+ imaging experiment.
+ This entity applies to collections of 2D images, 3D volumes or 4D volume series
+ (for example, diffusion weighted images), and may be used to indicate different
+ anatomical structures or regions of the same structure.
+ type: string
+ format: index
+density:
+ name: den
+ display_name: Density
+ description: |
+ Density of non-parametric surfaces.
+
+ This entity represents the `"Density"` metadata field.
+ Therefore, if the `den-` entity is present in a filename,
+ `"Density"` MUST also be added in the JSON file, to provide interpretation.
+
+ This entity is only applicable to derivative data.
+ type: string
+ format: label
+description:
+ name: desc
+ display_name: Description
+ description: |
+ When necessary to distinguish two files that do not otherwise have a
+ distinguishing entity, the `desc-` entity SHOULD be used.
+
+ This entity is only applicable to derivative data.
+ type: string
+ format: label
+direction:
+ name: dir
+ display_name: Phase-Encoding Direction
+ description: |
+ The `dir-` entity can be set to an arbitrary alphanumeric label
+ (for example, `dir-LR` or `dir-AP`)
+ to distinguish different phase-encoding directions.
+
+ This entity represents the `"PhaseEncodingDirection"` metadata field.
+ Therefore, if the `dir-` entity is present in a filename,
+ `"PhaseEncodingDirection"` MUST be defined in the associated metadata.
+ Please note that the `` does not need to match the actual value of the field.
+ type: string
+ format: label
+echo:
+ name: echo
+ display_name: Echo
+ description: |
+ If files belonging to an entity-linked file collection are acquired at different
+ echo times, the `echo-` entity MUST be used to distinguish individual files.
+
+ This entity represents the `"EchoTime"` metadata field.
+ Therefore, if the `echo-` entity is present in a filename,
+ `"EchoTime"` MUST be defined in the associated metadata.
+ Please note that the `` denotes the number/index (in the form of a nonnegative integer),
+ not the `"EchoTime"` value of the separate JSON file.
+ type: string
+ format: index
+flip:
+ name: flip
+ display_name: Flip Angle
+ description: |
+ If files belonging to an entity-linked file collection are acquired at different
+ flip angles, the `_flip-` entity pair MUST be used to distinguish
+ individual files.
+
+ This entity represents the `"FlipAngle"` metadata field.
+ Therefore, if the `flip-` entity is present in a filename,
+ `"FlipAngle"` MUST be defined in the associated metadata.
+ Please note that the `` denotes the number/index (in the form of a nonnegative integer),
+ not the `"FlipAngle"` value of the separate JSON file.
+ type: string
+ format: index
+hemisphere:
+ name: hemi
+ display_name: Hemisphere
+ description: |
+ The `hemi-` entity indicates which hemibrain is described by the file.
+ Allowed label values for this entity are `L` and `R`, for the left and right
+ hemibrains, respectively.
+ type: string
+ format: label
+ enum:
+ - $ref: objects.enums.left_hemisphere.value
+ - $ref: objects.enums.right_hemisphere.value
+inversion:
+ name: inv
+ display_name: Inversion Time
+ description: |
+ If files belonging to an entity-linked file collection are acquired at different inversion times,
+ the `inv-` entity MUST be used to distinguish individual files.
+
+ This entity represents the `"InversionTime` metadata field.
+ Therefore, if the `inv-` entity is present in a filename,
+ `"InversionTime"` MUST be defined in the associated metadata.
+ Please note that the `` denotes the number/index (in the form of a nonnegative integer),
+ not the `"InversionTime"` value of the separate JSON file.
+ type: string
+ format: index
+label:
+ name: label
+ display_name: Label
+ description: |
+ Tissue-type label, following a prescribed vocabulary.
+ Applies to binary masks and probabilistic/partial volume segmentations
+ that describe a single tissue type.
+
+ This entity is only applicable to derivative data.
+ type: string
+ format: label
+modality:
+ name: mod
+ display_name: Corresponding Modality
+ description: |
+ The `mod-` entity 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
+mtransfer:
+ name: mt
+ display_name: Magnetization Transfer
+ description: |
+ If files belonging to an entity-linked file collection are acquired at different
+ magnetization transfer (MT) states, the `_mt-` entity MUST be used to
+ distinguish individual files.
+
+ This entity represents the `"MTState"` metadata field.
+ Therefore, if the `mt-` entity is present in a filename,
+ `"MTState"` MUST be defined in the associated metadata.
+ Allowed label values for this entity are `on` and `off`,
+ for images acquired in presence and absence of an MT pulse, respectively.
+ type: string
+ format: label
+ enum:
+ - $ref: objects.enums.on__mtransfer.value
+ - $ref: objects.enums.off__mtransfer.value
+part:
+ name: part
+ display_name: Part
+ description: |
+ This entity is used to indicate which component of the complex
+ representation of the MRI signal is represented in voxel data.
+ The `part-` entity is associated with the DICOM Tag
+ `0008, 9208`.
+ Allowed label values for this entity are `phase`, `mag`, `real` and `imag`,
+ which are typically used in `part-mag`/`part-phase` or
+ `part-real`/`part-imag` pairs of files.
+
+ Phase images MAY be in radians or in arbitrary units.
+ The sidecar JSON file MUST include the `"Units"` of the `phase` image.
+ The possible options are `"rad"` or `"arbitrary"`.
+
+ When there is only a magnitude image of a given type, the `part` entity MAY be
+ omitted.
+ type: string
+ format: label
+ enum:
+ - $ref: objects.enums.magnitude.value
+ - $ref: objects.enums.phase.value
+ - $ref: objects.enums.real.value
+ - $ref: objects.enums.imaginary.value
+processing:
+ name: proc
+ display_name: Processed (on device)
+ description: |
+ The proc label is analogous to rec for MR and denotes a variant of
+ a file that was a result of particular processing performed on the device.
+
+ This is useful for files produced in particular by Neuromag/Elekta/MEGIN's
+ MaxFilter (for example, `sss`, `tsss`, `trans`, `quat` or `mc`),
+ 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
+reconstruction:
+ name: rec
+ display_name: Reconstruction
+ description: |
+ The `rec-` entity can be used to distinguish different reconstruction algorithms
+ (for example, `MoCo` for the ones using motion correction).
+ type: string
+ format: label
+recording:
+ name: recording
+ display_name: Recording
+ description: |
+ The `recording-` entity can be used to distinguish continuous recording files.
+
+ This entity is commonly applied when continuous recordings have different sampling frequencies or start times.
+ For example, physiological recordings with different sampling frequencies may be distinguished using
+ labels like `recording-100Hz` and `recording-500Hz`.
+ type: string
+ format: label
+resolution:
+ name: res
+ display_name: Resolution
+ description: |
+ Resolution of regularly sampled N-dimensional data.
+
+ This entity represents the `"Resolution"` metadata field.
+ Therefore, if the `res-` entity is present in a filename,
+ `"Resolution"` MUST also be added in the JSON file, to provide interpretation.
+
+ This entity is only applicable to derivative data.
+ type: string
+ format: label
+run:
+ name: run
+ display_name: Run
+ description: |
+ The `run-` entity is used to distinguish separate data acquisitions with the same acquisition parameters
+ and (other) entities.
+
+ If several data acquisitions (for example, MRI scans or EEG recordings)
+ with the same acquisition parameters are acquired in the same session,
+ they MUST be indexed with the [`run-`](SPEC_ROOT/appendices/entities.md#run) entity:
+ `_run-1`, `_run-2`, `_run-3`, and so on
+ (only nonnegative integers are allowed as run indices).
+
+ If different entities apply,
+ such as a different session indicated by [`ses-`][SPEC_ROOT/appendices/entities.md#ses),
+ or different acquisition parameters indicated by
+ [`acq-`](SPEC_ROOT/appendices/entities.md#acq),
+ then `run` is not needed to distinguish the scans and MAY be omitted.
+ type: string
+ format: index
+sample:
+ name: sample
+ display_name: Sample
+ description: |
+ A sample pertaining to a subject such as tissue, primary cell or cell-free sample.
+ The `sample-` entity is used to distinguish between different samples from the same subject.
+ The label MUST be unique per subject and is RECOMMENDED to be unique throughout the dataset.
+ type: string
+ format: label
+segmentation:
+ name: seg
+ display_name: Segmentation
+ description: |
+ The `seg-` key/value pair corresponds to a custom label the user
+ MAY use to distinguish different segmentations.
+
+ This entity is only applicable to derivative data.
+ type: string
+ format: label
+session:
+ name: ses
+ display_name: Session
+ description: |
+ A logical grouping of neuroimaging and behavioral data consistent across subjects.
+ Session can (but doesn't have to) be synonymous to a visit in a longitudinal study.
+ In general, subjects will stay in the scanner during one session.
+ However, for example, if a subject has to leave the scanner room and then
+ be re-positioned on the scanner bed, the set of MRI acquisitions will still
+ be considered as a session and match sessions acquired in other subjects.
+ Similarly, in situations where different data types are obtained over
+ several visits (for example fMRI on one day followed by DWI the day after)
+ those can be grouped in one session.
+
+ Defining multiple sessions is appropriate when several identical or similar
+ 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
+space:
+ name: space
+ display_name: Space
+ description: |
+ The `space-` entity can be used to indicate the way in which electrode positions are interpreted
+ (for EEG/MEG/iEEG data)
+ or the spatial reference to which a file has been aligned (for MRI data).
+ The `` MUST be taken from one of the modality specific lists in the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md).
+ For example, for iEEG data, the restricted keywords listed under
+ [iEEG Specific Coordinate Systems](SPEC_ROOT/appendices/coordinate-systems.md#ieeg-specific-coordinate-systems)
+ are acceptable for ``.
+
+ 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
+ display_name: Split
+ description: |
+ In the case of long data recordings that exceed a file size of 2Gb,
+ `.fif` files are conventionally split into multiple parts.
+ Each of these files has an internal pointer to the next file.
+ This is important when renaming these split recordings to the BIDS convention.
+
+ Instead of a simple renaming, files should be read in and saved under their
+ new names with dedicated tools like [MNE-Python](https://mne.tools/),
+ which will ensure that not only the filenames, but also the internal file pointers, will be updated.
+
+ It is RECOMMENDED that `.fif` files with multiple parts use the `split-` entity to indicate each part.
+ If there are multiple parts of a recording and the optional `scans.tsv` is provided,
+ all files MUST be listed separately in `scans.tsv` and
+ the entries for the `acq_time` column in `scans.tsv` MUST all be identical,
+ as described in [Scans file](SPEC_ROOT/modality-agnostic-files.md#scans-file).
+ type: string
+ format: index
+stain:
+ name: stain
+ display_name: Stain
+ description: |
+ The `stain-` key/pair values can be used to distinguish image files
+ from the same sample using different stains or antibodies for contrast enhancement.
+
+ This entity represents the `"SampleStaining"` metadata field.
+ Therefore, if the `stain-` entity is present in a filename,
+ `"SampleStaining"` SHOULD be defined in the associated metadata,
+ although the label may be different.
+
+ Descriptions of antibodies SHOULD also be indicated in the `"SamplePrimaryAntibodies"`
+ and/or `"SampleSecondaryAntibodies"` metadata fields, as appropriate.
+ type: string
+ format: label
+subject:
+ name: sub
+ display_name: Subject
+ description: |
+ A person or animal participating in the study.
+ type: string
+ format: label
+task:
+ name: task
+ display_name: Task
+ description: |
+ A set of structured activities performed by the participant.
+ Tasks are usually accompanied by stimuli and responses, and can greatly vary in complexity.
+
+ In the context of brain scanning, a task is always tied to one data acquisition.
+ Therefore, even if during one acquisition the subject performed multiple conceptually different behaviors
+ (with different sets of instructions) they will be considered one (combined) task.
+
+ While tasks may be repeated across multiple acquisitions,
+ a given task may have different sets of stimuli (for example, randomized order) and participant responses
+ across subjects, sessions, and runs.
+
+ The `task-` MUST be consistent across subjects and sessions.
+
+ Files with the `task-` entity SHOULD have an associated
+ [events file](SPEC_ROOT/modality-specific-files/task-events.md#task-events),
+ as well as certain metadata fields in the associated JSON file.
+
+ For the purpose of this specification we consider the so-called "resting state" a task,
+ although events files are not expected for resting state data.
+ Additionally, a common convention in the specification is to include the word "rest" in
+ the `task` label for resting state files (for example, `task-rest`).
+ type: string
+ format: label
+tracer:
+ name: trc
+ display_name: Tracer
+ description: |
+ The `trc-` entity can be used to distinguish sequences using different tracers.
+
+ This entity represents the `"TracerName"` metadata field.
+ Therefore, if the `trc-` entity is present in a filename,
+ `"TracerName"` MUST be defined in the associated metadata.
+ Please note that the `` does not need to match the actual value of the field.
+ type: string
+ format: label
+tracksys:
+ name: tracksys
+ display_name: Tracking system
+ description: |
+ The `tracksys-` entity can be used as a key-value pair
+ to label *_motion.tsv and *_motion.json files.
+ It can also be used to label *_channel.tsv or *_events.tsv files
+ when they belong to a specific tracking system.
+
+ This entity corresponds to the `"TrackingSystemName"` metadata field in a *_motion.json file.
+ `tracksys-` entity is a concise string whereas `"TrackingSystemName"`
+ may be longer and more human readable.
+ type: string
+ format: label
diff --git a/bep32v01/ressources/schema/objects/enums.yaml b/bep32v01/ressources/schema/objects/enums.yaml
new file mode 100644
index 00000000..f01d16cd
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/enums.yaml
@@ -0,0 +1,1407 @@
+---
+# This file defines valid values in BIDS key-value pairs.
+_EEGCoordSys:
+ type: string
+ enum:
+ - $ref: objects.enums.CapTrak.value
+ - $ref: objects.enums.EEGLAB.value
+ - $ref: objects.enums.EEGLAB-HJ.value
+ - $ref: objects.enums.Other.value
+_GeneticLevelEnum:
+ type: string
+ enum:
+ - $ref: objects.enums.Genetic.value
+ - $ref: objects.enums.Genomic.value
+ - $ref: objects.enums.Epigenomic.value
+ - $ref: objects.enums.Transcriptomic.value
+ - $ref: objects.enums.Metabolomic.value
+ - $ref: objects.enums.Proteomic.value
+_MEGCoordSys:
+ type: string
+ enum:
+ - $ref: objects.enums.CTF.value
+ - $ref: objects.enums.ElektaNeuromag.value
+ - $ref: objects.enums.4DBti.value
+ - $ref: objects.enums.KitYokogawa.value
+ - $ref: objects.enums.ChietiItab.value
+ - $ref: objects.enums.Other.value
+_StandardTemplateCoordSys:
+ type: string
+ enum:
+ - $ref: objects.enums.ICBM452AirSpace.value
+ - $ref: objects.enums.ICBM452Warp5Space.value
+ - $ref: objects.enums.IXI549Space.value
+ - $ref: objects.enums.fsaverage.value
+ - $ref: objects.enums.fsaverageSym.value
+ - $ref: objects.enums.fsLR.value
+ - $ref: objects.enums.MNIColin27.value
+ - $ref: objects.enums.MNI152Lin.value
+ - $ref: objects.enums.MNI152NLin2009aSym.value
+ - $ref: objects.enums.MNI152NLin2009bSym.value
+ - $ref: objects.enums.MNI152NLin2009cSym.value
+ - $ref: objects.enums.MNI152NLin2009aAsym.value
+ - $ref: objects.enums.MNI152NLin2009bAsym.value
+ - $ref: objects.enums.MNI152NLin2009cAsym.value
+ - $ref: objects.enums.MNI152NLin6Sym.value
+ - $ref: objects.enums.MNI152NLin6ASym.value
+ - $ref: objects.enums.MNI305.value
+ - $ref: objects.enums.NIHPD.value
+ - $ref: objects.enums.OASIS30AntsOASISAnts.value
+ - $ref: objects.enums.OASIS30Atropos.value
+ - $ref: objects.enums.Talairach.value
+ - $ref: objects.enums.UNCInfant.value
+_StandardTemplateDeprecatedCoordSys:
+ type: string
+ enum:
+ - $ref: objects.enums.fsaverage3.value
+ - $ref: objects.enums.fsaverage4.value
+ - $ref: objects.enums.fsaverage5.value
+ - $ref: objects.enums.fsaverage6.value
+ - $ref: objects.enums.fsaveragesym.value
+ - $ref: objects.enums.UNCInfant0V21.value
+ - $ref: objects.enums.UNCInfant1V21.value
+ - $ref: objects.enums.UNCInfant2V21.value
+ - $ref: objects.enums.UNCInfant0V22.value
+ - $ref: objects.enums.UNCInfant1V22.value
+ - $ref: objects.enums.UNCInfant2V22.value
+ - $ref: objects.enums.UNCInfant0V23.value
+ - $ref: objects.enums.UNCInfant1V23.value
+ - $ref: objects.enums.UNCInfant2V23.value
+_iEEGCoordSys:
+ type: string
+ enum:
+ - $ref: objects.enums.Pixels.value
+ - $ref: objects.enums.ACPC.value
+ - $ref: objects.enums.ScanRAS.value
+ - $ref: objects.enums.Other.value
+left_hemisphere:
+ value: 'L'
+ display_name: Left Hemisphere
+ description: |
+ A left hemibrain image.
+right_hemisphere:
+ value: 'R'
+ display_name: Right Hemisphere
+ description: |
+ A right hemibrain image.
+CASL:
+ value: CASL
+ display_name: Continuous arterial spin labeling
+ description: |
+ Continuous arterial spin labeling was employed.
+PCASL:
+ value: PCASL
+ display_name: Pseudo-continuous arterial spin labeling
+ description: |
+ Pseudo-continuous arterial spin labeling was employed.
+PASL:
+ value: PASL
+ display_name: Pulsed arterial spin labeling
+ description: |
+ Pulsed arterial spin labeling was employed.
+Separate:
+ value: Separate
+ display_name: Separate
+ description: |
+ A separate `m0scan` file is present.
+Included:
+ value: Included
+ display_name: Included
+ description: |
+ An m0scan volume is contained within the associated `asl` file.
+Estimate:
+ value: Estimate
+ display_name: Estimate
+ description: |
+ A single whole-brain M0 value is provided in the metadata.
+Absent:
+ value: Absent
+ display_name: Absent
+ description: |
+ No specific M0 information is present.
+TwoD:
+ value: 2D
+ display_name: Two-dimensional
+ description: |
+ Two-dimensional MR acquisition.
+ThreeD:
+ value: 3D
+ display_name: Three-dimensional
+ description: |
+ Three-dimensional MR acquisition.
+HARD:
+ value: HARD
+ display_name: Hard pulse
+ description: |
+ A very brief, strong, rectangular pulse.
+GAUSSIAN:
+ value: GAUSSIAN
+ display_name: Gaussian pulse
+ description: |
+ A Gaussian pulse.
+GAUSSHANN:
+ value: GAUSSHANN
+ display_name: Gaussian-Hanning pulse.
+ description: |
+ A Gaussian pulse with a Hanning window.
+SINC:
+ value: SINC
+ display_name: Sinc pulse
+ description: |
+ A sinc-shaped pulse.
+SINCHANN:
+ value: SINCHANN
+ display_name: Sinc-Hanning pulse
+ description: |
+ A sinc-shaped pulse with a Hanning window.
+SINCGAUSS:
+ value: SINCGAUSS
+ display_name: Sinc-Gauss pulse
+ description: |
+ A sinc-shaped pulse with a Gaussian window.
+FERMI:
+ value: FERMI
+ display_name: Fermi pulse
+ description: |
+ A Fermi-shaped pulse.
+i:
+ value: i
+ display_name: i
+ description: |
+ The encoding direction is along the first axis of the data in the NIFTI file,
+ and the encoding value increases from the zero index to the maximum index.
+j:
+ value: j
+ display_name: j
+ description: |
+ The encoding direction is along the second axis of the data in the NIFTI file,
+ and the encoding value increases from the zero index to the maximum index.
+k:
+ value: k
+ display_name: k
+ description: |
+ The encoding direction is along the third axis of the data in the NIFTI file,
+ and the encoding value increases from the zero index to the maximum index.
+iMinus:
+ value: i-
+ display_name: i-
+ description: |
+ The encoding direction is along the first axis of the data in the NIFTI file,
+ and the encoding value decreases from the zero index to the maximum index.
+jMinus:
+ value: j-
+ display_name: j-
+ description: |
+ The encoding direction is along the second axis of the data in the NIFTI file,
+ and the encoding value decreases from the zero index to the maximum index.
+kMinus:
+ value: k-
+ display_name: k-
+ description: |
+ The encoding direction is along the third axis of the data in the NIFTI file,
+ and the encoding value decreases from the zero index to the maximum index.
+continuous:
+ value: continuous
+ display_name: Continuous recording
+ description: |
+ Continuous recording.
+epoched:
+ value: epoched
+ display_name: Epoched recording
+ description: |
+ Recording is limited to time windows around events of interest
+ (for example, stimulus presentations or subject responses).
+discontinuous:
+ value: discontinuous
+ display_name: Discontinuous recording
+ description: |
+ Discontinuous recording.
+orig:
+ value: orig
+ display_name: orig
+ description: |
+ A (potentially unique) per-image space.
+ Useful for describing the source of transforms from an input image to a target space.
+Brain:
+ value: Brain
+ display_name: Brain mask
+ description: |
+ A brain mask.
+Lesion:
+ value: Lesion
+ display_name: Lesion mask
+ description: |
+ A lesion mask.
+Face:
+ value: Face
+ display_name: Face mask
+ description: |
+ A face mask.
+ROI:
+ value: ROI
+ display_name: ROI mask
+ description: |
+ A region of interest mask.
+CapTrak:
+ value: CapTrak
+ display_name: CapTrak
+ description: |
+ RAS orientation and the origin approximately between LPA and RPA
+EEGLAB:
+ value: EEGLAB
+ display_name: EEGLAB
+ description: |
+ ALS orientation and the origin exactly between LPA and RPA.
+ For more information, see the
+ [EEGLAB wiki page](https://eeglab.org/tutorials/ConceptsGuide/coordinateSystem.html#eeglab-coordinate-system).
+EEGLAB-HJ:
+ value: EEGLAB-HJ
+ display_name: EEGLAB-HJ
+ description: |
+ ALS orientation and the origin exactly between LHJ and RHJ.
+ For more information, see the
+ [EEGLAB wiki page](https://eeglab.org/tutorials/ConceptsGuide/coordinateSystem.html#\
+ eeglab-hj-coordinate-system).
+Other:
+ value: Other
+ display_name: Other
+ description: |
+ Other coordinate system.
+Genetic:
+ value: Genetic
+ display_name: Genetic
+ description: |
+ Data report on a single genetic location (typically directly in the `participants.tsv` file).
+Genomic:
+ value: Genomic
+ display_name: Genomic
+ description: |
+ Data link to participants' genome (multiple genetic locations).
+Epigenomic:
+ value: Epigenomic
+ display_name: Epigenomic
+ description: |
+ Data link to participants' characterization of reversible modifications of DNA.
+Transcriptomic:
+ value: Transcriptomic
+ display_name: Transcriptomic
+ description: |
+ Data link to participants RNA levels.
+Metabolomic:
+ value: Metabolomic
+ display_name: Metabolomic
+ description: |
+ Data link to participants' products of cellular metabolic functions.
+Proteomic:
+ value: Proteomic
+ display_name: Proteomic
+ description: |
+ Data link to participants peptides and proteins quantification.
+CTF:
+ value: CTF
+ display_name: CTF
+ description: |
+ ALS orientation and the origin between the ears.
+ElektaNeuromag:
+ value: ElektaNeuromag
+ display_name: Elekta Neuromag
+ description: |
+ RAS orientation and the origin between the ears.
+4DBti:
+ value: 4DBti
+ display_name: 4D BTI
+ description: |
+ ALS orientation and the origin between the ears.
+KitYokogawa:
+ value: KitYokogawa
+ display_name: KIT/Yokogawa
+ description: |
+ ALS orientation and the origin between the ears.
+ChietiItab:
+ value: ChietiItab
+ display_name: Chieti ITAB
+ description: |
+ RAS orientation and the origin between the ears.
+calibration:
+ value: calibration
+ display_name: calibration
+ description: |
+ The fine-calibration file, is produced by the MaxFilter software and the work of
+ Neuromag/Elekta/MEGIN engineers during maintenance of the MEG acquisition system.
+ It is specific to the site of recording and may change in the process of regular system maintenance.
+ it is usually shared with a crosstalk file.
+crosstalk:
+ value: crosstalk
+ display_name: crosstalk
+ description: |
+ The crosstalk file, is produced by the MaxFilter software and the work of
+ Neuromag/Elekta/MEGIN engineers during maintenance of the MEG acquisition system.
+ It is specific to the site of recording and may change in the process of regular system maintenance.
+ it is usually shared with a fine-calibration file.
+individual:
+ value: individual
+ display_name: individual
+ description: |
+ Participant specific anatomical space (for example derived from T1w and/or T2w images).
+ This coordinate system requires specifying an additional, participant-specific file to be fully defined.
+ In context of surfaces this space has been referred to as `fsnative`.
+
+ In order for this space to be interpretable, `SpatialReference` metadata MUST be provided.
+study:
+ value: study
+ display_name: study
+ description: |
+ Custom space defined using a group/study-specific template.
+ This coordinate system requires specifying an additional file to be fully defined.
+
+ In order for this space to be interpretable, `SpatialReference` metadata MUST be provided.
+scanner:
+ value: scanner
+ display_name: scanner
+ description: |
+ The intrinsic coordinate system of the original image (the first entry of `RawSources`)
+ after reconstruction and conversion to NIfTI or equivalent for the case of surfaces and dual volume/surface
+ files.
+
+ The `scanner` coordinate system is implicit and assumed by default if the derivative filename does not
+ define **any** `space-`.
+ Please note that `space-scanner` SHOULD NOT be used,
+ it is mentioned in this specification to make its existence explicit.
+ICBM452AirSpace:
+ value: ICBM452AirSpace
+ display_name: ICBM452AirSpace
+ description: |
+ Reference space defined by the "average of 452 T1-weighted MRIs of normal young adult brains"
+ with "linear transforms of the subjects into the atlas space using a 12-parameter affine
+ transformation".
+ICBM452Warp5Space:
+ value: ICBM452Warp5Space
+ display_name: ICBM452Warp5Space
+ description: |
+ Reference space defined by the "average of 452 T1-weighted MRIs of normal young adult brains"
+ "based on a 5th order polynomial transformation into the atlas space".
+IXI549Space:
+ value: IXI549Space
+ display_name: IXI549Space
+ description: |
+ Reference space defined by the average of the "549 (...) subjects from the IXI dataset"
+ linearly transformed to ICBM MNI 452.
+
+ Used by SPM12.
+fsaverage:
+ value: fsaverage
+ display_name: fsaverage
+ description: |
+ The `fsaverage` is a **dual template** providing both volumetric and surface coordinates references.
+ The volumetric template corresponds to a FreeSurfer variant of `MNI305` space.
+ The `fsaverage` atlas also defines a surface reference system (formerly described as fsaverage[3|4|5|6|sym]).
+
+ Used by Freesurfer.
+fsaverageSym:
+ value: fsaverageSym
+ display_name: fsaverageSym
+ description: |
+ The `fsaverage` is a **dual template** providing both volumetric and surface coordinates references.
+ The volumetric template corresponds to a FreeSurfer variant of `MNI305` space.
+ The `fsaverageSym` atlas also defines a symmetric surface reference system
+ (formerly described as `fsaveragesym`).
+
+ Used by Freesurfer.
+fsLR:
+ value: fsLR
+ display_name: fsLR
+ description: |
+ The `fsLR` is a **dual template** providing both volumetric and surface coordinates references.
+ The volumetric template corresponds to `MNI152NLin6Asym`.
+ Surface templates are given at several sampling densities:
+ 164k (used by HCP pipelines for 3T and 7T anatomical analysis),
+ 59k (used by HCP pipelines for 7T MRI bold and DWI analysis),
+ 32k (used by HCP pipelines for 3T MRI bold and DWI analysis), or
+ 4k (used by HCP pipelines for MEG analysis) fsaverage_LR surface reconstructed from the T1w image.
+
+ Used by Freesurfer.
+MNIColin27:
+ value: MNIColin27
+ display_name: MNIColin27
+ description: |
+ Average of 27 T1 scans of a single subject.
+
+ Used by SPM96.
+MNI152Lin:
+ value: MNI152Lin
+ display_name: MNI152Lin
+ description: |
+ Also known as ICBM (version with linear coregistration).
+
+ Used by SPM99 to SPM8.
+MNI152NLin2009aSym:
+ value: MNI152NLin2009aSym
+ display_name: MNI152NLin2009aSym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the first symmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin2009bSym:
+ value: MNI152NLin2009bSym
+ display_name: MNI152NLin2009bSym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the second symmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin2009cSym:
+ value: MNI152NLin2009cSym
+ display_name: MNI152NLin2009cSym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the third symmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin2009aAsym:
+ value: MNI152NLin2009aAsym
+ display_name: MNI152NLin2009aAsym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the first asymmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin2009bAsym:
+ value: MNI152NLin2009bAsym
+ display_name: MNI152NLin2009bAsym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the second asymmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin2009cAsym:
+ value: MNI152NLin2009cAsym
+ display_name: MNI152NLin2009cAsym
+ description: |
+ Also known as ICBM (non-linear coregistration with 40 iterations, released in 2009).
+ This is the third asymmetric version.
+
+ Used by the DARTEL toolbox in SPM12b.
+MNI152NLin6Sym:
+ value: MNI152NLin6Sym
+ display_name: MNI152NLin6Sym
+ description: |
+ Also known as symmetric ICBM 6th generation (non-linear coregistration).
+
+ Used by FSL.
+MNI152NLin6ASym:
+ value: MNI152NLin6ASym
+ display_name: MNI152NLin6ASym
+ description: |
+ A variation of `MNI152NLin6Sym` built by A. Janke that is released as the _MNI template_ of FSL.
+ Volumetric templates included with
+ [HCP-Pipelines](https://github.com/Washington-University/HCPpipelines/tree/master/global/templates)
+ correspond to this template too.
+
+ Used by FSL and HPC-Pipelines.
+MNI305:
+ value: MNI305
+ display_name: MNI205
+ description: |
+ Also known as avg305.
+NIHPD:
+ value: NIHPD
+ display_name: NIHPD
+ description: |
+ Pediatric templates generated from the NIHPD sample.
+ Available for different age groups
+ (4.5-18.5 y.o., 4.5-8.5 y.o., 7-11 y.o., 7.5-13.5 y.o., 10-14 y.o., 13-18.5 y.o.).
+ This template also comes in either -symmetric or -asymmetric flavor.
+OASIS30AntsOASISAnts:
+ value: OASIS30AntsOASISAnts
+ display_name: OASIS30AntsOASISAnts
+ description: |
+ OASIS30AntsOASISAnts
+OASIS30Atropos:
+ value: OASIS30Atropos
+ display_name: OASIS30Atropos
+ description: |
+ OASIS30Atropos
+Talairach:
+ value: Talairach
+ display_name: Talairach
+ description: |
+ Piecewise linear scaling of the brain is implemented as described in TT88.
+UNCInfant:
+ value: UNCInfant
+ display_name: UNCInfant
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds.
+fsaverage3:
+ value: fsaverage3
+ display_name: fsaverage3
+ description: |
+ Images were sampled to the FreeSurfer surface reconstructed from the subject's T1w image,
+ and registered to an fsaverage template.
+ For new datasets, the recommended alternative is fsaverage.
+fsaverage4:
+ value: fsaverage4
+ display_name: fsaverage4
+ description: |
+ Images were sampled to the FreeSurfer surface reconstructed from the subject's T1w image,
+ and registered to an fsaverage template.
+ For new datasets, the recommended alternative is fsaverage.
+fsaverage5:
+ value: fsaverage5
+ display_name: fsaverage5
+ description: |
+ Images were sampled to the FreeSurfer surface reconstructed from the subject's T1w image,
+ and registered to an fsaverage template.
+ For new datasets, the recommended alternative is fsaverage.
+fsaverage6:
+ value: fsaverage6
+ display_name: fsaverage6
+ description: |
+ Images were sampled to the FreeSurfer surface reconstructed from the subject's T1w image,
+ and registered to an fsaverage template.
+ For new datasets, the recommended alternative is fsaverage.
+fsaveragesym:
+ value: fsaveragesym
+ display_name: fsaveragesym
+ description: |
+ Images were sampled to the FreeSurfer surface reconstructed from the subject's T1w image,
+ and registered to an fsaverage template.
+ For new datasets, the recommended alternative is fsaverageSym.
+UNCInfant0V21:
+ value: UNCInfant0V21
+ display_name: UNCInfant0V21
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant1V21:
+ value: UNCInfant1V21
+ display_name: UNCInfant1V21
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant2V21:
+ value: UNCInfant2V21
+ display_name: UNCInfant2V21
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant0V22:
+ value: UNCInfant0V22
+ display_name: UNCInfant0V22
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant1V22:
+ value: UNCInfant1V22
+ display_name: UNCInfant1V22
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant2V22:
+ value: UNCInfant2V22
+ display_name: UNCInfant2V22
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant0V23:
+ value: UNCInfant0V23
+ display_name: UNCInfant0V23
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant1V23:
+ value: UNCInfant1V23
+ display_name: UNCInfant1V23
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+UNCInfant2V23:
+ value: UNCInfant2V23
+ display_name: UNCInfant2V23
+ description: |
+ Infant Brain Atlases from Neonates to 1- and 2-year-olds. See https://www.nitrc.org/projects/pediatricatlas.
+ For new datasets, the recommended alternative is UNCInfant.
+Pixels:
+ value: Pixels
+ display_name: Pixels
+ description: |
+ If electrodes are localized in 2D space (only x and y are
+ specified and z is n/a), then the positions in this file must correspond to
+ the locations expressed in pixels on the photo/drawing/rendering of the
+ electrodes on the brain. In this case, coordinates must be (row,column)
+ pairs, with (0,0) corresponding to the upper left pixel and (N,0)
+ corresponding to the lower left pixel.
+ACPC:
+ value: ACPC
+ display_name: ACPC
+ description: |
+ The origin of the coordinate system is at the Anterior Commissure
+ and the negative y-axis is passing through the Posterior Commissure. The
+ positive z-axis is passing through a mid-hemispheric point in the superior
+ direction. The anatomical landmarks are determined in the individual's
+ anatomical scan and no scaling or deformations have been applied to the
+ individual's anatomical scan. For more information, see the
+ [ACPC site](https://www.fieldtriptoolbox.org/faq/acpc/) on the FieldTrip
+ toolbox wiki.
+ScanRAS:
+ value: ScanRAS
+ display_name: ScanRAS
+ description: |
+ The origin of the coordinate system is the center of the
+ gradient coil for the corresponding T1w image of the subject, and the x-axis
+ increases left to right, the y-axis increases posterior to anterior and
+ the z-axis increases inferior to superior. For more information see the
+ [Nipy Documentation](https://nipy.org/nibabel/coordinate_systems.html). It is
+ strongly encouraged to align the subject's T1w to ACPC so that the `ACPC`
+ coordinate system can be used. If the subject's T1w in the BIDS dataset
+ is not aligned to ACPC, `ScanRAS` should be used.
+on__mtransfer:
+ value: 'on'
+ display_name: 'On'
+ description: |
+ The image acquired in the presence of the magnetization transfer pulse,
+ also known as the off-resonance pulse.
+off__mtransfer:
+ value: 'off'
+ display_name: 'Off'
+ description: |
+ The image acquired in the absence of the magnetization transfer pulse.
+magnitude:
+ value: mag
+ display_name: Magnitude
+ description: |
+ A magnitude image, typically paired with an associated "phase" image.
+phase:
+ value: phase
+ display_name: Phase
+ description: |
+ A phase image, typically paird with an associated "magnitude" (part-mag) image.
+ Images with this key/value pair MAY be in radians or in arbitrary units.
+ The sidecar JSON file MUST include the units of the `phase` image.
+ The possible options are `rad` or `arbitrary`.
+real:
+ value: real
+ display_name: Real
+ description: |
+ A real-valued image, typically paired with an associated "imaginary" (part-imag) image.
+imaginary:
+ value: imag
+ display_name: Imaginary
+ description: |
+ An imaginary-valued image, typically paird with an associated "real" image.
+ACCEL:
+ value: ACCEL
+ display_name: ACCEL
+ tags:
+ - fnirs
+ - motion
+ description: |
+ Accelerometer channel, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y, or z).
+ANGACCEL:
+ value: ANGACCEL
+ display_name: ANGACCEL
+ tags:
+ - motion
+ description: |
+ Angular acceleration channel, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y, or z).
+GYRO:
+ value: GYRO
+ display_name: GYRO
+ tags:
+ - fnirs
+ - motion
+ description: |
+ Gyrometer channel, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y, or z).
+JNTANG:
+ value: JNTANG
+ display_name: JNTANG
+ tags:
+ - motion
+ description: |
+ Joint angle channel between two fixed axis belonging to two bodyparts.
+ Angle SHOULD be defined between proximal and distal bodypart in `deg`.
+LATENCY:
+ value: LATENCY
+ display_name: LATENCY
+ tags:
+ - motion
+ description: |
+ Latency of samples in seconds from recording onset.
+ MUST be in form of `ss[.000000]`,
+ where `[.000000]` is an optional subsecond resolution between 1 and 6 decimal points.
+MAGN:
+ value: MAGN
+ display_name: MAGN
+ tags:
+ - fnirs
+ - motion
+ description: |
+ Magnetic field strength, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y or z).
+MISC:
+ value: MISC
+ display_name: MISC
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ - motion
+ description: |
+ Miscellaneous channels.
+ORNT:
+ value: ORNT
+ display_name: ORNT
+ tags:
+ - fnirs
+ - motion
+ description: |
+ Orientation channel, one channel for each spatial axis or quaternion component.
+ Column `component` for the axis or quaternion label MUST be added to the `*_channels.tsv` file
+ (x, y, z, quat_x, quat_y, quat_z, or quat_w).
+POS:
+ value: POS
+ display_name: POS
+ tags:
+ - motion
+ description: |
+ Position in space, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y or z).
+VEL:
+ value: VEL
+ display_name: VEL
+ tags:
+ - motion
+ description: |
+ Velocity, one channel for each spatial axis.
+ Column `component` for the axis MUST be added to the `*_channels.tsv` file (x, y or z).
+AUDIO:
+ value: AUDIO
+ display_name: AUDIO
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Audio signal.
+EEG:
+ value: EEG
+ display_name: EEG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electroencephalogram channel.
+EOG:
+ value: EOG
+ display_name: EOG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Generic electrooculogram (eye), different from HEOG and VEOG.
+ECG:
+ value: ECG
+ display_name: ECG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electrocardiogram (heart).
+EMG:
+ value: EMG
+ display_name: EMG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electromyogram (muscle).
+EYEGAZE:
+ value: EYEGAZE
+ display_name: EYEGAZE
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Eye tracker gaze.
+GSR:
+ value: GSR
+ display_name: GSR
+ tags:
+ - eeg
+ description: |
+ Galvanic skin response.
+HEOG:
+ value: HEOG
+ display_name: HEOG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Horizontal EOG (eye).
+PPG:
+ value: PPG
+ display_name: PPG
+ tags:
+ - eeg
+ description: |
+ Photoplethysmography.
+PUPIL:
+ value: PUPIL
+ display_name: PUPIL
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Eye tracker pupil diameter.
+REF:
+ value: REF
+ display_name: REF
+ tags:
+ - eeg
+ - ieeg
+ description: |
+ Reference channel.
+RESP:
+ value: RESP
+ display_name: RESP
+ tags:
+ - eeg
+ description: |
+ Respiration.
+SYSCLOCK:
+ value: SYSCLOCK
+ display_name: SYSCLOCK
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ System time showing elapsed time since trial started.
+TEMP:
+ value: TEMP
+ display_name: TEMP
+ tags:
+ - eeg
+ description: |
+ Temperature.
+TRIG:
+ value: TRIG
+ display_name: TRIG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Analog (TTL in Volt) or digital (binary TTL) trigger channel.
+VEOG:
+ value: VEOG
+ display_name: VEOG
+ tags:
+ - eeg
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Vertical EOG (eye).
+MEGMAG:
+ value: MEGMAG
+ display_name: MEGMAG
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG magnetometer.
+MEGGRADAXIAL:
+ value: MEGGRADAXIAL
+ display_name: MEGGRADAXIAL
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG axial gradiometer.
+MEGGRADPLANAR:
+ value: MEGGRADPLANAR
+ display_name: MEGGRADPLANAR
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG planargradiometer.
+MEGREFMAG:
+ value: MEGREFMAG
+ display_name: MEGREFMAG
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG reference magnetometer.
+MEGREFGRADAXIAL:
+ value: MEGREFGRADAXIAL
+ display_name: MEGREFGRADAXIAL
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG reference axial gradiometer.
+MEGREFGRADPLANAR:
+ value: MEGREFGRADPLANAR
+ display_name: MEGREFGRADPLANAR
+ tags:
+ - meg
+ - fnirs
+ description: |
+ MEG reference planar gradiometer.
+MEGOTHER:
+ value: MEGOTHER
+ display_name: MEGOTHER
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Any other type of MEG sensor.
+ECOG:
+ value: ECOG
+ display_name: ECOG
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electrode channel.
+SEEG:
+ value: SEEG
+ display_name: SEEG
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electrode channel.
+DBS:
+ value: DBS
+ display_name: DBS
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Electrode channel.
+PD:
+ value: PD
+ display_name: PD
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Photodiode.
+ADC:
+ value: ADC
+ display_name: ADC
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Analog to Digital input.
+DAC:
+ value: DAC
+ display_name: DAC
+ tags:
+ - meg
+ - ieeg
+ - fnirs
+ description: |
+ Digital to Analog output.
+HLU:
+ value: HLU
+ display_name: HLU
+ tags:
+ - meg
+ - fnirs
+ description: |
+ Measured position of head and head coils.
+FITERR:
+ value: FITERR
+ display_name: FITERR
+ tags:
+ - meg
+ - fnirs
+ description: |
+ Fit error signal from each head localization coil.
+OTHER:
+ value: OTHER
+ display_name: OTHER
+ tags:
+ - meg
+ - fnirs
+ description: |
+ Any other type of channel.
+NIRSCWAMPLITUDE:
+ value: NIRSCWAMPLITUDE
+ display_name: NIRSCWAMPLITUDE
+ tags:
+ - fnirs
+ description: |
+ Continuous wave amplitude measurements. Equivalent to dataType 001 in SNIRF.
+NIRSCWFLUORESCENSEAMPLITUDE:
+ value: NIRSCWFLUORESCENSEAMPLITUDE
+ display_name: NIRSCWFLUORESCENSEAMPLITUDE
+ tags:
+ - fnirs
+ description: |
+ Continuous wave fluorescence amplitude measurements. Equivalent to dataType 051 in SNIRF.
+NIRSCWOPTICALDENSITY:
+ value: NIRSCWOPTICALDENSITY
+ display_name: NIRSCWOPTICALDENSITY
+ tags:
+ - fnirs
+ description: |
+ Continuous wave change in optical density measurements. Equivalent to dataTypeLabel dOD in SNIRF.
+NIRSCWHBO:
+ value: NIRSCWHBO
+ display_name: NIRSCWHBO
+ tags:
+ - fnirs
+ description: |
+ Continuous wave oxygenated hemoglobin (oxyhemoglobin) concentration measurements.
+ Equivalent to dataTypeLabel HbO in SNIRF.
+NIRSCWHBR:
+ value: NIRSCWHBR
+ display_name: NIRSCWHBR
+ tags:
+ - fnirs
+ description: |
+ Continuous wave deoxygenated hemoglobin (deoxyhemoglobin) concentration measurements.
+ Equivalent to dataTypeLabel HbR in SNIRF.
+NIRSCWMUA:
+ value: NIRSCWMUA
+ display_name: NIRSCWMUA
+ tags:
+ - fnirs
+ description: |
+ Continuous wave optical absorption measurements. Equivalent to dataTypeLabel mua in SNIRF.
+source:
+ value: source
+ display_name: source
+ description: |
+ A light emitting device, sometimes called a transmitter.
+detector:
+ value: detector
+ display_name: detector
+ description: |
+ A photoelectric transducer, sometimes called a receiver.
+mixed:
+ value: mixed
+ display_name: mixed
+ description: |
+ Mixed detector types were used for this NIRS recording, specify in `optodes.tsv`.
+x:
+ value: x
+ display_name: x
+ description: |
+ The x dimension of the coordinate system.
+y:
+ value: y
+ display_name: y
+ description: |
+ The y dimension of the coordinate system.
+z:
+ value: z
+ display_name: z
+ description: |
+ The z dimension of the coordinate system.
+quat_x:
+ value: quat_x
+ display_name: quat_x
+ description: |
+ The quaternion x dimension of the coordinate system.
+quat_y:
+ value: quat_y
+ display_name: quat_y
+ description: |
+ The quaternion y dimension of the coordinate system.
+quat_z:
+ value: quat_z
+ display_name: quat_z
+ description: |
+ The quaternion z dimension of the coordinate system.
+quat_w:
+ value: quat_w
+ display_name: quat_w
+ description: |
+ The quaternion w dimension of the coordinate system.
+unknown:
+ value: 'unknown'
+ display_name: unknown
+ description: |
+ An unknown unit.
+pixels:
+ value: pixels
+ display_name: pixels
+ description: |
+ A dimension specified in pixels.
+cell_line:
+ value: cell line
+ display_name: cell line
+ description: |
+ A biosample type (`sample_type`): cell line
+in_vitro_differentiated_cells:
+ value: in vitro differentiated cells
+ display_name: in vitro differentiated cells
+ description: |
+ A biosample type (`sample_type`): in vitro differentiated cells
+primary_cell:
+ value: primary cell
+ display_name: primary cell
+ description: |
+ A biosample type (`sample_type`): primary cell
+cell_free_sample:
+ value: cell-free sample
+ display_name: cell-free sample
+ description: |
+ A biosample type (`sample_type`): cell-free sample
+cloning_host:
+ value: cloning host
+ display_name: cloning host
+ description: |
+ A biosample type (`sample_type`): cloning host
+tissue:
+ value: tissue
+ display_name: tissue
+ description: |
+ A biosample type (`sample_type`): tissue
+whole_organisms:
+ value: whole organisms
+ display_name: whole organisms
+ description: |
+ A biosample type (`sample_type`): whole organisms
+organoid:
+ value: organoid
+ display_name: organoid
+ description: |
+ A biosample type (`sample_type`): organoid
+technical_sample:
+ value: technical sample
+ display_name: technical sample
+ description: |
+ A biosample type (`sample_type`): technical sample
+good:
+ value: good
+ display_name: good
+ description: |
+ A good status (for example the status of a recording channel).
+bad:
+ value: bad
+ display_name: bad
+ description: |
+ A bad status (for example the status of a recording channel).
+control:
+ value: control
+ display_name: control
+ description: |
+ An ASL volume type: control
+label:
+ value: label
+ display_name: label
+ description: |
+ An ASL volume type: label
+m0scan:
+ value: m0scan
+ display_name: m0scan
+ description: |
+ An ASL volume type: m0scan
+deltam:
+ value: deltam
+ display_name: deltam
+ description: |
+ An ASL volume type: deltam
+cbf:
+ value: cbf
+ display_name: cbf
+ description: |
+ An ASL volume type: cbf
+single_coil:
+ value: single-coil
+ display_name: single-coil
+ description: |
+ CASL Type: when a single coil is used for labeling.
+double_coil:
+ value: double-coil
+ display_name: double-coil
+ description: |
+ CASL Type: when a double coil is used for labeling.
+IODINE:
+ value: IODINE
+ display_name: IODINE
+ description: |
+ A Contrast Bolus Ingredient: Iodine
+GADOLINIUM:
+ value: GADOLINIUM
+ display_name: GADOLINIUM
+ description: |
+ A Contrast Bolus Ingredient: Gadolinium
+CARBON_DIOXIDE:
+ value: CARBON DIOXIDE
+ display_name: CARBON DIOXIDE
+ description: |
+ A Contrast Bolus Ingredient: Carbon Dioxide
+BARIUM:
+ value: BARIUM
+ display_name: BARIUM
+ description: |
+ A Contrast Bolus Ingredient: Barium
+XENON:
+ value: XENON
+ display_name: XENON
+ description: |
+ A Contrast Bolus Ingredient: Xenon
+raw:
+ value: raw
+ display_name: raw
+ description: |
+ A raw BIDS dataset.
+derivative:
+ value: derivative
+ display_name: derivative
+ description: |
+ A derived BIDS dataset.
+balanced:
+ value: balanced
+ display_name: balanced
+ description: |
+ PCASL Type: when balanced gradient pulses are used.
+unbalanced:
+ value: unbalanced
+ display_name: unbalanced
+ description: |
+ PCASL Type: when unbalanced gradient pulses are used.
+left_hand:
+ value: left-hand
+ display_name: left-hand
+ description: |
+ A rotation rule: rotations are applied clockwise around
+ an axis when seen from the positive direction
+right_hand:
+ value: right-hand
+ display_name: right-hand
+ description: |
+ A rotation rule: rotations are applied counter-clockwise around
+ an axis when seen from the positive direction
+in_vivo:
+ value: in vivo
+ display_name: in vivo
+ description: |
+ The environment of a sample: in vivo
+ex_vivo:
+ value: ex vivo
+ display_name: ex vivo
+ description: |
+ The environment of a sample: ex vivo
+in_vitro:
+ value: in vitro
+ display_name: in vitro
+ description: |
+ The environment of a sample: in vitro
+blood:
+ value: blood
+ display_name: blood
+ description: |
+ The origin of a sample: blood
+saliva:
+ value: saliva
+ display_name: saliva
+ description: |
+ The origin of a sample: saliva
+brain:
+ value: brain
+ display_name: brain
+ description: |
+ The origin of a sample: brain
+csf:
+ value: csf
+ display_name: CSF
+ description: |
+ Cerebrospinal fluid (for example, the origin of a sample or tissue)
+breast_milk:
+ value: breast milk
+ display_name: breast milk
+ description: |
+ The origin of a sample: breast milk
+bile:
+ value: bile
+ display_name: Bile
+ description: |
+ The origin of a sample: bile
+amniotic_fluid:
+ value: amniotic fluid
+ display_name: amniotic fluid
+ description: |
+ The origin of a sample: amniotic fluid
+other_biospecimen:
+ value: other biospecimen
+ display_name: other biospecimen
+ description: |
+ The origin of a sample: other biospecimen
+RF:
+ value: RF
+ display_name: RF
+ description: |
+ A spoiling type: RF
+GRADIENT:
+ value: GRADIENT
+ display_name: GRADIENT
+ description: |
+ A spoiling type: GRADIENT
+COMBINED:
+ value: COMBINED
+ display_name: COMBINED
+ description: |
+ A spoiling type: COMBINED
+gray_matter:
+ value: gray matter
+ display_name: gray matter
+ description: |
+ The origin of a tissue: gray matter
+white_matter:
+ value: white matter
+ display_name: white matter
+ description: |
+ The origin of a tissue: white matter
+meninges:
+ value: meninges
+ display_name: meninges
+ description: |
+ The origin of a tissue: meninges
+macrovascular:
+ value: macrovascular
+ display_name: macrovascular
+ description: |
+ The origin of a tissue: macrovascular
+microvascular:
+ value: microvascular
+ display_name: microvascular
+ description: |
+ The origin of a tissue: microvascular
diff --git a/bep32v01/ressources/schema/objects/extensions.yaml b/bep32v01/ressources/schema/objects/extensions.yaml
new file mode 100644
index 00000000..96056e49
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/extensions.yaml
@@ -0,0 +1,320 @@
+---
+# This file describes valid file extensions in the specification.
+ave:
+ value: .ave
+ display_name: AVE # not sure what ave stands for
+ description: |
+ File containing data averaged by segments of interest.
+
+ Used by KIT, Yokogawa, and Ricoh MEG systems.
+bdf:
+ value: .bdf
+ display_name: Biosemi Data Format
+ description: |
+ A [Biosemi](https://www.biosemi.com/) Data Format file.
+
+ Each recording consists of a single `.bdf` file.
+ [`bdf+`](https://www.teuniz.net/edfbrowser/bdfplus%20format%20description.html) files are permitted.
+ The capital `.BDF` extension MUST NOT be used.
+bval:
+ value: .bval
+ display_name: FSL-Format Gradient Amplitudes
+ description: |
+ A space-delimited file containing gradient directions (b-vectors) of diffusion measurement.
+
+ The `bval` file contains the *b*-values (in s/mm2 ) corresponding to the
+ volumes in the relevant NIfTI file, with 0 designating *b*=0 volumes.
+bvec:
+ value: .bvec
+ display_name: FSL-Format Gradient Directions
+ description: |
+ A space-delimited file containing gradient directions (b-vectors) of diffusion measurement.
+
+ This file contains 3 rows with *N* space-delimited floating-point numbers,
+ corresponding to the *N* volumes in the corresponding NIfTI file.
+
+ The first row contains the *x* elements, the second row contains the *y* elements and
+ the third row contains the *z* elements of a unit vector in the direction of the applied
+ diffusion gradient, where the *i*-th elements in each row correspond together to
+ the *i*-th volume, with `[0,0,0]` for *non-diffusion-weighted* (also called *b*=0 or *low-b*)
+ volumes.
+
+ Following the FSL format for the `bvec` specification, the coordinate system of
+ the *b* vectors MUST be defined with respect to the coordinate system defined by
+ the header of the corresponding `_dwi` NIfTI file and not the scanner's device
+ coordinate system (see [Coordinate systems](SPEC_ROOT/appendices/coordinate-systems.md)).
+ The most relevant limitation imposed by this choice is that the gradient information cannot
+ be directly stored in this format if the scanner generates *b*-vectors in *scanner coordinates*.
+chn:
+ value: .chn
+ display_name: KRISS CHN
+ description: |
+ A file generated by KRISS MEG systems containing the position of the center of the MEG coils.
+
+ Each experimental run on the KRISS system produces a file with extension `.kdf`.
+ Additional files that may be available in the same directory include
+ the digitized positions of the head points (`\_digitizer.txt`),
+ the position of the center of the MEG coils (`.chn`),
+ and the event markers (`.trg`).
+con:
+ value: .con
+ display_name: KIT/Yokogawa/Ricoh Continuous Data
+ description: |
+ Raw continuous data from a KIT/Yokogawa/Ricoh MEG system.
+
+ Successor to the `.sqd` extension for raw continuous data.
+dat:
+ value: .dat
+ display_name: MEG Fine-Calibration Format
+ description: |
+ A fine-calibration file used for Neuromag/Elekta/MEGIN MEG recording hardware.
+CTF:
+ value: .ds/
+ display_name: CTF MEG Dataset Directory
+ description: |
+ A directory for MEG data, typically containing a `.meg4` file for the data and a `.res4` file for the resources.
+dlabelnii:
+ value: .dlabel.nii
+ display_name: CIFTI-2 Dense Label File
+ description: |
+ A CIFTI-2 dense label file.
+
+ This extension may only be used in derivative datasets.
+edf:
+ value: .edf
+ display_name: European Data Format
+ description: |
+ A [European data format](https://www.edfplus.info/) file.
+
+ Each recording consists of a single `.edf`` file.
+ [`edf+`](https://www.edfplus.info/specs/edfplus.html) files are permitted.
+ The capital `.EDF` extension MUST NOT be used.
+eeg:
+ value: .eeg
+ display_name: BrainVision Binary Data
+ description: |
+ A binary data file in the
+ [BrainVision Core Data Format](https://www.brainproducts.com/support-resources/brainvision-core-data-format-1-0/).
+ These files come in three-file sets, including a `.vhdr`, a `.vmrk`, and a `.eeg` file.
+fdt:
+ value: .fdt
+ display_name: EEGLAB FDT
+ description: |
+ An [EEGLAB](https://sccn.ucsd.edu/eeglab/index.php) file.
+
+ The format used by the MATLAB toolbox [EEGLAB](https://sccn.ucsd.edu/eeglab/index.php).
+ Each recording consists of a `.set` file with an optional `.fdt` file.
+fif:
+ value: .fif
+ display_name: Functional Imaging File Format
+ description: |
+ An MEG file format used by Neuromag, Elekta, and MEGIN.
+jpg:
+ value: .jpg
+ display_name: Joint Photographic Experts Group Format
+ description: |
+ A JPEG image file.
+json:
+ value: .json
+ display_name: JavaScript Object Notation
+ description: |
+ A JSON file.
+
+ In the BIDS specification, JSON files are primarily used as "sidecar" files, in which metadata describing "data"
+ files are encoded.
+ These sidecar files follow the inheritance principle.
+
+ There are also a few special cases of JSON files being first-order data files, such as `genetic_info.json`.
+kdf:
+ value: .kdf
+ display_name: KRISS KDF
+ description: |
+ A KRISS (file with extension `.kdf`) file.
+
+ Each experimental run on the KRISS system produces a file with extension `.kdf`.
+ Additional files that may be available in the same directory include
+ the digitized positions of the head points (`\_digitizer.txt`),
+ the position of the center of the MEG coils (`.chn`),
+ and the event markers (`.trg`).
+labelgii:
+ value: .label.gii
+ display_name: GIFTI label/annotation file
+ description: |
+ A GIFTI label/annotation file.
+
+ This extension may only be used in derivative datasets.
+md:
+ value: .md
+ display_name: Markdown
+ description: |
+ A Markdown file.
+mefd:
+ value: .mefd/
+ display_name: Multiscale Electrophysiology File Format Version 3.0
+ description: |
+ A directory in the [MEF3](https://osf.io/e3sf9/) format.
+
+ Each recording consists of a `.mefd` directory.
+mhd:
+ value: .mhd
+ display_name: ITAB Binary Header
+ description: |
+ Produced by ITAB-ARGOS153 systems. This file a binary header file, and is generated along with a
+ raw data file with the `.raw` extension.
+mrk:
+ value: .mrk
+ display_name: MRK
+ description: |
+ A file containing MEG sensor coil positions.
+
+ Used by KIT, Yokogawa, and Ricoh MEG systems.
+ Successor to the `.sqd` extension for marker files.
+OMEZARR:
+ value: .ome.zarr/
+ display_name: OME Next Generation File Format
+ description: |
+ An OME-NGFF file.
+
+ OME-NGFF is a [Zarr](https://zarr.readthedocs.io/en/stable/)-based format,
+ organizing data arrays in nested directories.
+ This format was developed by the Open Microscopy Environment
+ to provide data stream access to very large data.
+nii:
+ value: .nii
+ display_name: NIfTI
+ description: |
+ A Neuroimaging Informatics Technology Initiative (NIfTI) data file.
+niigz:
+ value: .nii.gz
+ display_name: Compressed NIfTI
+ description: |
+ A compressed Neuroimaging Informatics Technology Initiative (NIfTI) data file.
+nwb:
+ value: .nwb
+ display_name: Neurodata Without Borders Format
+ description: |
+ A [Neurodata Without Borders](https://nwb-schema.readthedocs.io/en/latest/) file.
+
+ Each recording consists of a single `.nwb` file.
+OMEBigTiff:
+ value: .ome.btf
+ display_name: Open Microscopy Environment BigTIFF
+ description: |
+ A [BigTIFF](https://www.awaresystems.be/imaging/tiff/bigtiff.html) image file, for very large images.
+OMETiff:
+ value: .ome.tif
+ display_name: Open Microscopy Environment Tag Image File Format
+ description: |
+ An [OME-TIFF](https://docs.openmicroscopy.org/ome-model/6.1.2/ome-tiff/specification.html#) image file.
+png:
+ value: .png
+ display_name: Portable Network Graphics
+ description: |
+ A [Portable Network Graphics](http://www.libpng.org/pub/png/) file.
+pos:
+ value: .pos
+ display_name: Head Point Position
+ description: |
+ File containing digitized positions of the head points.
+
+ This may be produced by a 4D neuroimaging/BTi MEG system or a CTF MEG system.
+raw:
+ value: .raw
+ display_name: RAW
+ description: |
+ When produced by a KIT / Yokogawa / Ricoh MEG system, this file contains trial-based evoked fields.
+
+ When produced by an ITAB-ARGOS153 system, this file contains raw data and is generated along with
+ an associated binary header file with the `.mhd` extension.
+rst:
+ value: .rst
+ display_name: reStructuredText
+ description: |
+ A [reStructuredText](https://docutils.sourceforge.io/rst.html) file.
+set:
+ value: .set
+ display_name: EEGLAB SET
+ description: |
+ An [EEGLAB](https://sccn.ucsd.edu/eeglab/index.php) file.
+
+ The format used by the MATLAB toolbox [EEGLAB](https://sccn.ucsd.edu/eeglab/index.php).
+ Each recording consists of a `.set` file with an optional `.fdt` file.
+snirf:
+ value: .snirf
+ display_name: Shared Near Infrared Spectroscopy Format
+ description: |
+ HDF5 file organized according to the [SNIRF specification](https://github.com/fNIRS/snirf)
+sqd:
+ value: .sqd
+ display_name: SQD
+ description: |
+ A file containing either raw MEG data or MEG sensor coil positions.
+ While this extension is still valid, it has been succeeded by `.con` for raw MEG data and `.mrk` for
+ marker information.
+
+ Used by KIT, Yokogawa, and Ricoh MEG systems.
+tif:
+ value: .tif
+ display_name: Tag Image File Format
+ description: |
+ A [Tag Image File Format](https://en.wikipedia.org/wiki/TIFF) file.
+trg:
+ value: .trg
+ display_name: KRISS TRG
+ description: |
+ A file generated by KRISS MEG systems containing the event markers.
+
+ Each experimental run on the KRISS system produces a file with extension `.kdf`.
+ Additional files that may be available in the same directory include
+ the digitized positions of the head points (`\_digitizer.txt`),
+ the position of the center of the MEG coils (`.chn`),
+ and the event markers (`.trg`).
+tsv:
+ value: .tsv
+ display_name: Tab-Delimited
+ description: |
+ A tab-delimited file.
+tsvgz:
+ value: .tsv.gz
+ display_name: Compressed Tab-Delimited
+ description: |
+ A gzipped tab-delimited file.
+ This file extension is only used for very large tabular data, such as physiological recordings.
+ For smaller data, the unzipped `.tsv` extension is preferred.
+txt:
+ value: .txt
+ display_name: Text
+ description: |
+ A free-form text file.
+
+ Tab-delimited files should have the `.tsv` extension rather than a `.txt` extension.
+vhdr:
+ value: .vhdr
+ display_name: BrainVision Text Header
+ description: |
+ A text header file in the
+ [BrainVision Core Data Format](https://www.brainproducts.com/support-resources/brainvision-core-data-format-1-0/).
+ These files come in three-file sets, including a `.vhdr`, a `.vmrk`, and a `.eeg` file.
+vmrk:
+ value: .vmrk
+ display_name: BrainVision Marker
+ description: |
+ A text marker file in the
+ [BrainVision Core Data Format](https://www.brainproducts.com/support-resources/brainvision-core-data-format-1-0/).
+ These files come in three-file sets, including a `.vhdr`, a `.vmrk`, and a `.eeg` file.
+Any:
+ value: .*
+ display_name: Any Extension
+ description: |
+ Any extension is allowed.
+None:
+ value: ''
+ display_name: No extension
+ description: |
+ A file with no extension.
+Directory:
+ value: /
+ display_name: Directory
+ description: |
+ A directory with no extension.
+ Corresponds to BTi/4D data.
diff --git a/bep32v01/ressources/schema/objects/files.yaml b/bep32v01/ressources/schema/objects/files.yaml
new file mode 100644
index 00000000..10cadf3b
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/files.yaml
@@ -0,0 +1,128 @@
+---
+# This file describes files which may appear at the top level of a dataset.
+# This does not include information about whether these files are required or optional.
+# For that information, see `rules/top_level_files.yaml`.
+CHANGES:
+ display_name: Changelog
+ file_type: regular
+ description: |
+ Version history of the dataset (describing changes, updates and corrections) MAY be provided in
+ the form of a `CHANGES` text file.
+ This file MUST follow the
+ [CPAN Changelog convention](https://metacpan.org/release/HAARG/CPAN-Changes-0.400002/view\
+ /lib/CPAN/Changes/Spec.pod).
+ The `CHANGES` file MUST be either in ASCII or UTF-8 encoding.
+CITATION:
+ display_name: CITATION.cff
+ file_type: regular
+ description: |
+ A description of the citation information for the dataset, following the
+ [Citation File Format](https://citation-file-format.github.io/) specification.
+ This file permits more detailed and structured descriptions than
+ [dataset_description.json](SPEC_ROOT/glossary.md#dataset_description-files).
+LICENSE:
+ display_name: License
+ file_type: regular
+ description: |
+ A `LICENSE` file MAY be provided in addition to the short specification of the
+ used license in the `dataset_description.json` `"License"` field.
+ The `"License"` field and `LICENSE` file MUST correspond.
+ The `LICENSE` file MUST be either in ASCII or UTF-8 encoding.
+README:
+ display_name: README
+ file_type: regular
+ description: |
+ A REQUIRED text file, `README`, SHOULD describe the dataset in more detail.
+ The `README` file MUST be either in ASCII or UTF-8 encoding and MAY have one of the extensions:
+ `.md` ([Markdown](https://www.markdownguide.org/)),
+ `.rst` ([reStructuredText](https://docutils.sourceforge.io/rst.html)),
+ or `.txt`.
+ A BIDS dataset MUST NOT contain more than one `README` file (with or without extension)
+ at its root directory.
+ BIDS does not make any recommendations with regards to the
+ [Markdown flavor](https://www.markdownguide.org/extended-syntax/#lightweight-markup-languages)
+ and does not validate the syntax of Markdown and reStructuredText.
+ The `README` file SHOULD be structured such that its contents can be easily understood
+ even if the used format is not rendered.
+ A guideline for creating a good `README` file can be found in the
+ [bids-starter-kit](https://github.com/bids-standard/bids-starter-kit/tree/main/templates/).
+dataset_description:
+ display_name: Dataset Description
+ file_type: regular
+ description: |
+ The file `dataset_description.json` is a JSON file describing the dataset.
+genetic_info:
+ display_name: Genetic Information
+ file_type: regular
+ description: |
+ The `genetic_info.json` file describes the genetic information available in the
+ `participants.tsv` file and/or the genetic database described in
+ `dataset_description.json`.
+
+ Datasets containing the `Genetics` field in `dataset_description.json` or the
+ `genetic_id` column in `participants.tsv` MUST include this file.
+participants:
+ display_name: Participant Information
+ file_type: regular
+ description: |
+ The purpose of this RECOMMENDED file is to describe properties of participants
+ such as age, sex, handedness, species and strain.
+ If this file exists, it MUST contain the column `participant_id`,
+ which MUST consist of `sub-` values identifying one row for each participant,
+ followed by a list of optional columns describing participants.
+ Each participant MUST be described by one and only one row.
+
+ Commonly used *optional* columns in `participants.tsv` files are `age`, `sex`,
+ `handedness`, `strain`, and `strain_rrid`.
+
+ The RECOMMENDED `species` column SHOULD be a binomial species name from the
+ [NCBI Taxonomy](https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi)
+ (for examples `homo sapiens`, `mus musculus`, `rattus norvegicus`).
+ For backwards compatibility, if `species` is absent, the participant is assumed to be
+ `homo sapiens`.
+samples:
+ display_name: Sample Information
+ file_type: regular
+ description: |
+ The purpose of this file is to describe properties of samples, indicated by the `sample` entity.
+ This file is REQUIRED if `sample-` is present in any filename within the dataset.
+ Each sample MUST be described by one and only one row.
+code:
+ display_name: Code
+ file_type: directory
+ description: |
+ A directory in which to store any code
+ (for example the one used to generate the derivatives from the raw data).
+ See the [Code section](SPEC_ROOT/modality-agnostic-files.md#code)
+ for more information.
+derivatives:
+ display_name: Derivative data
+ file_type: directory
+ description: |
+ Derivative data (for example preprocessed files).
+ See the [relevant section](SPEC_ROOT/common-principles.md#source-vs-raw-vs-derived-data)
+ for more information.
+phenotype:
+ display_name: Phenotype
+ file_type: directory
+ description: |
+ A directory where to store participant level measurements (for
+ example responses from multiple questionnaires) split into
+ individual files separate from `participants.tsv`.
+ See the [relevant section](SPEC_ROOT/modality-agnostic-files.md#phenotypic-and-assessment-data)
+ for more information.
+sourcedata:
+ display_name: Source data
+ file_type: directory
+ description: |
+ A directory where to store data before harmonization, reconstruction,
+ and/or file format conversion (for example, E-Prime event logs or DICOM files).
+ See the [relevant section](SPEC_ROOT/common-principles.md#source-vs-raw-vs-derived-data)
+ for more information.
+stimuli:
+ display_name: Stimulus files
+ file_type: directory
+ description: |
+ A directory to store any stimulus files used during an experiment.
+ See the [relevant section](SPEC_ROOT/modality-specific-files/task-events.md#stimuli-directory)
+ for more information.
diff --git a/bep32v01/ressources/schema/objects/formats.yaml b/bep32v01/ressources/schema/objects/formats.yaml
new file mode 100644
index 00000000..804dfda8
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/formats.yaml
@@ -0,0 +1,130 @@
+---
+# This file defines valid patterns for different formats
+# Entity patterns
+index:
+ display_name: Index
+ description: |
+ Non-negative, optionally prefixed with leading zeros for better visual homogeneity and sorting.
+ pattern: '[0-9]+'
+label:
+ display_name: Label
+ description: |
+ Freeform labels without special characters.
+ pattern: '[0-9a-zA-Z]+'
+# Metadata types
+boolean:
+ display_name: Boolean
+ description: |
+ A boolean.
+ Must be either "true" or "false".
+ pattern: '(true|false)'
+integer:
+ display_name: Integer
+ description: |
+ An integer which may be positive or negative.
+ pattern: ' *[+-]?\d+ *'
+number:
+ display_name: Number
+ description: |
+ A number which may be an integer or float, positive or negative.
+ pattern: ' *[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)? *'
+string:
+ display_name: String
+ description: |
+ The basic string type (not a specific format).
+ This should allow any free-form string.
+ pattern: '.*'
+# String formats
+hed_version:
+ display_name: HED Version
+ description: |
+ The version string of the used HED schema.
+ pattern: '^(?:[a-zA-Z]+:)?(?:[a-zA-Z]+_)?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\
+ (?:-(?:(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?\
+ (?:\+(?:[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
+bids_uri:
+ display_name: BIDS uniform resource indicator
+ description: |
+ A BIDS uniform resource indicator.
+
+ The validation for this format is minimal.
+ It simply ensures that the value is a string with any characters that may appear in a valid URI,
+ starting with "bids:".
+ pattern: 'bids:[0-9a-zA-Z/#:\?\_\-\.]+'
+dataset_relative:
+ display_name: Path relative to the BIDS dataset directory
+ description: |
+ A path to a file, relative to the dataset directory.
+
+ The validation for this format is minimal.
+ It simply ensures that the value is a string with any characters that may appear in a valid path,
+ without starting with "/" (an absolute path).
+ pattern: '(?!/)[0-9a-zA-Z/\_\-\.]+'
+date:
+ display_name: Date
+ description: |
+ A date in the form `"YYYY-MM-DD[Z]"`,
+ where [Z] is an optional, valid timezone code.
+ pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}([A-Z]{2,4})?'
+datetime:
+ display_name: Datetime
+ description: |
+ A datetime in the form `"YYYY-MM-DDThh:mm:ss[.000000][Z]"`,
+ where [.000000] is an optional subsecond resolution between 1 and 6 decimal points,
+ and [Z] is an optional, valid timezone code.
+ pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T(?:2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9](\.[0-9]{1,6})?([A-Z]{2,4})?'
+file_relative:
+ display_name: Path relative to the parent file
+ description: |
+ A path to a file, relative to the file in which the field is defined.
+
+ The validation for this format is minimal.
+ It simply ensures that the value is a string with any characters that may appear in a valid path,
+ without starting with "/" (an absolute path).
+ pattern: '(?!/)[0-9a-zA-Z/\_\-\.]+'
+participant_relative:
+ display_name: Path relative to the participant directory
+ description: |
+ A path to a file, relative to the participant's directory in the dataset.
+
+ The validation for this format is minimal.
+ It simply ensures that the value is a string with any characters that may appear in a valid path,
+ without starting with "/" (an absolute path) or "sub/"
+ (a relative path starting with the participant directory, rather than relative to that directory).
+ pattern: '(?!/)(?!sub-)[0-9a-zA-Z/\_\-\.]+'
+rrid:
+ display_name: Research resource identifier
+ description: |
+ A [research resource identifier](https://scicrunch.org/resources).
+ pattern: 'RRID:.+_.+'
+stimuli_relative:
+ display_name: Path relative to the stimuli directory
+ description: |
+ A path to a stimulus file, relative to a `/stimuli` directory somewhere.
+
+ The validation for this format is minimal.
+ It simply ensures that the value is a string with any characters that may appear in a valid path,
+ without starting with "/" (an absolute path) or "stimuli/"
+ (a relative path starting with the stimuli directory, rather than relative to that directory).
+ pattern: '(?!/)(?!stimuli/)[0-9a-zA-Z/\_\-\.]+'
+time:
+ display_name: Time
+ description: |
+ A time in the form `"hh:mm:ss"`.
+ pattern: '(?:2[0-3]|[01]?[0-9]):[0-5][0-9]:[0-5][0-9]'
+unit:
+ display_name: A standardized unit
+ description: |
+ A unit.
+ SI units in CMIXF formatting are RECOMMENDED
+ (see [Units](SPEC_ROOT/common-principles.md#units)).
+
+ Currently this matches any string.
+
+ TODO: Somehow reference the actual unit options in the Units appendix.
+ pattern: '.*'
+uri:
+ display_name: Uniform resource indicator
+ description: |
+ A uniform resource indicator.
+ pattern: '(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?'
diff --git a/bep32v01/ressources/schema/objects/metadata.yaml b/bep32v01/ressources/schema/objects/metadata.yaml
new file mode 100644
index 00000000..1c0d84e0
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/metadata.yaml
@@ -0,0 +1,3708 @@
+---
+# This file defines valid BIDS metadata fields.
+# These definitions include the field names, their descriptions, and valid values.
+# This file **does not** define how and when metadata fields can be used with a given file.
+ACCELChannelCount:
+ name: ACCELChannelCount
+ display_name: Acceleration channel count
+ description: |
+ Number of acceleration channels.
+ type: integer
+ minimum: 0
+Acknowledgements:
+ name: Acknowledgements
+ display_name: Acknowledgements
+ description: |
+ Text acknowledging contributions of individuals or institutions beyond
+ those listed in Authors or Funding.
+ type: string
+AcquisitionDuration:
+ name: AcquisitionDuration
+ display_name: Acquisition Duration
+ description: |
+ Duration (in seconds) of volume acquisition.
+ Corresponds to DICOM Tag 0018, 9073 `Acquisition Duration`.
+ This field is mutually exclusive with `"RepetitionTime"`.
+ type: number
+ exclusiveMinimum: 0
+ unit: s
+AcquisitionMode:
+ name: AcquisitionMode
+ display_name: Acquisition Mode
+ description: |
+ Type of acquisition of the PET data (for example, `"list mode"`).
+ type: string
+AcquisitionVoxelSize:
+ name: AcquisitionVoxelSize
+ display_name: Acquisition Voxel Size
+ description: |
+ An array of numbers with a length of 3, in millimeters.
+ This parameter denotes the original acquisition voxel size,
+ excluding any inter-slice gaps and before any interpolation or resampling
+ within reconstruction or image processing.
+ Any point spread function effects, for example due to T2-blurring,
+ that would decrease the effective resolution are not considered here.
+ type: array
+ minItems: 3
+ maxItems: 3
+ items:
+ type: number
+ exclusiveMinimum: 0
+ unit: mm
+Anaesthesia:
+ name: Anaesthesia
+ display_name: Anaesthesia
+ description: |
+ Details of anaesthesia used, if any.
+ type: string
+AnalyticalApproach:
+ name: AnalyticalApproach
+ display_name: Analytical Approach
+ description: |
+ Methodology or methodologies used to analyze the `"GeneticLevel"`.
+ Values MUST be taken from the
+ [database of Genotypes and Phenotypes
+ (dbGaP)](https://www.ncbi.nlm.nih.gov/gap/advanced)
+ under /Study/Molecular Data Type (for example, SNP Genotypes (Array) or
+ Methylation (CpG).
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+AnatomicalLandmarkCoordinateSystem:
+ name: AnatomicalLandmarkCoordinateSystem
+ display_name: Anatomical Landmark Coordinate System
+ description: |
+ Defines the coordinate system for the anatomical landmarks.
+ See the [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `"AnatomicalLandmarkCoordinateSystemDescription"`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+AnatomicalLandmarkCoordinateSystemDescription:
+ name: AnatomicalLandmarkCoordinateSystemDescription
+ display_name: Anatomical Landmark Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+AnatomicalLandmarkCoordinateUnits:
+ name: AnatomicalLandmarkCoordinateUnits
+ display_name: Anatomical Landmark Coordinate Units
+ description: |
+ Units of the coordinates of `"AnatomicalLandmarkCoordinateSystem"`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+AnatomicalLandmarkCoordinates:
+ name: AnatomicalLandmarkCoordinates
+ display_name: Anatomical Landmark Coordinates
+ description: |
+ Key-value pairs of the labels and 3-D digitized locations of anatomical landmarks,
+ interpreted following the `"AnatomicalLandmarkCoordinateSystem"`
+ (for example, `{"NAS": [12.7,21.3,13.9], "LPA": [5.2,11.3,9.6],
+ "RPA": [20.2,11.3,9.1]}`.
+ Each array MUST contain three numeric values corresponding to x, y, and z
+ axis of the coordinate system in that exact order.
+ type: object
+ additionalProperties:
+ type: array
+ items:
+ type: number
+ minItems: 3
+ maxItems: 3
+# Redefinition of AnatomicalLandmarkCoordinates for MRI data
+AnatomicalLandmarkCoordinates__mri:
+ name: AnatomicalLandmarkCoordinates
+ display_name: Anatomical Landmark Coordinates
+ description: |
+ Key-value pairs of any number of additional anatomical landmarks and their
+ coordinates in voxel units (where first voxel has index 0,0,0)
+ relative to the associated anatomical MRI
+ (for example, `{"AC": [127,119,149], "PC": [128,93,141],
+ "IH": [131,114,206]}`, or `{"NAS": [127,213,139], "LPA": [52,113,96],
+ "RPA": [202,113,91]}`).
+ Each array MUST contain three numeric values corresponding to x, y, and z
+ axis of the coordinate system in that exact order.
+ type: object
+ additionalProperties:
+ type: array
+ items:
+ type: number
+ minItems: 3
+ maxItems: 3
+ANGACCELChannelCount:
+ name: ANGACCELChannelCount
+ display_name: Angular acceleration channel count
+ description: |
+ Number of angular acceleration channels.
+ type: integer
+ minimum: 0
+ArterialSpinLabelingType:
+ name: ArterialSpinLabelingType
+ display_name: Arterial Spin Labeling Type
+ description: |
+ The arterial spin labeling type.
+ type: string
+ enum:
+ - $ref: objects.enums.CASL.value
+ - $ref: objects.enums.PCASL.value
+ - $ref: objects.enums.PASL.value
+AssociatedEmptyRoom:
+ name: AssociatedEmptyRoom
+ display_name: Associated Empty Room
+ description: |
+ One or more [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri)
+ pointing to empty-room file(s) associated with the subject's MEG recording.
+ Using forward-slash separated paths relative to the dataset root is
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ anyOf:
+ - type: array
+ items:
+ anyOf:
+ - type: string
+ format: dataset_relative
+ - type: string
+ format: bids_uri
+ - type: string
+ format: dataset_relative
+ - type: string
+ format: bids_uri
+AttenuationCorrection:
+ name: AttenuationCorrection
+ display_name: Attenuation Correction
+ description: |
+ Short description of the attenuation correction method used.
+ type: string
+AttenuationCorrectionMethodReference:
+ name: AttenuationCorrectionMethodReference
+ display_name: Attenuation Correction Method Reference
+ description: |
+ Reference paper for the attenuation correction method used.
+ type: string
+Authors:
+ name: Authors
+ display_name: Authors
+ description: |
+ List of individuals who contributed to the creation/curation of the dataset.
+ type: array
+ items:
+ type: string
+B0FieldIdentifier:
+ name: B0FieldIdentifier
+ display_name: B0 Field Identifier
+ description: |
+ The presence of this key states that this particular 3D or 4D image MAY be
+ used for fieldmap estimation purposes.
+ Each `"B0FieldIdentifier"` MUST be a unique string within one participant's tree,
+ shared only by the images meant to be used as inputs for the estimation of a
+ particular instance of the *B0 field* estimation.
+ It is RECOMMENDED to derive this identifier from DICOM Tags, for example,
+ DICOM tag 0018, 1030 `Protocol Name`, or DICOM tag 0018, 0024 `Sequence Name`
+ when the former is not defined (for example, in GE devices.)
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+B0FieldSource:
+ name: B0FieldSource
+ display_name: B0 Field Source
+ description: |
+ At least one existing `"B0FieldIdentifier"` defined by images in the
+ participant's tree.
+ This field states the *B0 field* estimation designated by the
+ `"B0FieldIdentifier"` that may be used to correct the dataset for distortions
+ caused by B0 inhomogeneities.
+ `"B0FieldSource"` and `"B0FieldIdentifier"` MAY both be present for images that
+ are used to estimate their own B0 field, for example, in "pepolar"
+ acquisitions.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+BIDSVersion:
+ name: BIDSVersion
+ display_name: BIDS Version
+ description: |
+ The version of the BIDS standard that was used.
+ type: string
+BackgroundSuppression:
+ name: BackgroundSuppression
+ display_name: Background Suppression
+ description: |
+ Boolean indicating if background suppression is used.
+ type: boolean
+BackgroundSuppressionNumberPulses:
+ name: BackgroundSuppressionNumberPulses
+ display_name: Background Suppression Number Pulses
+ description: |
+ The number of background suppression pulses used.
+ Note that this excludes any effect of background suppression pulses applied
+ before the labeling.
+ type: number
+ minimum: 0
+BackgroundSuppressionPulseTime:
+ name: BackgroundSuppressionPulseTime
+ display_name: Background Suppression Pulse Time
+ description: |
+ Array of numbers containing timing, in seconds,
+ of the background suppression pulses with respect to the start of the
+ labeling.
+ In case of multi-PLD with different background suppression pulse times,
+ only the pulse time of the first PLD should be defined.
+ type: array
+ items:
+ type: number
+ minimum: 0
+ unit: s
+BasedOn:
+ name: BasedOn
+ display_name: Based On
+ description: |
+ List of files in a file collection to generate the map.
+ Fieldmaps are also listed, if involved in the processing.
+ This field is DEPRECATED, and this metadata SHOULD be recorded in the
+ `Sources` field using [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri)
+ to distinguish sources from different datasets.
+ anyOf:
+ - type: string
+ format: participant_relative
+ - type: array
+ items:
+ type: string
+ format: participant_relative
+BloodDensity:
+ name: BloodDensity
+ display_name: Blood Density
+ description: |
+ Measured blood density. Unit of blood density should be in `"g/mL"`.
+ type: number
+ unit: g/mL
+BodyPart:
+ name: BodyPart
+ display_name: Body Part
+ description: |
+ Body part of the organ / body region scanned.
+ type: string
+BodyPartDetails:
+ name: BodyPartDetails
+ display_name: Body Part Details
+ description: |
+ Additional details about body part or location (for example: `"corpus callosum"`).
+ type: string
+BodyPartDetailsOntology:
+ name: BodyPartDetailsOntology
+ display_name: Body Part Details Ontology
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator) of ontology used for
+ BodyPartDetails (for example: `"https://www.ebi.ac.uk/ols/ontologies/uberon"`).
+ type: string
+ format: uri
+BolusCutOffDelayTime:
+ name: BolusCutOffDelayTime
+ display_name: Bolus Cut Off Delay Time
+ description: |
+ Duration between the end of the labeling and the start of the bolus cut-off
+ saturation pulse(s), in seconds.
+ This can be a number or array of numbers, of which the values must be
+ non-negative and monotonically increasing, depending on the number of bolus
+ cut-off saturation pulses.
+ For Q2TIPS, only the values for the first and last bolus cut-off saturation
+ pulses are provided.
+ Based on DICOM Tag 0018, 925F `ASL Bolus Cut-off Delay Time`.
+ anyOf:
+ - type: number
+ minimum: 0
+ unit: s
+ - type: array
+ items:
+ type: number
+ unit: s
+ minimum: 0
+BolusCutOffFlag:
+ name: BolusCutOffFlag
+ display_name: Bolus Cut Off Flag
+ description: |
+ Boolean indicating if a bolus cut-off technique is used.
+ Corresponds to DICOM Tag 0018, 925C `ASL Bolus Cut-off Flag`.
+ type: boolean
+BolusCutOffTechnique:
+ name: BolusCutOffTechnique
+ display_name: Bolus Cut Off Technique
+ description: |
+ Name of the technique used, for example `"Q2TIPS"`, `"QUIPSS"`, `"QUIPSSII"`.
+ Corresponds to DICOM Tag 0018, 925E `ASL Bolus Cut-off Technique`.
+ type: string
+BrainLocation:
+ name: BrainLocation
+ display_name: Brain Location
+ description: |
+ Refers to the location in space of the `"TissueOrigin"`.
+ Values may be an MNI coordinate,
+ a label taken from the
+ [Allen Brain Atlas](https://atlas.brain-map.org/atlas?atlas=265297125&plate=\
+ 112360888&structure=4392&x=40348.15104166667&y=46928.75&zoom=-7&resolution=\
+ 206.60&z=3),
+ or layer to refer to layer-specific gene expression,
+ which can also tie up with laminar fMRI.
+ type: string
+CASLType:
+ name: CASLType
+ display_name: CASL Type
+ description: |
+ Describes if a separate coil is used for labeling.
+ type: string
+ enum:
+ - $ref: objects.enums.single_coil.value
+ - $ref: objects.enums.double_coil.value
+CapManufacturer:
+ name: CapManufacturer
+ display_name: Cap Manufacturer
+ description: |
+ Name of the cap manufacturer (for example, `"EasyCap"`).
+ type: string
+CapManufacturersModelName:
+ name: CapManufacturersModelName
+ display_name: Cap Manufacturers Model Name
+ description: |
+ Manufacturer's designation of the cap model
+ (for example, `"actiCAP 64 Ch Standard-2"`).
+ type: string
+CellType:
+ name: CellType
+ display_name: Cell Type
+ description: |
+ Describes the type of cell analyzed.
+ Values SHOULD come from the
+ [cell ontology](https://obofoundry.org/ontology/cl.html).
+ type: string
+ChunkTransformationMatrix:
+ name: ChunkTransformationMatrix
+ display_name: Chunk Transformation Matrix
+ description: |
+ 3x3 or 4x4 affine transformation matrix describing spatial chunk transformation,
+ for 2D and 3D respectively (for examples: `[[2, 0, 0], [0, 3, 0], [0, 0, 1]]`
+ in 2D for 2x and 3x scaling along the first and second axis respectively; or
+ `[[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 1]]` in 3D for 2x and 3x
+ scaling along the second and third axis respectively).
+ Note that non-spatial dimensions like time and channel are not included in the
+ transformation matrix.
+ anyOf:
+ - type: array
+ minItems: 3
+ maxItems: 3
+ items:
+ type: array
+ minItems: 3
+ maxItems: 3
+ items:
+ type: number
+ - type: array
+ minItems: 4
+ maxItems: 4
+ items:
+ type: array
+ minItems: 4
+ maxItems: 4
+ items:
+ type: number
+ChunkTransformationMatrixAxis:
+ name: ChunkTransformationMatrixAxis
+ display_name: Chunk Transformation Matrix Axis
+ description: |
+ Describe the axis of the ChunkTransformationMatrix
+ (for examples: `["X", "Y"]` or `["Z", "Y", "X"]`).
+ type: array
+ minItems: 2
+ maxItems: 3
+ items:
+ type: string
+Code:
+ name: Code
+ display_name: Code
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ of the code used to present the stimuli.
+ Persistent identifiers such as DOIs are preferred.
+ If multiple versions of code may be hosted at the same location,
+ revision-specific URIs are recommended.
+ type: string
+ format: uri
+CogAtlasID:
+ name: CogAtlasID
+ display_name: Cognitive Atlas ID
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ of the corresponding [Cognitive Atlas](https://www.cognitiveatlas.org/)
+ Task term.
+ type: string
+ format: uri
+CogPOID:
+ name: CogPOID
+ display_name: Cognitive Paradigm Ontology ID
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ of the corresponding [CogPO](http://www.cogpo.org/) term.
+ type: string
+ format: uri
+CoilCombinationMethod:
+ name: CoilCombinationMethod
+ display_name: Coil Combination Method
+ description: |
+ Almost all fMRI studies using phased-array coils use root-sum-of-squares
+ (rSOS) combination, but other methods exist.
+ The image reconstruction is changed by the coil combination method
+ (as for the matrix coil mode above),
+ so anything non-standard should be reported.
+ type: string
+Columns:
+ name: Columns
+ display_name: Columns
+ description: |
+ Names of columns in file.
+ type: array
+ items:
+ type: string
+ContinuousHeadLocalization:
+ name: ContinuousHeadLocalization
+ display_name: Continuous Head Localization
+ description: |
+ `true` or `false` value indicating whether continuous head localisation
+ was performed.
+ type: boolean
+ContrastBolusIngredient:
+ name: ContrastBolusIngredient
+ display_name: Contrast Bolus Ingredient
+ description: |
+ Active ingredient of agent.
+ Corresponds to DICOM Tag 0018, 1048 `Contrast/Bolus Ingredient`.
+ type: string
+ enum:
+ - $ref: objects.enums.IODINE.value
+ - $ref: objects.enums.GADOLINIUM.value
+ - $ref: objects.enums.CARBON_DIOXIDE.value
+ - $ref: objects.enums.BARIUM.value
+ - $ref: objects.enums.XENON.value
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ - UNKNOWN
+ - NONE
+DCOffsetCorrection:
+ name: DCOffsetCorrection
+ display_name: DC Offset Correction
+ description: |
+ A description of the method (if any) used to correct for a DC offset.
+ If the method used was subtracting the mean value for each channel,
+ use "mean".
+ type: string
+DatasetDOI:
+ name: DatasetDOI
+ display_name: DatasetDOI
+ description: |
+ The Digital Object Identifier of the dataset (not the corresponding paper).
+ DOIs SHOULD be expressed as a valid
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator);
+ bare DOIs such as `10.0.2.3/dfjj.10` are
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ type: string
+ format: uri
+DatasetLinks:
+ name: DatasetLinks
+ display_name: Dataset Links
+ description: |
+ Used to map a given `` from a [BIDS URI](SPEC_ROOT/common-principles.md#bids-uri)
+ of the form `bids::path/within/dataset` to a local or remote location.
+ The ``: `""` (an empty string) is a reserved keyword that MUST NOT be a key in
+ `DatasetLinks` (example: `bids::path/within/dataset`).
+ type: object
+ additionalProperties:
+ type: string
+ format: uri
+DatasetType:
+ name: DatasetType
+ display_name: Dataset Type
+ description: |
+ The interpretation of the dataset.
+ For backwards compatibility, the default value is `"raw"`.
+ type: string
+ enum:
+ - $ref: objects.enums.raw.value
+ - $ref: objects.enums.derivative.value
+DecayCorrectionFactor:
+ name: DecayCorrectionFactor
+ display_name: Decay Correction Factor
+ description: |
+ Decay correction factor for each frame.
+ type: array
+ items:
+ type: number
+DelayAfterTrigger:
+ name: DelayAfterTrigger
+ display_name: Delay After Trigger
+ description: |
+ Duration (in seconds) from trigger delivery to scan onset.
+ This delay is commonly caused by adjustments and loading times.
+ This specification is entirely independent of
+ `"NumberOfVolumesDiscardedByScanner"` or `"NumberOfVolumesDiscardedByUser"`,
+ as the delay precedes the acquisition.
+ type: number
+ unit: s
+DelayTime:
+ name: DelayTime
+ display_name: Delay Time
+ description: |
+ User specified time (in seconds) to delay the acquisition of data for the
+ following volume.
+ If the field is not present it is assumed to be set to zero.
+ Corresponds to Siemens CSA header field `lDelayTimeInTR`.
+ This field is REQUIRED for sparse sequences using the `"RepetitionTime"` field
+ that do not have the `"SliceTiming"` field set to allowed for accurate
+ calculation of "acquisition time".
+ This field is mutually exclusive with `"VolumeTiming"`.
+ type: number
+ unit: s
+Delimiter:
+ name: Delimiter
+ display_name: Delimiter
+ description: |
+ If rows in a column may be interpreted as a lists of values, the character that
+ separates one value from the next.
+ type: string
+Density:
+ name: Density
+ display_name: Density
+ description: |
+ Specifies the interpretation of the density keyword.
+ If an object is used, then the keys should be values for the `den` entity
+ and values should be descriptions of those `den` values.
+ anyOf:
+ - type: string
+ - type: object
+ additionalProperties:
+ type: string
+Derivative:
+ name: Derivative
+ display_name: Derivative
+ description: |
+ Indicates that values in the corresponding column are transformations of values
+ from other columns (for example a summary score based on a subset of items in a
+ questionnaire).
+ type: boolean
+Description:
+ name: Description
+ display_name: Description
+ description: |
+ Free-form natural language description.
+ type: string
+DetectorType:
+ name: DetectorType
+ display_name: Detector Type
+ description: |
+ Type of detector. This is a free form description with the following suggested terms:
+ `"SiPD"`, `"APD"`. Preferably a specific model/part number is supplied.
+ If individual channels have different `DetectorType`,
+ then the field here should be specified as `"mixed"`
+ and this column should be included in `optodes.tsv`.
+ anyOf:
+ - type: string
+ format: unit
+ - type: string
+ enum:
+ - $ref: objects.enums.mixed.value
+DeviceSerialNumber:
+ name: DeviceSerialNumber
+ display_name: Device Serial Number
+ description: |
+ The serial number of the equipment that produced the measurements.
+ A pseudonym can also be used to prevent the equipment from being
+ identifiable, so long as each pseudonym is unique within the dataset.
+ type: string
+DewarPosition:
+ name: DewarPosition
+ display_name: Dewar Position
+ description: |
+ Position of the dewar during the MEG scan:
+ `"upright"`, `"supine"` or `"degrees"` of angle from vertical:
+ for example on CTF systems, `"upright=15°, supine=90°"`.
+ type: string
+DigitizedHeadPoints:
+ name: DigitizedHeadPoints
+ display_name: Digitized Head Points
+ description: |
+ `true` or `false` value indicating whether head points outlining the
+ scalp/face surface are contained within this recording.
+ type: boolean
+DigitizedHeadPoints__coordsystem:
+ name: DigitizedHeadPoints
+ display_name: Digitized Head Points
+ description: |
+ Relative path to the file containing the locations of digitized head points
+ collected during the session (for example, `"sub-01_headshape.pos"`).
+ RECOMMENDED for all MEG systems, especially for CTF and BTi/4D.
+ For Neuromag/Elekta/MEGIN, the head points will be stored in the `.fif` file.
+ type: string
+ format: file_relative
+DigitizedHeadPointsCoordinateSystem:
+ name: DigitizedHeadPointsCoordinateSystem
+ display_name: Digitized Head Points Coordinate System
+ description: |
+ Defines the coordinate system for the digitized head points.
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `"DigitizedHeadPointsCoordinateSystemDescription"`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+DigitizedHeadPointsCoordinateSystemDescription:
+ name: DigitizedHeadPointsCoordinateSystemDescription
+ display_name: Digitized Head Points Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+DigitizedHeadPointsCoordinateUnits:
+ name: DigitizedHeadPointsCoordinateUnits
+ display_name: Digitized Head Points Coordinate Units
+ description: |
+ Units of the coordinates of `"DigitizedHeadPointsCoordinateSystem"`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+DigitizedLandmarks:
+ name: DigitizedLandmarks
+ display_name: Digitized Landmarks
+ description: |
+ `true` or `false` value indicating whether anatomical landmark points
+ (fiducials) are contained within this recording.
+ type: boolean
+DispersionConstant:
+ name: DispersionConstant
+ display_name: Dispersion Constant
+ description: |
+ External dispersion time constant resulting from tubing in default unit
+ seconds.
+ type: number
+ unit: s
+DispersionCorrected:
+ name: DispersionCorrected
+ display_name: Dispersion Corrected
+ description: |
+ Boolean flag specifying whether the blood data have been dispersion-corrected.
+ NOTE: not customary for manual samples, and hence should be set to `false`.
+ type: boolean
+DoseCalibrationFactor:
+ name: DoseCalibrationFactor
+ display_name: Dose Calibration Factor
+ description: |
+ Multiplication factor used to transform raw data (in counts/sec) to meaningful unit (Bq/ml).
+ Corresponds to DICOM Tag 0054, 1322 `Dose Calibration Factor`.
+ type: number
+DwellTime:
+ name: DwellTime
+ display_name: Dwell Time
+ description: |
+ Actual dwell time (in seconds) of the receiver per point in the readout
+ direction, including any oversampling.
+ For Siemens, this corresponds to DICOM field 0019, 1018 (in ns).
+ This value is necessary for the optional readout distortion correction of
+ anatomicals in the HCP Pipelines.
+ It also usefully provides a handle on the readout bandwidth,
+ which isn't captured in the other metadata tags.
+ Not to be confused with `"EffectiveEchoSpacing"`, and the frequent mislabeling
+ of echo spacing (which is spacing in the phase encoding direction) as
+ "dwell time" (which is spacing in the readout direction).
+ type: number
+ unit: s
+ECGChannelCount:
+ name: ECGChannelCount
+ display_name: ECG Channel Count
+ description: |
+ Number of ECG channels.
+ type: integer
+ minimum: 0
+ECOGChannelCount:
+ name: ECOGChannelCount
+ display_name: ECOG Channel Count
+ description: |
+ Number of ECoG channels.
+ type: integer
+ minimum: 0
+EEGChannelCount:
+ name: EEGChannelCount
+ display_name: EEG Channel Count
+ description: |
+ Number of EEG channels recorded simultaneously (for example, `21`).
+ type: integer
+ minimum: 0
+EEGCoordinateSystem:
+ name: EEGCoordinateSystem
+ display_name: EEG Coordinate System
+ description: |
+ Defines the coordinate system for the EEG sensors.
+
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `EEGCoordinateSystemDescription`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+EEGCoordinateSystemDescription:
+ name: EEGCoordinateSystemDescription
+ display_name: EEG Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+EEGCoordinateUnits:
+ name: EEGCoordinateUnits
+ display_name: EEG Coordinate Units
+ description: |
+ Units of the coordinates of `EEGCoordinateSystem`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+EEGGround:
+ name: EEGGround
+ display_name: EEG Ground
+ description: |
+ Description of the location of the ground electrode
+ (for example, `"placed on right mastoid (M2)"`).
+ type: string
+EEGPlacementScheme:
+ name: EEGPlacementScheme
+ display_name: EEG Placement Scheme
+ description: |
+ Placement scheme of EEG electrodes.
+ Either the name of a standardized placement system (for example, `"10-20"`)
+ or a list of standardized electrode names (for example, `["Cz", "Pz"]`).
+ type: string
+EEGReference:
+ name: EEGReference
+ display_name: EEG Reference
+ description: |
+ General description of the reference scheme used and (when applicable) of
+ location of the reference electrode in the raw recordings
+ (for example, `"left mastoid"`, `"Cz"`, `"CMS"`).
+ If different channels have a different reference,
+ this field should have a general description and the channel specific
+ reference should be defined in the `channels.tsv` file.
+ type: string
+EMGChannelCount:
+ name: EMGChannelCount
+ display_name: EMG Channel Count
+ description: |
+ Number of EMG channels.
+ type: integer
+ minimum: 0
+EOGChannelCount:
+ name: EOGChannelCount
+ display_name: EOG Channel Count
+ description: |
+ Number of EOG channels.
+ type: integer
+ minimum: 0
+EchoTime:
+ name: EchoTime
+ display_name: Echo Time
+ description: |
+ 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](SPEC_ROOT/appendices/file-collections.md)
+ where the value of this field is iterated using the
+ [`echo` entity](SPEC_ROOT/appendices/entities.md#echo).
+ 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](SPEC_ROOT/modality-specific-files/magnetic-resonance-imaging-data.md#\
+ arterial-spin-labeling-perfusion-data)
+ or variable echo time fMRI sequences.
+ anyOf:
+ - type: number
+ unit: s
+ exclusiveMinimum: 0
+ - type: array
+ items:
+ type: number
+ unit: s
+ exclusiveMinimum: 0
+EchoTime1:
+ name: EchoTime1
+ display_name: Echo Time1
+ description: |
+ The time (in seconds) when the first (shorter) echo occurs.
+ type: number
+ unit: s
+ exclusiveMinimum: 0
+EchoTime2:
+ name: EchoTime2
+ display_name: Echo Time2
+ description: |
+ The time (in seconds) when the second (longer) echo occurs.
+ type: number
+ unit: s
+ exclusiveMinimum: 0
+# Redefinition of EchoTime for fieldmap data
+EchoTime__fmap:
+ name: EchoTime
+ display_name: Echo Time
+ description: |
+ The time (in seconds) when the echo corresponding to this map was acquired.
+ type: number
+ unit: s
+ exclusiveMinimum: 0
+EffectiveEchoSpacing:
+ name: EffectiveEchoSpacing
+ display_name: Effective Echo Spacing
+ description: |
+ The "effective" sampling interval, specified in seconds,
+ between lines in the phase-encoding direction,
+ defined based on the size of the reconstructed image in the phase direction.
+ It is frequently, but incorrectly, referred to as "dwell time"
+ (see the `"DwellTime"` parameter for actual dwell time).
+ It is required for unwarping distortions using field maps.
+ Note that beyond just in-plane acceleration,
+ a variety of other manipulations to the phase encoding need to be accounted
+ for properly, including partial fourier, phase oversampling,
+ phase resolution, phase field-of-view and interpolation.
+ type: number
+ exclusiveMinimum: 0
+ unit: s
+ElectricalStimulation:
+ name: ElectricalStimulation
+ display_name: Electrical Stimulation
+ description: |
+ Boolean field to specify if electrical stimulation was done during the
+ recording (options are `true` or `false`). Parameters for event-like
+ stimulation should be specified in the `events.tsv` file.
+ type: boolean
+ElectricalStimulationParameters:
+ name: ElectricalStimulationParameters
+ display_name: Electrical Stimulation Parameters
+ description: |
+ Free form description of stimulation parameters, such as frequency or shape.
+ Specific onsets can be specified in the `events.tsv` file.
+ Specific shapes can be described here in freeform text.
+ type: string
+ElectrodeManufacturer:
+ name: ElectrodeManufacturer
+ display_name: Electrode Manufacturer
+ description: |
+ Can be used if all electrodes are of the same manufacturer
+ (for example, `"AD-TECH"`, `"DIXI"`).
+ If electrodes of different manufacturers are used,
+ please use the corresponding table in the `_electrodes.tsv` file.
+ type: string
+ElectrodeManufacturersModelName:
+ name: ElectrodeManufacturersModelName
+ display_name: Electrode Manufacturers Model Name
+ description: |
+ If different electrode types are used,
+ please use the corresponding table in the `_electrodes.tsv` file.
+ type: string
+EpochLength:
+ name: EpochLength
+ display_name: Epoch Length
+ description: |
+ Duration of individual epochs in seconds (for example, `1`)
+ in case of epoched data.
+ If recording was continuous or discontinuous, leave out the field.
+ type: number
+ minimum: 0
+EstimationAlgorithm:
+ name: EstimationAlgorithm
+ display_name: Estimation Algorithm
+ description: |
+ Type of algorithm used to perform fitting
+ (for example, `"linear"`, `"non-linear"`, `"LM"` and such).
+ type: string
+EstimationReference:
+ name: EstimationReference
+ display_name: Estimation Reference
+ description: |
+ Reference to the study/studies on which the implementation is based.
+ type: string
+EthicsApprovals:
+ name: EthicsApprovals
+ display_name: Ethics Approvals
+ description: |
+ List of ethics committee approvals of the research protocols and/or
+ protocol identifiers.
+ type: array
+ items:
+ type: string
+FiducialsCoordinateSystem:
+ name: FiducialsCoordinateSystem
+ display_name: Fiducials Coordinate System
+ description: |
+ Defines the coordinate system for the fiducials.
+ Preferably the same as the `"EEGCoordinateSystem"`.
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `"FiducialsCoordinateSystemDescription"`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+FiducialsCoordinateSystemDescription:
+ name: FiducialsCoordinateSystemDescription
+ display_name: Fiducials Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+FiducialsCoordinateUnits:
+ name: FiducialsCoordinateUnits
+ display_name: Fiducials Coordinate Units
+ description: |
+ Units in which the coordinates that are listed in the field
+ `"FiducialsCoordinateSystem"` are represented.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+FiducialsCoordinates:
+ name: FiducialsCoordinates
+ display_name: Fiducials Coordinates
+ description: |
+ Key-value pairs of the labels and 3-D digitized position of anatomical
+ landmarks, interpreted following the `"FiducialsCoordinateSystem"`
+ (for example, `{"NAS": [12.7,21.3,13.9], "LPA": [5.2,11.3,9.6],
+ "RPA": [20.2,11.3,9.1]}`).
+ Each array MUST contain three numeric values corresponding to x, y, and z
+ axis of the coordinate system in that exact order.
+ type: object
+ additionalProperties:
+ type: array
+ items:
+ type: number
+ minItems: 3
+ maxItems: 3
+FiducialsDescription:
+ name: FiducialsDescription
+ display_name: Fiducials Description
+ description: |
+ Free-form text description of how the fiducials such as vitamin-E capsules
+ were placed relative to anatomical landmarks,
+ and how the position of the fiducials were measured
+ (for example, `"both with Polhemus and with T1w MRI"`).
+ type: string
+FlipAngle:
+ name: FlipAngle
+ display_name: Flip Angle
+ description: |
+ Flip angle (FA) for the acquisition, specified in degrees.
+ Corresponds to: DICOM Tag 0018, 1314 `Flip Angle`.
+ 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](SPEC_ROOT/appendices/file-collections.md)
+ where the value of this field is iterated using the
+ [`flip` entity](SPEC_ROOT/appendices/entities.md#flip).
+ 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](SPEC_ROOT/modality-specific-files/magnetic-resonance-imaging-data.md#\
+ arterial-spin-labeling-perfusion-data)
+ or variable flip angle fMRI sequences.
+ anyOf:
+ - type: number
+ unit: degree
+ exclusiveMinimum: 0
+ maximum: 360
+ - type: array
+ items:
+ type: number
+ unit: degree
+ exclusiveMinimum: 0
+ maximum: 360
+FrameDuration:
+ name: FrameDuration
+ display_name: Frame Duration
+ description: |
+ Time duration of each frame in default unit seconds.
+ This corresponds to DICOM Tag 0018, 1242 `Actual Frame Duration` converted
+ to seconds.
+ type: array
+ items:
+ type: number
+ unit: s
+FrameTimesStart:
+ name: FrameTimesStart
+ display_name: Frame Times Start
+ description: |
+ Start times for all frames relative to `"TimeZero"` in default unit seconds.
+ type: array
+ items:
+ type: number
+ unit: s
+Funding:
+ name: Funding
+ display_name: Funding
+ description: |
+ List of sources of funding (grant numbers).
+ type: array
+ items:
+ type: string
+GeneratedBy:
+ name: GeneratedBy
+ display_name: Generated By
+ description: |
+ Used to specify provenance of the dataset.
+ type: array
+ minItems: 1
+ items:
+ type: object
+ required_fields: [Name]
+ recommended_fields: [Version]
+ properties:
+ Name:
+ name: Name
+ description: |
+ Name of the pipeline or process that generated the outputs. Use `"Manual"` to
+ indicate the derivatives were generated by hand, or adjusted manually after an
+ initial run of an automated pipeline.
+ type: string
+ Version:
+ name: Version
+ description: Version of the pipeline
+ type: string
+ Description:
+ name: Description
+ description: |
+ Plain-text description of the pipeline or process that generated the outputs.
+ RECOMMENDED if `Name` is `"Manual"`.
+ type: string
+ CodeURL:
+ name: CodeURL
+ description: URL where the code used to generate the dataset may be found.
+ type: string
+ format: uri
+ Container:
+ name: Container
+ description: |
+ Used to specify the location and relevant attributes of software container image
+ used to produce the dataset. Valid keys in this object include `Type`, `Tag` and
+ [`URI`][uri] with [string][] values.
+ type: object
+ recommended_fields:
+ - Type
+ - Tag
+ - URI
+ properties:
+ Type:
+ type: string
+ Tag:
+ type: string
+ URI:
+ type: string
+ format: uri
+GeneticLevel:
+ name: GeneticLevel
+ display_name: Genetic Level
+ description: |
+ Describes the level of analysis.
+ Values MUST be one of `"Genetic"`, `"Genomic"`, `"Epigenomic"`,
+ `"Transcriptomic"`, `"Metabolomic"`, or `"Proteomic"`.
+
+ For more information on these levels, see
+ [Multi-omics approaches to disease](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-017-1215-1)
+ by Hasin et al. 2017.
+ anyOf:
+ - $ref: objects.enums._GeneticLevelEnum
+ - type: array
+ items:
+ $ref: objects.enums._GeneticLevelEnum
+Genetics:
+ name: Genetics
+ display_name: Genetics
+ description: |
+ An object containing information about the genetics descriptor.
+ type: object
+ required_fields: [Dataset]
+ properties:
+ Dataset:
+ name: Dataset
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ where data can be retrieved.
+ type: string
+ format: uri
+ Database:
+ name: Database
+ description: |
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ of database where the dataset is hosted.
+ type: string
+ format: uri
+ Descriptors:
+ name: Descriptors
+ description: |
+ List of relevant descriptors (for example, journal articles) for dataset
+ using a valid
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ when possible.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+GradientSetType:
+ name: GradientSetType
+ display_name: Gradient Set Type
+ description: |
+ It should be possible to infer the gradient coil from the scanner model.
+ If not, for example because of a custom upgrade or use of a gradient
+ insert set, then the specifications of the actual gradient coil should be
+ reported independently.
+ type: string
+GYROChannelCount:
+ name: GYROChannelCount
+ display_name: Gyrometer Channel Count
+ description: |
+ Number of gyrometer channels.
+ type: integer
+ minimum: 0
+HED:
+ name: HED
+ display_name: HED
+ description: |
+ Hierarchical Event Descriptor (HED) information,
+ see the [HED Appendix](SPEC_ROOT/appendices/hed.md) for details.
+ anyOf:
+ - type: string
+ - type: object
+ additionalProperties:
+ type: string
+HEDVersion:
+ name: HEDVersion
+ display_name: HED Version
+ description: |
+ If HED tags are used:
+ The version of the HED schema used to validate HED tags for study.
+ May include a single schema or a base schema and one or more library schema.
+ anyOf:
+ - type: string
+ format: hed_version
+ - type: array
+ items:
+ type: string
+ format: hed_version
+Haematocrit:
+ name: Haematocrit
+ display_name: Haematocrit
+ description: |
+ Measured haematocrit, meaning the volume of erythrocytes divided by the
+ volume of whole blood.
+ type: number
+HardcopyDeviceSoftwareVersion:
+ name: HardcopyDeviceSoftwareVersion
+ display_name: Hardcopy Device Software Version
+ description: |
+ Manufacturer's designation of the software of the device that created this
+ Hardcopy Image (the printer).
+ Corresponds to DICOM Tag 0018, 101A `Hardcopy Device Software Version`.
+ type: string
+HardwareFilters:
+ name: HardwareFilters
+ display_name: Hardware Filters
+ description: |
+ Object of temporal hardware filters applied, or `"n/a"` if the data is not
+ available. Each key-value pair in the JSON object is a name of the filter and
+ an object in which its parameters are defined as key-value pairs.
+ For example, `{"Highpass RC filter": {"Half amplitude cutoff (Hz)":
+ 0.0159, "Roll-off": "6dB/Octave"}}`.
+ anyOf:
+ - type: object
+ additionalProperties:
+ type: object
+ - type: string
+ enum:
+ - n/a
+HeadCircumference:
+ name: HeadCircumference
+ display_name: Head Circumference
+ description: |
+ Circumference of the participant's head, expressed in cm (for example, `58`).
+ type: number
+ exclusiveMinimum: 0
+ unit: cm
+HeadCoilCoordinateSystem:
+ name: HeadCoilCoordinateSystem
+ display_name: Head Coil Coordinate System
+ description: |
+ Defines the coordinate system for the head coils.
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `HeadCoilCoordinateSystemDescription`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+HeadCoilCoordinateSystemDescription:
+ name: HeadCoilCoordinateSystemDescription
+ display_name: Head Coil Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the system in greater detail.
+ type: string
+HeadCoilCoordinateUnits:
+ name: HeadCoilCoordinateUnits
+ display_name: Head Coil Coordinate Units
+ description: |
+ Units of the coordinates of `HeadCoilCoordinateSystem`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+HeadCoilCoordinates:
+ name: HeadCoilCoordinates
+ display_name: Head Coil Coordinates
+ description: |
+ Key-value pairs describing head localization coil labels and their
+ coordinates, interpreted following the `HeadCoilCoordinateSystem`
+ (for example, `{"NAS": [12.7,21.3,13.9], "LPA": [5.2,11.3,9.6],
+ "RPA": [20.2,11.3,9.1]}`).
+ Note that coils are not always placed at locations that have a known
+ anatomical name (for example, for Neuromag/Elekta/MEGIN, Yokogawa systems);
+ in that case generic labels can be used
+ (for example, `{"coil1": [12.2,21.3,12.3], "coil2": [6.7,12.3,8.6],
+ "coil3": [21.9,11.0,8.1]}`).
+ Each array MUST contain three numeric values corresponding to x, y, and z
+ axis of the coordinate system in that exact order.
+ type: object
+ additionalProperties:
+ type: array
+ items:
+ type: number
+ minItems: 3
+ maxItems: 3
+HeadCoilFrequency:
+ name: HeadCoilFrequency
+ display_name: Head Coil Frequency
+ description: |
+ List of frequencies (in Hz) used by the head localisation coils
+ ('HLC' in CTF systems, 'HPI' in Neuromag/Elekta/MEGIN, 'COH' in BTi/4D)
+ that track the subject's head position in the MEG helmet
+ (for example, `[293, 307, 314, 321]`).
+ anyOf:
+ - type: number
+ unit: Hz
+ - type: array
+ items:
+ type: number
+ unit: Hz
+HeadStabilization:
+ name: HeadStabilization
+ display_name: Head stabilization
+ description: |
+ Head restraint method used during the experiment
+ to prevent rotation and/or translation of the head.
+ Example: "chin-rest", "head-rest", "bite-bar", "chin-rest and head-rest", "none"
+ type: string
+HowToAcknowledge:
+ name: HowToAcknowledge
+ display_name: How To Acknowledge
+ description: |
+ Text containing instructions on how researchers using this dataset should
+ acknowledge the original authors.
+ This field can also be used to define a publication that should be cited in
+ publications that use the dataset.
+ type: string
+ImageAcquisitionProtocol:
+ name: ImageAcquisitionProtocol
+ display_name: Image Acquisition Protocol
+ description: |
+ Description of the image acquisition protocol or
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ (for example from [protocols.io](https://www.protocols.io/)).
+ type: string
+ImageDecayCorrected:
+ name: ImageDecayCorrected
+ display_name: Image Decay Corrected
+ description: |
+ Boolean flag specifying whether the image data have been decay-corrected.
+ type: boolean
+ImageDecayCorrectionTime:
+ name: ImageDecayCorrectionTime
+ display_name: Image Decay Correction Time
+ description: |
+ Point in time from which the decay correction was applied with respect to
+ `"TimeZero"` in the default unit seconds.
+ type: number
+ unit: s
+Immersion:
+ name: Immersion
+ display_name: Immersion
+ description: |
+ Lens immersion medium. If the file format is OME-TIFF, the value MUST be consistent
+ with the `Immersion` OME metadata field.
+ type: string
+InfusionRadioactivity:
+ name: InfusionRadioactivity
+ display_name: Infusion Radioactivity
+ description: |
+ Amount of radioactivity infused into the patient.
+ This value must be less than or equal to the total injected radioactivity
+ (`"InjectedRadioactivity"`).
+ Units should be the same as `"InjectedRadioactivityUnits"`.
+ type: number
+InfusionSpeed:
+ name: InfusionSpeed
+ display_name: Infusion Speed
+ description: |
+ If given, infusion speed.
+ type: number
+InfusionSpeedUnits:
+ name: InfusionSpeedUnits
+ display_name: Infusion Speed Units
+ description: |
+ Unit of infusion speed (for example, `"mL/s"`).
+ type: string
+ format: unit
+InfusionStart:
+ name: InfusionStart
+ display_name: Infusion Start
+ description: |
+ Time of start of infusion with respect to `"TimeZero"` in the default unit
+ seconds.
+ type: number
+ unit: s
+InjectedMass:
+ name: InjectedMass
+ display_name: Injected Mass
+ description: |
+ Total mass of radiolabeled compound injected into subject (for example, `10`).
+ This can be derived as the ratio of the `"InjectedRadioactivity"` and
+ `"MolarRadioactivity"`.
+ **For those tracers in which injected mass is not available (for example FDG)
+ can be set to `"n/a"`)**.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+InjectedMassPerWeight:
+ name: InjectedMassPerWeight
+ display_name: Injected Mass Per Weight
+ description: |
+ Injected mass per kilogram bodyweight.
+ type: number
+InjectedMassPerWeightUnits:
+ name: InjectedMassPerWeightUnits
+ display_name: Injected Mass Per Weight Units
+ description: |
+ Unit format of the injected mass per kilogram bodyweight
+ (for example, `"ug/kg"`).
+ type: string
+ format: unit
+InjectedMassUnits:
+ name: InjectedMassUnits
+ display_name: Injected Mass Units
+ description: |
+ Unit format of the mass of compound injected (for example, `"ug"` or
+ `"umol"`).
+ **Note this is not required for an FDG acquisition, since it is not available,
+ and SHOULD be set to `"n/a"`**.
+ anyOf:
+ - type: string
+ format: unit
+ - type: string
+ enum:
+ - n/a
+InjectedRadioactivity:
+ name: InjectedRadioactivity
+ display_name: Injected Radioactivity
+ description: |
+ Total amount of radioactivity injected into the patient (for example, `400`).
+ For bolus-infusion experiments, this value should be the sum of all injected
+ radioactivity originating from both bolus and infusion.
+ Corresponds to DICOM Tag 0018, 1074 `Radionuclide Total Dose`.
+ type: number
+InjectedRadioactivityUnits:
+ name: InjectedRadioactivityUnits
+ display_name: Injected Radioactivity Units
+ description: |
+ Unit format of the specified injected radioactivity (for example, `"MBq"`).
+ type: string
+ format: unit
+InjectedVolume:
+ name: InjectedVolume
+ display_name: Injected Volume
+ description: |
+ Injected volume of the radiotracer in the unit `"mL"`.
+ type: number
+ unit: mL
+InjectionEnd:
+ name: InjectionEnd
+ display_name: Injection End
+ description: |
+ Time of end of injection with respect to `"TimeZero"` in the default unit
+ seconds.
+ type: number
+ unit: s
+InjectionStart:
+ name: InjectionStart
+ display_name: Injection Start
+ description: |
+ Time of start of injection with respect to `"TimeZero"` in the default unit
+ seconds.
+ This corresponds to DICOM Tag 0018, 1072 `Contrast/Bolus Start Time`
+ converted to seconds relative to `"TimeZero"`.
+ type: number
+ unit: s
+InstitutionAddress:
+ name: InstitutionAddress
+ display_name: Institution Address
+ description: |
+ The address of the institution in charge of the equipment that produced the
+ measurements.
+ type: string
+InstitutionName:
+ name: InstitutionName
+ display_name: Institution Name
+ description: |
+ The name of the institution in charge of the equipment that produced the
+ measurements.
+ type: string
+InstitutionalDepartmentName:
+ name: InstitutionalDepartmentName
+ display_name: Institutional Department Name
+ description: |
+ The department in the institution in charge of the equipment that produced
+ the measurements.
+ type: string
+Instructions:
+ name: Instructions
+ display_name: Instructions
+ description: |
+ Text of the instructions given to participants before the recording.
+ type: string
+IntendedFor:
+ name: IntendedFor
+ display_name: Intended For
+ description: |
+ The paths to files for which the associated file is intended to be used.
+ Contains one or more [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri).
+ Using forward-slash separated paths relative to the participant subdirectory is
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ anyOf:
+ - type: string
+ format: bids_uri
+ - type: string
+ format: participant_relative
+ - type: array
+ items:
+ anyOf:
+ - type: string
+ format: bids_uri
+ - type: string
+ format: participant_relative
+IntendedFor__ds_relative:
+ name: IntendedFor
+ display_name: Intended For
+ description: |
+ The paths to files for which the associated file is intended to be used.
+ Contains one or more [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri).
+ Using forward-slash separated paths relative to the dataset root is
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ anyOf:
+ - type: string
+ format: bids_uri
+ - type: string
+ format: dataset_relative
+ - type: array
+ items:
+ anyOf:
+ - type: string
+ format: bids_uri
+ - type: string
+ format: dataset_relative
+InversionTime:
+ name: InversionTime
+ display_name: Inversion Time
+ description: |
+ The inversion time (TI) for the acquisition, specified in seconds.
+ Inversion time is the time after the middle of inverting RF pulse to middle
+ of excitation pulse to detect the amount of longitudinal magnetization.
+ Corresponds to DICOM Tag 0018, 0082 `Inversion Time`
+ (please note that the DICOM term is in milliseconds not seconds).
+ type: number
+ unit: s
+ exclusiveMinimum: 0
+JNTANGChannelCount:
+ name: JNTANGChannelCount
+ display_name: Joint angle channel count
+ description: |
+ Number of joint angle channels.
+ type: integer
+ minimum: 0
+LabelingDistance:
+ name: LabelingDistance
+ display_name: Labeling Distance
+ description: |
+ Distance from the center of the imaging slab to the center of the labeling
+ plane (`(P)CASL`) or the leading edge of the labeling slab (`PASL`),
+ in millimeters.
+ If the labeling is performed inferior to the isocenter,
+ this number should be negative.
+ Based on DICOM macro C.8.13.5.14.
+ type: number
+ unit: mm
+LabelingDuration:
+ name: LabelingDuration
+ display_name: Labeling Duration
+ description: |
+ Total duration of the labeling pulse train, in seconds,
+ corresponding to the temporal width of the labeling bolus for
+ `"PCASL"` or `"CASL"`.
+ In case all control-label volumes (or deltam or CBF) have the same
+ `LabelingDuration`, a scalar must be specified.
+ In case the control-label volumes (or deltam or cbf) have a different
+ `"LabelingDuration"`, an array of numbers must be specified,
+ for which any `m0scan` in the timeseries has a `"LabelingDuration"` of zero.
+ In case an array of numbers is provided,
+ its length should be equal to the number of volumes specified in
+ `*_aslcontext.tsv`.
+ Corresponds to DICOM Tag 0018, 9258 `ASL Pulse Train Duration`.
+ anyOf:
+ - type: number
+ minimum: 0
+ unit: s
+ - type: array
+ items:
+ type: number
+ unit: s
+ minimum: 0
+LabelingEfficiency:
+ name: LabelingEfficiency
+ display_name: Labeling Efficiency
+ description: |
+ Labeling efficiency, specified as a number between zero and one,
+ only if obtained externally (for example phase-contrast based).
+ type: number
+ exclusiveMinimum: 0
+LabelingLocationDescription:
+ name: LabelingLocationDescription
+ display_name: Labeling Location Description
+ description: |
+ Description of the location of the labeling plane (`"CASL"` or `"PCASL"`) or
+ the labeling slab (`"PASL"`) that cannot be captured by fields
+ `LabelingOrientation` or `LabelingDistance`.
+ May include a link to an anonymized screenshot of the planning of the
+ labeling slab/plane with respect to the imaging slab or slices
+ `*_asllabeling.*`.
+ Based on DICOM macro C.8.13.5.14.
+ type: string
+LabelingOrientation:
+ name: LabelingOrientation
+ display_name: Labeling Orientation
+ description: |
+ Orientation of the labeling plane (`(P)CASL`) or slab (`PASL`).
+ The direction cosines of a normal vector perpendicular to the ASL labeling
+ slab or plane with respect to the patient.
+ Corresponds to DICOM Tag 0018, 9255 `ASL Slab Orientation`.
+ type: array
+ items:
+ type: number
+LabelingPulseAverageB1:
+ name: LabelingPulseAverageB1
+ display_name: Labeling Pulse Average B1
+ description: |
+ The average B1-field strength of the RF labeling pulses, in microteslas.
+ As an alternative, `"LabelingPulseFlipAngle"` can be provided.
+ type: number
+ exclusiveMinimum: 0
+ unit: uT
+LabelingPulseAverageGradient:
+ name: LabelingPulseAverageGradient
+ display_name: Labeling Pulse Average Gradient
+ description: |
+ The average labeling gradient, in milliteslas per meter.
+ type: number
+ exclusiveMinimum: 0
+ unit: mT/m
+LabelingPulseDuration:
+ name: LabelingPulseDuration
+ display_name: Labeling Pulse Duration
+ description: |
+ Duration of the individual labeling pulses, in milliseconds.
+ type: number
+ exclusiveMinimum: 0
+ unit: ms
+LabelingPulseFlipAngle:
+ name: LabelingPulseFlipAngle
+ display_name: Labeling Pulse Flip Angle
+ description: |
+ The flip angle of a single labeling pulse, in degrees,
+ which can be given as an alternative to `"LabelingPulseAverageB1"`.
+ type: number
+ exclusiveMinimum: 0
+ maximum: 360
+ unit: degree
+LabelingPulseInterval:
+ name: LabelingPulseInterval
+ display_name: Labeling Pulse Interval
+ description: |
+ Delay between the peaks of the individual labeling pulses, in milliseconds.
+ type: number
+ exclusiveMinimum: 0
+ unit: ms
+LabelingPulseMaximumGradient:
+ name: LabelingPulseMaximumGradient
+ display_name: Labeling Pulse Maximum Gradient
+ description: |
+ The maximum amplitude of the gradient switched on during the application of
+ the labeling RF pulse(s), in milliteslas per meter.
+ type: number
+ exclusiveMinimum: 0
+ unit: mT/m
+LabelingSlabThickness:
+ name: LabelingSlabThickness
+ display_name: Labeling Slab Thickness
+ description: |
+ Thickness of the labeling slab in millimeters.
+ For non-selective FAIR a zero is entered.
+ Corresponds to DICOM Tag 0018, 9254 `ASL Slab Thickness`.
+ type: number
+ exclusiveMinimum: 0
+ unit: mm
+LATENCYChannelCount:
+ name: LATENCYChannelCount
+ display_name: Latency channel count
+ description: |
+ Number of Latency channels.
+ type: integer
+ minimum: 0
+Levels:
+ name: Levels
+ display_name: Levels
+ description: |
+ For categorical variables: An object of possible values (keys) and their
+ descriptions (values).
+ type: object
+ additionalProperties:
+ anyOf:
+ - type: string
+ - type: object
+ properties:
+ TermURL:
+ type: string
+ format: uri
+ Description:
+ type: string
+License:
+ name: License
+ display_name: License
+ description: |
+ The license for the dataset.
+ The use of license name abbreviations is RECOMMENDED for specifying a license
+ (see [Licenses](SPEC_ROOT/appendices/licenses.md)).
+ The corresponding full license text MAY be specified in an additional
+ `LICENSE` file.
+ type: string
+LongName:
+ name: LongName
+ display_name: Long Name
+ description: |
+ Long (unabbreviated) name of the column.
+ type: string
+LookLocker:
+ name: LookLocker
+ display_name: Look Locker
+ description: |
+ Boolean indicating if a Look-Locker readout is used.
+ type: boolean
+M0Estimate:
+ name: M0Estimate
+ display_name: M0Estimate
+ description: |
+ A single numerical whole-brain M0 value (referring to the M0 of blood),
+ only if obtained externally
+ (for example retrieved from CSF in a separate measurement).
+ type: number
+ exclusiveMinimum: 0
+M0Type:
+ name: M0Type
+ display_name: M0Type
+ description: |
+ Describes the presence of M0 information.
+ `"Separate"` means that a separate `*_m0scan.nii[.gz]` is present.
+ `"Included"` means that an m0scan volume is contained within the current
+ `*_asl.nii[.gz]`.
+ `"Estimate"` means that a single whole-brain M0 value is provided.
+ `"Absent"` means that no specific M0 information is present.
+ type: string
+ enum:
+ - $ref: objects.enums.Separate.value
+ - $ref: objects.enums.Included.value
+ - $ref: objects.enums.Estimate.value
+ - $ref: objects.enums.Absent.value
+MAGNChannelCount:
+ name: MAGNChannelCount
+ display_name: Magnetometer Channel Count
+ description: |
+ Number of magnetometer channels.
+ type: integer
+ minimum: 0
+MEGChannelCount:
+ name: MEGChannelCount
+ display_name: MEG Channel Count
+ description: |
+ Number of MEG channels (for example, `275`).
+ type: integer
+ minimum: 0
+MEGCoordinateSystem:
+ name: MEGCoordinateSystem
+ display_name: MEG Coordinate System
+ description: |
+ Defines the coordinate system for the MEG sensors.
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `"MEGCoordinateSystemDescription"`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+MEGCoordinateSystemDescription:
+ name: MEGCoordinateSystemDescription
+ display_name: MEG Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+MEGCoordinateUnits:
+ name: MEGCoordinateUnits
+ display_name: MEG Coordinate Units
+ description: |
+ Units of the coordinates of `"MEGCoordinateSystem"`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+MEGREFChannelCount:
+ name: MEGREFChannelCount
+ display_name: MEGREF Channel Count
+ description: |
+ Number of MEG reference channels (for example, `23`).
+ For systems without such channels (for example, Neuromag Vectorview),
+ `MEGREFChannelCount` should be set to `0`.
+ type: integer
+ minimum: 0
+MISCChannelCount:
+ name: MISCChannelCount
+ display_name: Miscellaneous channel count
+ description: |
+ Number of miscellaneous channels not covered otherwise.
+ type: integer
+ minimum: 0
+MotionChannelCount:
+ name: MotionChannelCount
+ display_name: Motion Channel Count
+ description: |
+ Number of motion channels (for example, `275`).
+ type: integer
+ minimum: 0
+MRAcquisitionType:
+ name: MRAcquisitionType
+ display_name: MR Acquisition Type
+ description: |
+ Type of sequence readout.
+ Corresponds to DICOM Tag 0018, 0023 `MR Acquisition Type`.
+ type: string
+ enum:
+ - $ref: objects.enums.TwoD.value
+ - $ref: objects.enums.ThreeD.value
+MRTransmitCoilSequence:
+ name: MRTransmitCoilSequence
+ display_name: MR Transmit Coil Sequence
+ description: |
+ This is a relevant field if a non-standard transmit coil is used.
+ Corresponds to DICOM Tag 0018, 9049 `MR Transmit Coil Sequence`.
+ type: string
+MTNumberOfPulses:
+ name: MTNumberOfPulses
+ display_name: MT Number Of Pulses
+ description: |
+ The number of magnetization transfer RF pulses applied before the readout.
+ type: number
+MTOffsetFrequency:
+ name: MTOffsetFrequency
+ display_name: MT Offset Frequency
+ description: |
+ The frequency offset of the magnetization transfer pulse with respect to the
+ central H1 Larmor frequency in Hertz (Hz).
+ type: number
+ unit: Hz
+MTPulseBandwidth:
+ name: MTPulseBandwidth
+ display_name: MT Pulse Bandwidth
+ description: |
+ The excitation bandwidth of the magnetization transfer pulse in Hertz (Hz).
+ type: number
+ unit: Hz
+MTPulseDuration:
+ name: MTPulseDuration
+ display_name: MT Pulse Duration
+ description: |
+ Duration of the magnetization transfer RF pulse in seconds.
+ type: number
+ unit: s
+MTPulseShape:
+ name: MTPulseShape
+ display_name: MT Pulse Shape
+ description: |
+ Shape of the magnetization transfer RF pulse waveform.
+ The value `"GAUSSHANN"` refers to a Gaussian pulse with a Hanning window.
+ The value `"SINCHANN"` refers to a sinc pulse with a Hanning window.
+ The value `"SINCGAUSS"` refers to a sinc pulse with a Gaussian window.
+ type: string
+ enum:
+ - $ref: objects.enums.HARD.value
+ - $ref: objects.enums.GAUSSIAN.value
+ - $ref: objects.enums.GAUSSHANN.value
+ - $ref: objects.enums.SINC.value
+ - $ref: objects.enums.SINCHANN.value
+ - $ref: objects.enums.SINCGAUSS.value
+ - $ref: objects.enums.FERMI.value
+MTState:
+ name: MTState
+ display_name: MT State
+ description: |
+ Boolean stating whether the magnetization transfer pulse is applied.
+ Corresponds to DICOM Tag 0018, 9020 `Magnetization Transfer`.
+ type: boolean
+MagneticFieldStrength:
+ name: MagneticFieldStrength
+ display_name: Magnetic Field Strength
+ description: |
+ Nominal field strength of MR magnet in Tesla.
+ Corresponds to DICOM Tag 0018, 0087 `Magnetic Field Strength`.
+ type: number
+Magnification:
+ name: Magnification
+ display_name: Magnification
+ description: |
+ Lens magnification (for example: `40`). If the file format is OME-TIFF,
+ the value MUST be consistent with the `"NominalMagnification"` OME metadata field.
+ type: number
+ exclusiveMinimum: 0
+Manual:
+ name: Manual
+ display_name: Manual
+ description: |
+ Indicates if the segmentation was performed manually or via an automated
+ process.
+ type: boolean
+Manufacturer:
+ name: Manufacturer
+ display_name: Manufacturer
+ description: |
+ Manufacturer of the equipment that produced the measurements.
+ type: string
+ManufacturersModelName:
+ name: ManufacturersModelName
+ display_name: Manufacturers Model Name
+ description: |
+ Manufacturer's model name of the equipment that produced the measurements.
+ type: string
+MatrixCoilMode:
+ name: MatrixCoilMode
+ display_name: Matrix Coil Mode
+ description: |
+ (If used)
+ A method for reducing the number of independent channels by combining in
+ analog the signals from multiple coil elements.
+ There are typically different default modes when using un-accelerated or
+ accelerated (for example, `"GRAPPA"`, `"SENSE"`) imaging.
+ type: string
+MaxMovement:
+ name: MaxMovement
+ display_name: Max Movement
+ description: |
+ Maximum head movement (in mm) detected during the recording,
+ as measured by the head localisation coils (for example, `4.8`).
+ type: number
+ unit: mm
+MeasurementToolMetadata:
+ name: MeasurementToolMetadata
+ display_name: Measurement Tool Metadata
+ description: |
+ A description of the measurement tool as a whole.
+ Contains two fields: `"Description"` and `"TermURL"`.
+ `"Description"` is a free text description of the measurement tool.
+ `"TermURL"` is a URL to an entity in an ontology corresponding to this tool.
+ type: object
+ properties:
+ TermURL:
+ type: string
+ format: uri
+ Description:
+ type: string
+MetaboliteAvail:
+ name: MetaboliteAvail
+ display_name: Metabolite Available
+ description: |
+ Boolean that specifies if metabolite measurements are available.
+ If `true`, the `metabolite_parent_fraction` column MUST be present in the
+ corresponding `*_blood.tsv` file.
+ type: boolean
+MetaboliteMethod:
+ name: MetaboliteMethod
+ display_name: Metabolite Method
+ description: |
+ Method used to measure metabolites.
+ type: string
+MetaboliteRecoveryCorrectionApplied:
+ name: MetaboliteRecoveryCorrectionApplied
+ display_name: Metabolite Recovery Correction Applied
+ description: |
+ Metabolite recovery correction from the HPLC, for tracers where it changes
+ with time postinjection.
+ If `true`, the `hplc_recovery_fractions` column MUST be present in the
+ corresponding `*_blood.tsv` file.
+ type: boolean
+MiscChannelCount:
+ name: MiscChannelCount
+ display_name: Misc Channel Count
+ description: |
+ Number of miscellaneous analog channels for auxiliary signals.
+ type: integer
+ minimum: 0
+MissingValues:
+ name: MissingValues
+ display_name: MissingValues
+ description: |
+ Describes how missing values are represented in the given recording system
+ (for example a tracking system in motion), can take values such as, "NaN", "0".
+ type: string
+MixingTime:
+ name: MixingTime
+ display_name: Mixing Time
+ description: |
+ In the context of a stimulated- and spin-echo 3D EPI sequence for B1+ mapping,
+ corresponds to the interval between spin- and stimulated-echo pulses.
+ In the context of a diffusion-weighted double spin-echo sequence,
+ corresponds to the interval between two successive diffusion sensitizing
+ gradients, specified in seconds.
+ type: number
+ unit: s
+ModeOfAdministration:
+ name: ModeOfAdministration
+ display_name: Mode Of Administration
+ description: |
+ Mode of administration of the injection
+ (for example, `"bolus"`, `"infusion"`, or `"bolus-infusion"`).
+ type: string
+MolarActivity:
+ name: MolarActivity
+ display_name: Molar Activity
+ description: |
+ Molar activity of compound injected.
+ Corresponds to DICOM Tag 0018, 1077 `Radiopharmaceutical Specific Activity`.
+ type: number
+MolarActivityMeasTime:
+ name: MolarActivityMeasTime
+ display_name: Molar Activity Measurement Time
+ description: |
+ Time to which molar radioactivity measurement above applies in the default
+ unit `"hh:mm:ss"`.
+ type: string
+ format: time
+MolarActivityUnits:
+ name: MolarActivityUnits
+ display_name: Molar Activity Units
+ description: |
+ Unit of the specified molar radioactivity (for example, `"GBq/umol"`).
+ type: string
+ format: unit
+MultibandAccelerationFactor:
+ name: MultibandAccelerationFactor
+ display_name: Multiband Acceleration Factor
+ description: |
+ The multiband factor, for multiband acquisitions.
+ type: number
+MultipartID:
+ name: MultipartID
+ display_name: MultipartID
+ description: |
+ A unique (per participant) label tagging DWI runs that are part of a
+ multipart scan.
+ type: string
+Name:
+ name: Name
+ display_name: Name
+ description: |
+ Name of the dataset.
+ type: string
+NegativeContrast:
+ name: NegativeContrast
+ display_name: Negative Contrast
+ description: |
+ `true` or `false` value specifying whether increasing voxel intensity
+ (within sample voxels) denotes a decreased value with respect to the
+ contrast suffix.
+ This is commonly the case when Cerebral Blood Volume is estimated via
+ usage of a contrast agent in conjunction with a T2\* weighted acquisition
+ protocol.
+ type: boolean
+NIRSChannelCount:
+ name: NIRSChannelCount
+ display_name: NIRS Channel Count
+ description: |
+ Total number of NIRS channels, including short channels.
+ Corresponds to the number of rows in `channels.tsv` with any NIRS type.
+ type: integer
+ minimum: 0
+NIRSSourceOptodeCount:
+ name: NIRSSourceOptodeCount
+ display_name: NIRS Source Optode Count
+ description: |
+ Number of NIRS sources.
+ Corresponds to the number of rows in `optodes.tsv` with type `"source"`.
+ type: integer
+ minimum: 1
+NIRSDetectorOptodeCount:
+ name: NIRSDetectorOptodeCount
+ display_name: NIRS Detector Optode Channel Count
+ description: |
+ Number of NIRS detectors.
+ Corresponds to the number of rows in `optodes.tsv` with type `"detector"`.
+ type: integer
+ minimum: 1
+NIRSPlacementScheme:
+ name: NIRSPlacementScheme
+ display_name: NIRS Placement Scheme
+ description: |
+ Placement scheme of NIRS optodes.
+ Either the name of a standardized placement system (for example, `"10-20"`)
+ or an array of standardized position names (for example, `["Cz", "Pz"]`).
+ This field should only be used if a cap was not used.
+ If a standard cap was used, then it should be specified in `CapManufacturer`
+ and `CapManufacturersModelName` and this field should be set to `"n/a"`
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+NIRSCoordinateSystem:
+ name: NIRSCoordinateSystem
+ display_name: NIRS Coordinate System
+ description: |
+ Defines the coordinate system in which the optode positions are expressed.
+
+ See
+ [Appendix VIII](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, a definition of the coordinate system MUST be
+ provided in `NIRSCoordinateSystemDescription`.
+ anyOf:
+ - $ref: objects.enums._MEGCoordSys
+ - $ref: objects.enums._EEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+NIRSCoordinateSystemDescription:
+ name: NIRSCoordinateSystemDescription
+ display_name: NIRS Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+NIRSCoordinateUnits:
+ name: NIRSCoordinateUnits
+ display_name: NIRS Coordinate Units
+ description: |
+ Units of the coordinates of `NIRSCoordinateSystem`.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - m
+ - mm
+ - cm
+ - n/a
+NIRSCoordinateProcessingDescription:
+ name: NIRSCoordinateProcessingDescription
+ display_name: NIRS Coordinate Processing Description
+ description: |
+ Has any post-processing (such as projection) been done on the optode
+ positions (for example, `"surface_projection"`, `"n/a"`).
+ type: string
+NonlinearGradientCorrection:
+ name: NonlinearGradientCorrection
+ display_name: Nonlinear Gradient Correction
+ description: |
+ Boolean stating if the image saved has been corrected for gradient
+ nonlinearities by the scanner sequence.
+ type: boolean
+NumberOfVolumesDiscardedByScanner:
+ name: NumberOfVolumesDiscardedByScanner
+ display_name: Number Of Volumes Discarded By Scanner
+ description: |
+ Number of volumes ("dummy scans") discarded by the scanner
+ (as opposed to those discarded by the user post hoc)
+ before saving the imaging file.
+ For example, a sequence that automatically discards the first 4 volumes
+ before saving would have this field as 4.
+ A sequence that does not discard dummy scans would have this set to 0.
+ Please note that the onsets recorded in the `events.tsv` file should always
+ refer to the beginning of the acquisition of the first volume in the
+ corresponding imaging file - independent of the value of
+ `"NumberOfVolumesDiscardedByScanner"` field.
+ type: integer
+ minimum: 0
+NumberOfVolumesDiscardedByUser:
+ name: NumberOfVolumesDiscardedByUser
+ display_name: Number Of Volumes Discarded By User
+ description: |
+ Number of volumes ("dummy scans") discarded by the user before including the
+ file in the dataset.
+ If possible, including all of the volumes is strongly recommended.
+ Please note that the onsets recorded in the `events.tsv` file should always
+ refer to the beginning of the acquisition of the first volume in the
+ corresponding imaging file - independent of the value of
+ `"NumberOfVolumesDiscardedByUser"` field.
+ type: integer
+ minimum: 0
+NumberShots:
+ name: NumberShots
+ display_name: Number Shots
+ description: |
+ The number of RF excitations needed to reconstruct a slice or volume
+ (may be referred to as partition).
+ Please mind that this is not the same as Echo Train Length which denotes the
+ number of k-space lines collected after excitation in a multi-echo readout.
+ The data type array is applicable for specifying this parameter before and
+ after the k-space center is sampled.
+ Please see
+ [`"NumberShots"` metadata field]\
+ (SPEC_ROOT/appendices/qmri.md#numbershots-metadata-field)
+ in the qMRI appendix for corresponding calculations.
+ anyOf:
+ - type: number
+ - type: array
+ items:
+ type: number
+NumericalAperture:
+ name: NumericalAperture
+ display_name: Numerical Aperture
+ description: |
+ Lens numerical aperture (for example: `1.4`). If the file format is OME-TIFF,
+ the value MUST be consistent with the `LensNA` OME metadata field.
+ type: number
+ exclusiveMinimum: 0
+OperatingSystem:
+ name: OperatingSystem
+ display_name: Operating System
+ description: |
+ Operating system used to run the stimuli presentation software
+ (for formatting recommendations, see examples below this table).
+ type: string
+ORNTChannelCount:
+ name: ORNTChannelCount
+ display_name: Orientation Channel Count
+ description: |
+ Number of orientation channels.
+ type: integer
+ minimum: 0
+OtherAcquisitionParameters:
+ name: OtherAcquisitionParameters
+ display_name: Other Acquisition Parameters
+ description: |
+ Description of other relevant image acquisition parameters.
+ type: string
+PASLType:
+ name: PASLType
+ display_name: PASL Type
+ description: |
+ Type of the labeling pulse of the `PASL` labeling,
+ for example `"FAIR"`, `"EPISTAR"`, or `"PICORE"`.
+ type: string
+PCASLType:
+ name: PCASLType
+ display_name: PCASL Type
+ description: |
+ The type of gradient pulses used in the `control` condition.
+ type: string
+ enum:
+ - $ref: objects.enums.balanced.value
+ - $ref: objects.enums.unbalanced.value
+ParallelAcquisitionTechnique:
+ name: ParallelAcquisitionTechnique
+ display_name: Parallel Acquisition Technique
+ description: |
+ The type of parallel imaging used (for example `"GRAPPA"`, `"SENSE"`).
+ Corresponds to DICOM Tag 0018, 9078 `Parallel Acquisition Technique`.
+ type: string
+ParallelReductionFactorInPlane:
+ name: ParallelReductionFactorInPlane
+ display_name: Parallel Reduction Factor In Plane
+ description: |
+ The parallel imaging (for instance, GRAPPA) factor in plane.
+ Use the denominator of the fraction of k-space encoded for each slice.
+ For example, 2 means half of k-space is encoded.
+ Corresponds to DICOM Tag 0018, 9069 `Parallel Reduction Factor In-plane`.
+ type: number
+ParallelReductionFactorOutOfPlane:
+ name: ParallelReductionFactorOutOfPlane
+ display_name: Parallel Reduction Factor Out of Plane
+ description: |
+ The parallel imaging (for instance, GRAPPA) factor in the second phase encoding dimension of 3D sequences.
+ Use the denominator of the fraction of k-space encoded in the second phase encoding dimension.
+ For example, 2 means half of k-space is encoded.
+ Will typically be 1 for 2D sequences, as each slice in a 2D acquisition is usually fully encoded.
+ `ParallelReductionFactorOutOfPlane` should not be confused with `MultibandAccelerationFactor`,
+ as they imply different methods of accelerating the acquisition.
+ Corresponds to DICOM Tag 0018, 9155 `Parallel Reduction Factor out-of-plane`.
+ type: number
+PartialFourier:
+ name: PartialFourier
+ display_name: Partial Fourier
+ description: |
+ The fraction of partial Fourier information collected.
+ Corresponds to DICOM Tag 0018, 9081 `Partial Fourier`.
+ type: number
+PartialFourierDirection:
+ name: PartialFourierDirection
+ display_name: Partial Fourier Direction
+ description: |
+ The direction where only partial Fourier information was collected.
+ Corresponds to DICOM Tag 0018, 9036 `Partial Fourier Direction`.
+ type: string
+PharmaceuticalDoseAmount:
+ name: PharmaceuticalDoseAmount
+ display_name: Pharmaceutical Dose Amount
+ description: |
+ Dose amount of pharmaceutical coadministered with tracer.
+ anyOf:
+ - type: number
+ - type: array
+ items:
+ type: number
+PharmaceuticalDoseRegimen:
+ name: PharmaceuticalDoseRegimen
+ display_name: Pharmaceutical Dose Regimen
+ description: |
+ Details of the pharmaceutical dose regimen.
+ Either adequate description or short-code relating to regimen documented
+ elsewhere (for example, `"single oral bolus"`).
+ type: string
+PharmaceuticalDoseTime:
+ name: PharmaceuticalDoseTime
+ display_name: Pharmaceutical Dose Time
+ description: |
+ Time of administration of pharmaceutical dose, relative to time zero.
+ For an infusion, this should be a vector with two elements specifying the
+ start and end of the infusion period. For more complex dose regimens,
+ the regimen description should be complete enough to enable unambiguous
+ interpretation of `"PharmaceuticalDoseTime"`.
+ Unit format of the specified pharmaceutical dose time MUST be seconds.
+ anyOf:
+ - type: number
+ unit: s
+ - type: array
+ items:
+ type: number
+ unit: s
+PharmaceuticalDoseUnits:
+ name: PharmaceuticalDoseUnits
+ display_name: Pharmaceutical Dose Units
+ description: |
+ Unit format relating to pharmaceutical dose
+ (for example, `"mg"` or `"mg/kg"`).
+ type: string
+ format: unit
+PharmaceuticalName:
+ name: PharmaceuticalName
+ display_name: Pharmaceutical Name
+ description: |
+ Name of pharmaceutical coadministered with tracer.
+ type: string
+PhaseEncodingDirection:
+ name: PhaseEncodingDirection
+ display_name: Phase Encoding Direction
+ description: |
+ The letters `i`, `j`, `k` correspond to the first, second and third axis of
+ the data in the NIFTI file.
+ The polarity of the phase encoding is assumed to go from zero index to
+ maximum index unless `-` sign is present
+ (then the order is reversed - starting from the highest index instead of
+ zero).
+ `PhaseEncodingDirection` is defined as the direction along which phase is was
+ modulated which may result in visible distortions.
+ Note that this is not the same as the DICOM term
+ `InPlanePhaseEncodingDirection` which can have `ROW` or `COL` values.
+ type: string
+ enum:
+ - $ref: objects.enums.i.value
+ - $ref: objects.enums.iMinus.value
+ - $ref: objects.enums.j.value
+ - $ref: objects.enums.jMinus.value
+ - $ref: objects.enums.k.value
+ - $ref: objects.enums.kMinus.value
+PhotoDescription:
+ name: PhotoDescription
+ display_name: Photo Description
+ description: |
+ Description of the photo.
+ type: string
+PixelSize:
+ name: PixelSize
+ display_name: Pixel Size
+ description: |
+ A 2- or 3-number array of the physical size of a pixel, either `[PixelSizeX, PixelSizeY]`
+ or `[PixelSizeX, PixelSizeY, PixelSizeZ]`, where X is the width, Y the height and Z the
+ depth.
+ If the file format is OME-TIFF, these values need to be consistent with `PhysicalSizeX`,
+ `PhysicalSizeY` and `PhysicalSizeZ` OME metadata fields, after converting in
+ `PixelSizeUnits` according to `PhysicalSizeXunit`, `PhysicalSizeYunit` and
+ `PhysicalSizeZunit` OME fields.
+ type: array
+ minItems: 2
+ maxItems: 3
+ items:
+ type: number
+ minimum: 0
+PixelSizeUnits:
+ name: PixelSizeUnits
+ display_name: Pixel Size Units
+ description: |
+ Unit format of the specified `"PixelSize"`. MUST be one of: `"mm"` (millimeter), `"um"`
+ (micrometer) or `"nm"` (nanometer).
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - mm
+ - um
+ - nm
+PlasmaAvail:
+ name: PlasmaAvail
+ display_name: Plasma Avail
+ description: |
+ Boolean that specifies if plasma measurements are available.
+ type: boolean
+PlasmaFreeFraction:
+ name: PlasmaFreeFraction
+ display_name: Plasma Free Fraction
+ description: |
+ Measured free fraction in plasma, meaning the concentration of free compound
+ in plasma divided by total concentration of compound in plasma
+ (Units: 0-100%).
+ type: number
+ minimum: 0
+ maximum: 100
+PlasmaFreeFractionMethod:
+ name: PlasmaFreeFractionMethod
+ display_name: Plasma Free Fraction Method
+ description: |
+ Method used to estimate free fraction.
+ type: string
+POSChannelCount:
+ name: POSChannelCount
+ display_name: Position Channel Count
+ description: |
+ Number of position channels.
+ type: integer
+ minimum: 0
+PostLabelingDelay:
+ name: PostLabelingDelay
+ display_name: Post Labeling Delay
+ description: |
+ This is the postlabeling delay (PLD) time, in seconds, after the end of the
+ labeling (for `"CASL"` or `"PCASL"`) or middle of the labeling pulse
+ (for `"PASL"`) until the middle of the excitation pulse applied to the
+ imaging slab (for 3D acquisition) or first slice (for 2D acquisition).
+ Can be a number (for a single-PLD time series) or an array of numbers
+ (for multi-PLD and Look-Locker).
+ In the latter case, the array of numbers contains the PLD of each volume,
+ namely each `control` and `label`, in the acquisition order.
+ Any image within the time-series without a PLD, for example an `m0scan`,
+ is indicated by a zero.
+ Based on DICOM Tags 0018, 9079 `Inversion Times` and 0018, 0082
+ `InversionTime`.
+ anyOf:
+ - type: number
+ exclusiveMinimum: 0
+ unit: s
+ - type: array
+ items:
+ type: number
+ exclusiveMinimum: 0
+ unit: s
+PowerLineFrequency:
+ name: PowerLineFrequency
+ display_name: Power Line Frequency
+ description: |
+ Frequency (in Hz) of the power grid at the geographical location of the
+ instrument (for example, `50` or `60`).
+ anyOf:
+ - type: number
+ exclusiveMinimum: 0
+ unit: Hz
+ - type: string
+ enum:
+ - n/a
+PromptRate:
+ name: PromptRate
+ display_name: Prompt Rate
+ description: |
+ Prompt rate for each frame (same units as `Units`, for example, `"Bq/mL"`).
+ type: array
+ items:
+ type: number
+PulseSequenceDetails:
+ name: PulseSequenceDetails
+ display_name: Pulse Sequence Details
+ description: |
+ Information beyond pulse sequence type that identifies the specific pulse
+ sequence used (for example,
+ `"Standard Siemens Sequence distributed with the VB17 software"`,
+ `"Siemens WIP ### version #.##,"` or
+ `"Sequence written by X using a version compiled on MM/DD/YYYY"`).
+ type: string
+PulseSequenceType:
+ name: PulseSequenceType
+ display_name: Pulse Sequence Type
+ description: |
+ A general description of the pulse sequence used for the scan
+ (for example, `"MPRAGE"`, `"Gradient Echo EPI"`, `"Spin Echo EPI"`,
+ `"Multiband gradient echo EPI"`).
+ type: string
+Purity:
+ name: Purity
+ display_name: Purity
+ description: |
+ Purity of the radiolabeled compound (between 0 and 100%).
+ type: number
+ minimum: 0
+ maximum: 100
+RandomRate:
+ name: RandomRate
+ display_name: Random Rate
+ description: |
+ Random rate for each frame (same units as `"Units"`, for example, `"Bq/mL"`).
+ type: array
+ items:
+ type: number
+RawSources:
+ name: RawSources
+ display_name: Raw Sources
+ description: |
+ A list of paths relative to dataset root pointing to the BIDS-Raw file(s)
+ that were used in the creation of this derivative.
+ This field is DEPRECATED, and this metadata SHOULD be recorded in the
+ `Sources` field using [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri)
+ to distinguish sources from different datasets.
+ type: array
+ items:
+ type: string
+ format: dataset_relative
+ReceiveCoilActiveElements:
+ name: ReceiveCoilActiveElements
+ display_name: Receive Coil Active Elements
+ description: |
+ Information describing the active/selected elements of the receiver coil.
+ This does not correspond to a tag in the DICOM ontology.
+ The vendor-defined terminology for active coil elements can go in this field.
+ type: string
+ReceiveCoilName:
+ name: ReceiveCoilName
+ display_name: Receive Coil Name
+ description: |
+ Information describing the receiver coil.
+ Corresponds to DICOM Tag 0018, 1250 `Receive Coil Name`,
+ although not all vendors populate that DICOM Tag,
+ in which case this field can be derived from an appropriate
+ private DICOM field.
+ type: string
+ReconFilterSize:
+ name: ReconFilterSize
+ display_name: Recon Filter Size
+ description: |
+ Kernel size of post-recon filter (FWHM) in default units `"mm"`.
+ anyOf:
+ - type: number
+ unit: mm
+ - type: array
+ items:
+ type: number
+ unit: mm
+ReconFilterType:
+ name: ReconFilterType
+ display_name: Recon Filter Type
+ description: |
+ Type of post-recon smoothing (for example, `["Shepp"]`).
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+ReconMethodImplementationVersion:
+ name: ReconMethodImplementationVersion
+ display_name: Recon Method Implementation Version
+ description: |
+ Identification for the software used, such as name and version.
+ type: string
+ReconMethodName:
+ name: ReconMethodName
+ display_name: Recon Method Name
+ description: |
+ Reconstruction method or algorithm (for example, `"3d-op-osem"`).
+ type: string
+ReconMethodParameterLabels:
+ name: ReconMethodParameterLabels
+ display_name: Recon Method Parameter Labels
+ description: |
+ Names of reconstruction parameters (for example, `["subsets", "iterations"]`).
+ type: array
+ items:
+ type: string
+ReconMethodParameterUnits:
+ name: ReconMethodParameterUnits
+ display_name: Recon Method Parameter Units
+ description: |
+ Unit of reconstruction parameters (for example, `["none", "none"]`).
+ type: array
+ items:
+ type: string
+ format: unit
+ReconMethodParameterValues:
+ name: ReconMethodParameterValues
+ display_name: Recon Method Parameter Values
+ description: |
+ Values of reconstruction parameters (for example, `[21, 3]`).
+ type: array
+ items:
+ type: number
+RecordingDuration:
+ name: RecordingDuration
+ display_name: Recording Duration
+ description: |
+ Length of the recording in seconds (for example, `3600`).
+ type: number
+ unit: s
+RecordingType:
+ name: RecordingType
+ display_name: Recording Type
+ description: |
+ Defines whether the recording is `"continuous"`, `"discontinuous"`, or
+ `"epoched"`, where `"epoched"` is limited to time windows about events of
+ interest (for example, stimulus presentations or subject responses).
+ type: string
+ enum:
+ - $ref: objects.enums.continuous.value
+ - $ref: objects.enums.epoched.value
+ - $ref: objects.enums.discontinuous.value
+ReferencesAndLinks:
+ name: ReferencesAndLinks
+ display_name: References And Links
+ description: |
+ List of references to publications that contain information on the dataset.
+ A reference may be textual or a
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator).
+ items:
+ type: string
+ type: array
+RepetitionTime:
+ name: RepetitionTime
+ display_name: Repetition Time
+ description: |
+ The time in seconds between the beginning of an acquisition of one volume
+ and the beginning of acquisition of the volume following it (TR).
+ When used in the context of functional acquisitions this parameter best
+ corresponds to
+ [DICOM Tag 0020, 0110](http://dicomlookup.com/dicomtags/(0020,0110)):
+ the "time delta between images in a
+ dynamic of functional set of images" but may also be found in
+ [DICOM Tag 0018, 0080](http://dicomlookup.com/dicomtags/(0018,0080)):
+ "the period of time in msec between the beginning
+ of a pulse sequence and the beginning of the succeeding
+ (essentially identical) pulse sequence".
+ This definition includes time between scans (when no data has been acquired)
+ in case of sparse acquisition schemes.
+ This value MUST be consistent with the 'pixdim[4]' field (after accounting
+ for units stored in 'xyzt_units' field) in the NIfTI header.
+ This field is mutually exclusive with VolumeTiming.
+ type: number
+ exclusiveMinimum: 0
+ unit: s
+RepetitionTimeExcitation:
+ name: RepetitionTimeExcitation
+ display_name: Repetition Time Excitation
+ description: |
+ The interval, in seconds, between two successive excitations.
+ [DICOM Tag 0018, 0080](http://dicomlookup.com/dicomtags/(0018,0080))
+ best refers to this parameter.
+ This field may be used together with the `"RepetitionTimePreparation"` for
+ certain use cases, such as
+ [MP2RAGE](https://doi.org/10.1016/j.neuroimage.2009.10.002).
+ Use `RepetitionTimeExcitation` (in combination with
+ `"RepetitionTimePreparation"` if needed) for anatomy imaging data rather than
+ `"RepetitionTime"` as it is already defined as the amount of time that it takes
+ to acquire a single volume in the
+ [task imaging data](SPEC_ROOT/modality-specific-files/magnetic-resonance-\
+ imaging-data.md#task-including-resting-state-imaging-data)
+ section.
+ type: number
+ minimum: 0
+ unit: s
+RepetitionTimePreparation:
+ name: RepetitionTimePreparation
+ display_name: Repetition Time Preparation
+ description: |
+ The interval, in seconds, that it takes a preparation pulse block to
+ re-appear at the beginning of the succeeding (essentially identical) pulse
+ sequence block.
+ The data type number may apply to files from any MRI modality concerned with
+ a single value for this field.
+ 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](SPEC_ROOT/modality-specific-files/magnetic-resonance-imaging-data.md\
+ #arterial-spin-labeling-perfusion-data).
+ anyOf:
+ - type: number
+ minimum: 0
+ unit: s
+ - type: array
+ items:
+ type: number
+ minimum: 0
+ unit: s
+Resolution:
+ name: Resolution
+ display_name: Resolution
+ description: |
+ Specifies the interpretation of the resolution keyword.
+ If an object is used, then the keys should be values for the `res` entity
+ and values should be descriptions of those `res` values.
+ anyOf:
+ - type: string
+ - type: object
+ additionalProperties:
+ type: string
+RotationOrder:
+ name: RotationOrder
+ display_name: RotationOrder
+ description: |
+ Specify the sequence in which the elemental 3D extrinsic rotations are applied around the three distinct axes.
+ type: string
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ enum:
+ - XYZ
+ - XZY
+ - YXZ
+ - YZX
+ - ZXY
+ - ZYX
+ - n/a
+RotationRule:
+ name: RotationRule
+ display_name: Rotation Rule
+ description: |
+ In case orientation channels are present, indicate whether rotations are applied
+ clockwise around an axis when seen from the positive direction (left-hand rule) or
+ counter-clockwise (right-hand rule). Must be one of: "left-hand", "right-hand".
+ type: string
+ enum:
+ - $ref: objects.enums.left_hand.value
+ - $ref: objects.enums.right_hand.value
+ - n/a
+SEEGChannelCount:
+ name: SEEGChannelCount
+ display_name: SEEG Channel Count
+ description: |
+ Number of SEEG channels.
+ type: integer
+ minimum: 0
+SampleEmbedding:
+ name: SampleEmbedding
+ display_name: Sample Embedding
+ description: |
+ Description of the tissue sample embedding (for example: `"Epoxy resin"`).
+ type: string
+SampleEnvironment:
+ name: SampleEnvironment
+ display_name: Sample Environment
+ description: |
+ Environment in which the sample was imaged. MUST be one of: `"in vivo"`, `"ex vivo"`
+ or `"in vitro"`.
+ type: string
+ enum:
+ - $ref: objects.enums.in_vivo.value
+ - $ref: objects.enums.ex_vivo.value
+ - $ref: objects.enums.in_vitro.value
+SampleExtractionInstitution:
+ name: SampleExtractionInstitution
+ display_name: Sample Extraction Institution
+ description: |
+ The name of the institution in charge of the extraction of the sample,
+ if different from the institution in charge of the equipment that produced the image.
+ type: string
+SampleExtractionProtocol:
+ name: SampleExtractionProtocol
+ display_name: Sample Extraction Protocol
+ description: |
+ Description of the sample extraction protocol or
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)
+ (for example from [protocols.io](https://www.protocols.io/)).
+ type: string
+SampleFixation:
+ name: SampleFixation
+ display_name: Sample Fixation
+ description: |
+ Description of the tissue sample fixation
+ (for example: `"4% paraformaldehyde, 2% glutaraldehyde"`).
+ type: string
+SampleOrigin:
+ name: SampleOrigin
+ display_name: Sample Origin
+ description: |
+ Describes from which tissue the genetic information was extracted.
+ type: string
+ enum:
+ - $ref: objects.enums.blood.value
+ - $ref: objects.enums.saliva.value
+ - $ref: objects.enums.brain.value
+ - $ref: objects.enums.csf.value
+ - $ref: objects.enums.breast_milk.value
+ - $ref: objects.enums.bile.value
+ - $ref: objects.enums.amniotic_fluid.value
+ - $ref: objects.enums.other_biospecimen.value
+SamplePrimaryAntibody:
+ name: SamplePrimaryAntibody
+ display_name: Sample Primary Antibody
+ description: |
+ Description(s) of the primary antibody used for immunostaining.
+ Either an [RRID](https://scicrunch.org/resources) or the name, supplier and catalog
+ number of a commercial antibody.
+ For non-commercial antibodies either an [RRID](https://scicrunch.org/resources) or the
+ host-animal and immunogen used (for examples: `"RRID:AB_2122563"` or
+ `"Rabbit anti-Human HTR5A Polyclonal Antibody, Invitrogen, Catalog # PA1-2453"`).
+ MAY be an array of strings if different antibodies are used in each channel of the file.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+SampleSecondaryAntibody:
+ name: SampleSecondaryAntibody
+ display_name: Sample Secondary Antibody
+ description: |
+ Description(s) of the secondary antibody used for immunostaining.
+ Either an [RRID](https://scicrunch.org/resources) or the name, supplier and catalog
+ number of a commercial antibody.
+ For non-commercial antibodies either an [RRID](https://scicrunch.org/resources) or the
+ host-animal and immunogen used (for examples: `"RRID:AB_228322"` or
+ `"Goat anti-Mouse IgM Secondary Antibody, Invitrogen, Catalog # 31172"`).
+ MAY be an array of strings if different antibodies are used in each channel of the file.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+SampleStaining:
+ name: SampleStaining
+ display_name: Sample Staining
+ description: |
+ Description(s) of the tissue sample staining (for example: `"Osmium"`).
+ MAY be an array of strings if different stains are used in each channel of the file
+ (for example: `["LFB", "PLP"]`).
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+SamplingFrequency:
+ name: SamplingFrequency
+ display_name: Sampling Frequency
+ description: |
+ Sampling frequency (in Hz) of all the data in the recording,
+ regardless of their type (for example, `2400`).
+ type: number
+ unit: Hz
+SamplingFrequencyEffective:
+ name: SamplingFrequencyEffective
+ display_name: Effective Sampling Frequency
+ description: |
+ Effective sampling frequency (in Hz) of all the data in the recording,
+ regardless of their type (for example, `2400`) which can be determined if timestamps
+ per sample are provided.
+ type: number
+ unit: Hz
+SamplingFrequency__nirs:
+ name: SamplingFrequency
+ display_name: Sampling Frequency
+ description: |
+ Sampling frequency (in Hz) of all the data in the recording,
+ regardless of their type (for example, `2400`).
+ anyOf:
+ - type: number
+ unit: Hz
+ - type: string
+ enum:
+ - n/a
+ScaleFactor:
+ name: ScaleFactor
+ display_name: Scale Factor
+ description: |
+ Scale factor for each frame. This field MUST be defined if the imaging data (`.nii[.gz]`) are scaled.
+ If this field is not defined, then it is assumed that the scaling factor is 1. Defining this field
+ when the scaling factor is 1 is RECOMMENDED, for the sake of clarity.
+ type: array
+ items:
+ type: number
+ScanDate:
+ name: ScanDate
+ display_name: Scan Date
+ description: |
+ Date of scan in the format `"YYYY-MM-DD[Z]"`.
+ This field is DEPRECATED, and this metadata SHOULD be recorded in the `acq_time` column of the
+ corresponding [Scans file](SPEC_ROOT/modality-agnostic-files.md#scans-file).
+ type: string
+ format: date
+ScanOptions:
+ name: ScanOptions
+ display_name: Scan Options
+ description: |
+ Parameters of ScanningSequence.
+ Corresponds to DICOM Tag 0018, 0022 `Scan Options`.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+ScanStart:
+ name: ScanStart
+ display_name: Scan Start
+ description: |
+ Time of start of scan with respect to `TimeZero` in the default unit seconds.
+ type: number
+ unit: s
+ScanningSequence:
+ name: ScanningSequence
+ display_name: Scanning Sequence
+ description: |
+ Description of the type of data acquired.
+ Corresponds to DICOM Tag 0018, 0020 `Scanning Sequence`.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+ScatterFraction:
+ name: ScatterFraction
+ display_name: Scatter Fraction
+ description: |
+ Scatter fraction for each frame (Units: 0-100%).
+ type: array
+ items:
+ type: number
+ minimum: 0
+ maximum: 100
+ScreenDistance:
+ name: ScreenDistance
+ display_name: Screen Distance
+ description: |
+ Distance between the participant's eye and the screen. If no screen was used, use `n/a`.
+ anyOf:
+ - type: number
+ unit: m
+ - type: string
+ enum:
+ - n/a
+ScreenRefreshRate:
+ name: ScreenRefreshRate
+ display_name: Screen Refresh Rate
+ description: |
+ Refresh rate of the screen (when used), in Hertz (equivalent to frames per second, "FPS").
+ type: number
+ unit: Hz
+ScreenResolution:
+ name: ScreenResolution
+ display_name: Screen Resolution
+ description: |
+ Screen resolution in pixel
+ (for example `[1920, 1200]` for a screen of 1920-width by 1080-height pixels),
+ if no screen use `n/a`.
+ anyOf:
+ - type: array
+ items:
+ type: integer
+ minItems: 2
+ maxItems: 2
+ - type: string
+ enum:
+ - n/a
+ScreenSize:
+ name: ScreenSize
+ display_name: Screen Size
+ description: |
+ Screen size in m, excluding potential screen borders
+ (for example `[0.472, 0.295]` for a screen of 47.2-width by 29.5-height cm),
+ if no screen use `n/a`.
+ anyOf:
+ - type: array
+ items:
+ type: number
+ unit: m
+ minItems: 2
+ maxItems: 2
+ - type: string
+ enum:
+ - n/a
+SequenceName:
+ name: SequenceName
+ display_name: Sequence Name
+ description: |
+ Manufacturer's designation of the sequence name.
+ Corresponds to DICOM Tag 0018, 0024 `Sequence Name`.
+ type: string
+SequenceVariant:
+ name: SequenceVariant
+ display_name: Sequence Variant
+ description: |
+ Variant of the ScanningSequence.
+ Corresponds to DICOM Tag 0018, 0021 `Sequence Variant`.
+ anyOf:
+ - type: string
+ - type: array
+ items:
+ type: string
+ShortChannelCount:
+ name: ShortChannelCount
+ display_name: Short Channel Count
+ description: |
+ The number of short channels. 0 indicates no short channels.
+ type: integer
+ minimum: 0
+SinglesRate:
+ name: SinglesRate
+ display_name: Singles Rate
+ description: |
+ Singles rate for each frame (same units as `Units`, for example, `"Bq/mL"`).
+ type: array
+ items:
+ type: number
+SkullStripped:
+ name: SkullStripped
+ display_name: Skull Stripped
+ description: |
+ Whether the volume was skull stripped (non-brain voxels set to zero) or not.
+ type: boolean
+SliceEncodingDirection:
+ name: SliceEncodingDirection
+ display_name: Slice Encoding Direction
+ description: |
+ The axis of the NIfTI data along which slices were acquired,
+ and the direction in which `"SliceTiming"` is defined with respect to.
+ `i`, `j`, `k` identifiers correspond to the first, second and third axis of
+ the data in the NIfTI file.
+ A `-` sign indicates that the contents of `"SliceTiming"` are defined in
+ reverse order - that is, the first entry corresponds to the slice with the
+ largest index, and the final entry corresponds to slice index zero.
+ When present, the axis defined by `"SliceEncodingDirection"` needs to be
+ consistent with the `slice_dim` field in the NIfTI header.
+ When absent, the entries in `"SliceTiming"` must be in the order of increasing
+ slice index as defined by the NIfTI header.
+ type: string
+ enum:
+ - $ref: objects.enums.i.value
+ - $ref: objects.enums.iMinus.value
+ - $ref: objects.enums.j.value
+ - $ref: objects.enums.jMinus.value
+ - $ref: objects.enums.k.value
+ - $ref: objects.enums.kMinus.value
+SliceThickness:
+ name: SliceThickness
+ display_name: Slice Thickness
+ description: |
+ Slice thickness of the tissue sample in the unit micrometers (`"um"`) (for example: `5`).
+ type: number
+ unit: um
+ exclusiveMinimum: 0
+SliceTiming:
+ name: SliceTiming
+ display_name: Slice Timing
+ description: |
+ The time at which each slice was acquired within each volume (frame) of the
+ acquisition.
+ Slice timing is not slice order -- rather, it is a list of times containing
+ the time (in seconds) of each slice acquisition in relation to the beginning
+ of volume acquisition.
+ The list goes through the slices along the slice axis in the slice encoding
+ dimension (see below).
+ Note that to ensure the proper interpretation of the `"SliceTiming"` field,
+ it is important to check if the OPTIONAL `SliceEncodingDirection` exists.
+ In particular, if `"SliceEncodingDirection"` is negative,
+ the entries in `"SliceTiming"` are defined in reverse order with respect to the
+ slice axis, such that the final entry in the `"SliceTiming"` list is the time
+ of acquisition of slice 0. Without this parameter slice time correction will
+ not be possible.
+ type: array
+ items:
+ type: number
+ minimum: 0
+ unit: s
+SoftwareFilters:
+ name: SoftwareFilters
+ display_name: Software Filters
+ description: |
+ [Object](https://www.json.org/json-en.html)
+ of temporal software filters applied, or `"n/a"` if the data is
+ not available.
+ Each key-value pair in the JSON object is a name of the filter and an object
+ in which its parameters are defined as key-value pairs
+ (for example, `{"Anti-aliasing filter":
+ {"half-amplitude cutoff (Hz)": 500, "Roll-off": "6dB/Octave"}}`).
+ anyOf:
+ - type: object
+ additionalProperties:
+ type: object
+ - type: string
+ enum:
+ - n/a
+SoftwareName:
+ name: SoftwareName
+ display_name: Software Name
+ description: |
+ Name of the software that was used to present the stimuli.
+ type: string
+SoftwareRRID:
+ name: SoftwareRRID
+ display_name: SoftwareRRID
+ description: |
+ [Research Resource Identifier](https://scicrunch.org/resources) of the
+ software that was used to present the stimuli.
+ Examples: The RRID for Psychtoolbox is 'SCR_002881',
+ and that of PsychoPy is 'SCR_006571'.
+ type: string
+ format: rrid
+SoftwareVersion:
+ name: SoftwareVersion
+ display_name: Software Version
+ description: |
+ Version of the software that was used to present the stimuli.
+ type: string
+SoftwareVersions:
+ name: SoftwareVersions
+ display_name: Software Versions
+ description: |
+ Manufacturer's designation of software version of the equipment that produced
+ the measurements.
+ type: string
+SourceDatasets:
+ name: SourceDatasets
+ display_name: Source Datasets
+ description: |
+ Used to specify the locations and relevant attributes of all source datasets.
+ Valid keys in each object include `"URL"`, `"DOI"` (see
+ [URI](SPEC_ROOT/common-principles.md#uniform-resource-indicator)), and
+ `"Version"` with
+ [string](https://www.w3schools.com/js/js_json_datatypes.asp)
+ values.
+ type: array
+ items:
+ type: object
+ properties:
+ URL:
+ type: string
+ format: uri
+ DOI:
+ type: string
+ Version:
+ type: string
+Sources:
+ name: Sources
+ display_name: Sources
+ description: |
+ A list of files with the paths specified using
+ [BIDS URIs](SPEC_ROOT/common-principles.md#bids-uri);
+ these files were directly used in the creation of this derivative data file.
+ For example, if a derivative A is used in the creation of another
+ derivative B, which is in turn used to generate C in a chain of A->B->C,
+ C should only list B in `"Sources"`, and B should only list A in `"Sources"`.
+ However, in case both X and Y are directly used in the creation of Z,
+ then Z should list X and Y in `"Sources"`,
+ regardless of whether X was used to generate Y.
+ Using paths specified relative to the dataset root is
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ type: array
+ items:
+ type: string
+ format: dataset_relative
+SourceType:
+ name: SourceType
+ display_name: Source Type
+ description: |
+ Type of source. Preferably a specific model/part number is supplied.
+ This is a freeform description, but the following keywords are suggested:
+ `"LED"`, `"LASER"`, `"VCSEL"`. If individual channels have different SourceType,
+ then the field here should be specified as "mixed"
+ and this column should be included in optodes.tsv.
+ type: string
+SpatialAxes:
+ name: SpatialAxes
+ display_name: Spatial axes
+ description: |
+ Refers to the coordinate system in which the motion data are to be interpreted,
+ if the recorded data can be mapped to a fixed reference frame. A sequence of
+ characters F/B (forward-backward), L/R (left-right), and U/D (up-down). The
+ position of a character in the sequence determines which of the X,Y,Z axes it
+ maps to. For example, "FRD" for X-forward, Y-right, Z-down. For 1D or 2D cases,
+ only specify the used axes and use the character "_" for unused axes
+ ("F_R" when the Y axis is not used, for instance).
+ type: string
+SpatialReference:
+ name: SpatialReference
+ display_name: Spatial Reference
+ description: |
+ For images with a single reference, the value MUST be a single string.
+ For images with multiple references, such as surface and volume references,
+ a JSON object MUST be used.
+ anyOf:
+ - type: string
+ enum:
+ - $ref: objects.enums.orig.value
+ - type: string
+ format: uri
+ - type: string
+ format: dataset_relative
+ - type: object
+ additionalProperties:
+ anyOf:
+ - type: string
+ enum:
+ - $ref: objects.enums.orig.value
+ - type: string
+ format: uri
+ - type: string
+ format: dataset_relative
+SpecificRadioactivity:
+ name: SpecificRadioactivity
+ display_name: Specific Radioactivity
+ description: |
+ Specific activity of compound injected.
+ **Note this is not required for an FDG acquisition, since it is not available,
+ and SHOULD be set to `"n/a"`**.
+ anyOf:
+ - type: number
+ - type: string
+ enum:
+ - n/a
+SpecificRadioactivityMeasTime:
+ name: SpecificRadioactivityMeasTime
+ display_name: Specific Radioactivity Measurement Time
+ description: |
+ Time to which specific radioactivity measurement above applies in the default
+ unit `"hh:mm:ss"`.
+ type: string
+ format: time
+SpecificRadioactivityUnits:
+ name: SpecificRadioactivityUnits
+ display_name: Specific Radioactivity Units
+ description: |
+ Unit format of specified specific radioactivity (for example, `"Bq/g"`).
+ **Note this is not required for an FDG acquisition, since it is not available,
+ and SHOULD be set to `"n/a"`**.
+ anyOf:
+ - type: string
+ format: unit
+ - type: string
+ enum:
+ - n/a
+SpoilingGradientDuration:
+ name: SpoilingGradientDuration
+ display_name: Spoiling Gradient Duration
+ description: |
+ The duration of the spoiler gradient lobe in seconds.
+ The duration of a trapezoidal lobe is defined as the summation of ramp-up
+ and plateau times.
+ type: number
+ unit: s
+SpoilingGradientMoment:
+ name: SpoilingGradientMoment
+ display_name: Spoiling Gradient Moment
+ description: |
+ Zeroth moment of the spoiler gradient lobe in
+ millitesla times second per meter (mT.s/m).
+ type: number
+ unit: mT.s/m
+SpoilingRFPhaseIncrement:
+ name: SpoilingRFPhaseIncrement
+ display_name: Spoiling RF Phase Increment
+ description: |
+ The amount of incrementation described in degrees,
+ which is applied to the phase of the excitation pulse at each TR period for
+ achieving RF spoiling.
+ type: number
+ unit: degree
+SpoilingState:
+ name: SpoilingState
+ display_name: Spoiling State
+ description: |
+ Boolean stating whether the pulse sequence uses any type of spoiling
+ strategy to suppress residual transverse magnetization.
+ type: boolean
+SpoilingType:
+ name: SpoilingType
+ display_name: Spoiling Type
+ description: |
+ Specifies which spoiling method(s) are used by a spoiled sequence.
+ type: string
+ enum:
+ - $ref: objects.enums.RF.value
+ - $ref: objects.enums.GRADIENT.value
+ - $ref: objects.enums.COMBINED.value
+StartTime:
+ name: StartTime
+ display_name: Start Time
+ description: |
+ Start time in seconds in relation to the start of acquisition of the first
+ data sample in the corresponding (neural) dataset (negative values are allowed).
+ This data MAY be specified with sub-second precision using the syntax `s[.000000]`,
+ where `s` reflects whole seconds, and `.000000` reflects OPTIONAL fractional seconds.
+ type: number
+ unit: s
+StationName:
+ name: StationName
+ display_name: Station Name
+ description: |
+ Institution defined name of the machine that produced the measurements.
+ type: string
+StimulusPresentation:
+ name: StimulusPresentation
+ display_name: Stimulus Presentation
+ description: |
+ Object containing key-value pairs related to the software used to present
+ the stimuli during the experiment.
+ type: object
+ recommended_fields:
+ - OperatingSystem
+ - ScreenDistance
+ - ScreenRefreshRate
+ - ScreenResolution
+ - ScreenSize
+ - SoftwareName
+ - SoftwareRRID
+ - SoftwareVersion
+ - Code
+ - HeadStabilization
+ properties:
+ OperatingSystem:
+ $ref: objects.metadata.OperatingSystem
+ ScreenDistance:
+ $ref: objects.metadata.ScreenDistance
+ ScreenRefreshRate:
+ $ref: objects.metadata.ScreenRefreshRate
+ ScreenResolution:
+ $ref: objects.metadata.ScreenResolution
+ ScreenSize:
+ $ref: objects.metadata.ScreenSize
+ SoftwareName:
+ $ref: objects.metadata.SoftwareName
+ SoftwareRRID:
+ $ref: objects.metadata.SoftwareRRID
+ SoftwareVersion:
+ $ref: objects.metadata.SoftwareVersion
+ Code:
+ $ref: objects.metadata.Code
+SubjectArtefactDescription:
+ name: SubjectArtefactDescription
+ display_name: Subject Artifact Description
+ description: |
+ Freeform description of the observed subject artifact and its possible cause
+ (for example, `"Vagus Nerve Stimulator"`, `"non-removable implant"`).
+ If this field is set to `"n/a"`, it will be interpreted as absence of major
+ source of artifacts except cardiac and blinks.
+ type: string
+TaskDescription:
+ name: TaskDescription
+ display_name: Task Description
+ description: |
+ Longer description of the task.
+ type: string
+TaskName:
+ name: TaskName
+ display_name: Task Name
+ description: |
+ Name of the task.
+ No two tasks should have the same name.
+ The task label included in the filename is derived from this `"TaskName"` field
+ by removing all non-alphanumeric characters (that is, all except those matching `[0-9a-zA-Z]`).
+ For example `"TaskName"` `"faces n-back"` or `"head nodding"` will correspond to task labels
+ `facesnback` and `headnodding`, respectively.
+ type: string
+TermURL:
+ name: TermURL
+ display_name: TermURL
+ description: |
+ URL pointing to a formal definition of this type of data in an ontology available on the web.
+ For example: https://www.ncbi.nlm.nih.gov/mesh/68008297 for "male".
+ type: string
+ format: uri
+TimeZero:
+ name: TimeZero
+ display_name: Time Zero
+ description: |
+ Time zero to which all scan and/or blood measurements have been adjusted to,
+ in the unit "hh:mm:ss".
+ This should be equal to `"InjectionStart"` or `"ScanStart"`.
+ type: string
+ format: time
+TissueDeformationScaling:
+ name: TissueDeformationScaling
+ display_name: Tissue Deformation Scaling
+ description: |
+ Estimated deformation of the tissue, given as a percentage of the original
+ tissue size (for examples: for a shrinkage of 3%, the value is `97`;
+ and for an expansion of 100%, the value is `200`).
+ type: number
+ exclusiveMinimum: 0
+TissueOrigin:
+ name: TissueOrigin
+ display_name: Tissue Origin
+ description: |
+ Describes the type of tissue analyzed for `"SampleOrigin"` `brain`.
+ type: string
+ enum:
+ - $ref: objects.enums.gray_matter.value
+ - $ref: objects.enums.white_matter.value
+ - $ref: objects.enums.csf.value
+ - $ref: objects.enums.meninges.value
+ - $ref: objects.enums.macrovascular.value
+ - $ref: objects.enums.microvascular.value
+TotalAcquiredPairs:
+ name: TotalAcquiredPairs
+ display_name: Total Acquired Pairs
+ description: |
+ The total number of acquired `control`-`label` pairs.
+ A single pair consists of a single `control` and a single `label` image.
+ type: number
+ exclusiveMinimum: 0
+TotalReadoutTime:
+ name: TotalReadoutTime
+ display_name: Total Readout Time
+ description: |
+ This is actually the "effective" total readout time,
+ defined as the readout duration, specified in seconds,
+ that would have generated data with the given level of distortion.
+ It is NOT the actual, physical duration of the readout train.
+ If `"EffectiveEchoSpacing"` has been properly computed,
+ it is just `EffectiveEchoSpacing * (ReconMatrixPE - 1)`.
+ type: number
+ unit: s
+TracerMolecularWeight:
+ name: TracerMolecularWeight
+ display_name: Tracer Molecular Weight
+ description: |
+ Accurate molecular weight of the tracer used.
+ type: number
+TracerMolecularWeightUnits:
+ name: TracerMolecularWeightUnits
+ display_name: Tracer Molecular Weight Units
+ description: |
+ Unit of the molecular weights measurement (for example, `"g/mol"`).
+ type: string
+ format: unit
+TracerName:
+ name: TracerName
+ display_name: Tracer Name
+ description: |
+ Name of the tracer compound used (for example, `"CIMBI-36"`)
+ type: string
+TracerRadLex:
+ name: TracerRadLex
+ display_name: Tracer Rad Lex
+ description: |
+ ID of the tracer compound from the RadLex Ontology.
+ type: string
+TracerRadionuclide:
+ name: TracerRadionuclide
+ display_name: Tracer Radionuclide
+ description: |
+ Radioisotope labeling tracer (for example, `"C11"`).
+ type: string
+TracerSNOMED:
+ name: TracerSNOMED
+ display_name: TracerSNOMED
+ description: |
+ ID of the tracer compound from the SNOMED Ontology
+ (subclass of Radioactive isotope).
+ type: string
+TubingLength:
+ name: TubingLength
+ display_name: Tubing Length
+ description: |
+ The length of the blood tubing, from the subject to the detector in meters.
+ type: number
+ unit: m
+TriggerChannelCount:
+ name: TriggerChannelCount
+ display_name: Trigger Channel Count
+ description: |
+ Number of channels for digital (binary TTL) triggers or analog equivalents (TTL in volt).
+ Corresponds to the `TRIG` channel type.
+ type: integer
+ minimum: 0
+TrackedPointsCount:
+ name: TrackedPointsCount
+ display_name: Tracked Points Count
+ description: |
+ Number of different tracked points tracked in a motion tracking system.
+ type: number
+ unit: m
+TrackingSystemName:
+ name: TrackingSystemName
+ display_name: Tracking System Name
+ description: |
+ A human-readable name of the tracking system to complement `"tracksys"` label
+ of the corresponding *_motion.tsv filename.
+ type: string
+TubingType:
+ name: TubingType
+ display_name: Tubing Type
+ description: |
+ Description of the type of tubing used, ideally including the material and
+ (internal) diameter.
+ type: string
+Type:
+ name: Type
+ display_name: Type
+ description: |
+ Short identifier of the mask.
+ The value `"Brain"` refers to a brain mask.
+ The value `"Lesion"` refers to a lesion mask.
+ The value `"Face"` refers to a face mask.
+ The value `"ROI"` refers to a region of interest mask.
+ type: string
+ enum:
+ - $ref: objects.enums.Brain.value
+ - $ref: objects.enums.Lesion.value
+ - $ref: objects.enums.Face.value
+ - $ref: objects.enums.ROI.value
+Units:
+ name: Units
+ display_name: Units
+ description: |
+ Measurement units for the associated file.
+ SI units in CMIXF formatting are RECOMMENDED
+ (see [Units](SPEC_ROOT/common-principles.md#units)).
+ type: string
+ format: unit
+VascularCrushing:
+ name: VascularCrushing
+ display_name: Vascular Crushing
+ description: |
+ Boolean indicating if Vascular Crushing is used.
+ Corresponds to DICOM Tag 0018, 9259 `ASL Crusher Flag`.
+ type: boolean
+VascularCrushingVENC:
+ name: VascularCrushingVENC
+ display_name: Vascular Crushing VENC
+ description: |
+ The crusher gradient strength, in centimeters per second.
+ Specify either one number for the total time-series, or provide an array of
+ numbers, for example when using QUASAR, using the value zero to identify
+ volumes for which `VascularCrushing` was turned off.
+ Corresponds to DICOM Tag 0018, 925A `ASL Crusher Flow Limit`.
+ anyOf:
+ - type: number
+ unit: cm/s
+ - type: array
+ items:
+ type: number
+ unit: cm/s
+VELChannelCount:
+ name: VELChannelCount
+ display_name: Velocity Channel Count
+ description: |
+ Number of linear velocity channels.
+ type: integer
+ minimum: 0
+VisionCorrection:
+ name: VisionCorrection
+ display_name: Vision correction
+ description: |
+ Equipment used to correct participant vision during an experiment.
+ Example: "spectacles", "lenses", "none".
+ type: string
+VolumeTiming:
+ name: VolumeTiming
+ display_name: Volume Timing
+ description: |
+ The time at which each volume was acquired during the acquisition.
+ It is described using a list of times referring to the onset of each volume
+ in the BOLD series.
+ The list must have the same length as the BOLD series,
+ and the values must be non-negative and monotonically increasing.
+ This field is mutually exclusive with `"RepetitionTime"` and `"DelayTime"`.
+ If defined, this requires acquisition time (TA) be defined via either
+ `"SliceTiming"` or `"AcquisitionDuration"` be defined.
+ type: array
+ minItems: 1
+ items:
+ type: number
+ unit: s
+WholeBloodAvail:
+ name: WholeBloodAvail
+ display_name: Whole Blood Avail
+ description: |
+ Boolean that specifies if whole blood measurements are available.
+ If `true`, the `whole_blood_radioactivity` column MUST be present in the
+ corresponding `*_blood.tsv` file.
+ type: boolean
+WithdrawalRate:
+ name: WithdrawalRate
+ display_name: Withdrawal Rate
+ description: |
+ The rate at which the blood was withdrawn from the subject.
+ The unit of the specified withdrawal rate should be in `"mL/s"`.
+ type: number
+ unit: mL/s
+iEEGCoordinateProcessingDescription:
+ name: iEEGCoordinateProcessingDescription
+ display_name: iEEG Coordinate Processing Description
+ description: |
+ Has any post-processing (such as projection) been done on the electrode
+ positions (for example, `"surface_projection"`, `"none"`).
+ type: string
+iEEGCoordinateProcessingReference:
+ name: iEEGCoordinateProcessingReference
+ display_name: iEEG Coordinate Processing Reference
+ description: |
+ A reference to a paper that defines in more detail the method used to
+ localize the electrodes and to post-process the electrode positions.
+ type: string
+iEEGCoordinateSystem:
+ name: iEEGCoordinateSystem
+ display_name: iEEG Coordinate System
+ description: |
+ Defines the coordinate system for the iEEG sensors.
+ See the
+ [Coordinate Systems Appendix](SPEC_ROOT/appendices/coordinate-systems.md)
+ for a list of restricted keywords for coordinate systems.
+ If `"Other"`, provide definition of the coordinate system in
+ `iEEGCoordinateSystemDescription`.
+ If positions correspond to pixel indices in a 2D image
+ (of either a volume-rendering, surface-rendering, operative photo, or
+ operative drawing), this MUST be `"Pixels"`.
+ For more information, see the section on
+ [2D coordinate systems](SPEC_ROOT/modality-specific-files/intracranial\
+ -electroencephalography.md#allowed-2d-coordinate-systems).
+ anyOf:
+ - $ref: objects.enums._iEEGCoordSys
+ - $ref: objects.enums._StandardTemplateCoordSys
+ - $ref: objects.enums._StandardTemplateDeprecatedCoordSys
+iEEGCoordinateSystemDescription:
+ name: iEEGCoordinateSystemDescription
+ display_name: iEEG Coordinate System Description
+ description: |
+ Free-form text description of the coordinate system.
+ May also include a link to a documentation page or paper describing the
+ system in greater detail.
+ type: string
+iEEGCoordinateUnits:
+ name: iEEGCoordinateUnits
+ display_name: iEEG Coordinate Units
+ description: |
+ Units of the `*_electrodes.tsv`.
+ MUST be `"pixels"` if `iEEGCoordinateSystem` is `Pixels`.
+ type: string
+ enum:
+ - $ref: objects.enums.pixels.value
+ # TODO: Add definitions for these values. (perhaps don't specify)
+ - m
+ - mm
+ - cm
+ - n/a
+iEEGElectrodeGroups:
+ name: iEEGElectrodeGroups
+ display_name: iEEG Electrode Groups
+ description: |
+ Field to describe the way electrodes are grouped into strips, grids or depth
+ probes.
+ For example, `"grid1: 10x8 grid on left temporal pole, strip2: 1x8 electrode
+ strip on xxx"`.
+ type: string
+iEEGGround:
+ name: iEEGGround
+ display_name: iEEG Ground
+ description: |
+ Description of the location of the ground electrode
+ (`"placed on right mastoid (M2)"`).
+ type: string
+iEEGPlacementScheme:
+ name: iEEGPlacementScheme
+ display_name: iEEG Placement Scheme
+ description: |
+ Freeform description of the placement of the iEEG electrodes.
+ Left/right/bilateral/depth/surface
+ (for example, `"left frontal grid and bilateral hippocampal depth"` or
+ `"surface strip and STN depth"` or
+ `"clinical indication bitemporal, bilateral temporal strips and left grid"`).
+ type: string
+iEEGReference:
+ name: iEEGReference
+ display_name: iEEG Reference
+ description: |
+ General description of the reference scheme used and (when applicable) of
+ location of the reference electrode in the raw recordings
+ (for example, `"left mastoid"`, `"bipolar"`,
+ `"T01"` for electrode with name T01,
+ `"intracranial electrode on top of a grid, not included with data"`,
+ `"upside down electrode"`).
+ If different channels have a different reference,
+ this field should have a general description and the channel specific
+ reference should be defined in the `channels.tsv` file.
+ type: string
diff --git a/bep32v01/ressources/schema/objects/modalities.yaml b/bep32v01/ressources/schema/objects/modalities.yaml
new file mode 100644
index 00000000..4809e380
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/modalities.yaml
@@ -0,0 +1,37 @@
+---
+# This file describes modalities supported by BIDS.
+mri:
+ display_name: Magnetic Resonance Imaging
+ description: |
+ Data acquired with an MRI scanner.
+eeg:
+ display_name: Electroencephalography
+ description: |
+ Data acquired with EEG.
+ieeg:
+ display_name: Intracranial Electroencephalography
+ description: |
+ Data acquired with iEEG.
+meg:
+ display_name: Magnetoencephalography
+ description: |
+ Data acquired with an MEG scanner.
+beh:
+ display_name: Behavioral experiments
+ description: |
+ Behavioral data acquired without accompanying neuroimaging data.
+pet:
+ display_name: Positron Emission Tomography
+ description: |
+ Data acquired with PET.
+micr:
+ display_name: Microscopy
+ description: |
+ Data acquired with a microscope.
+motion:
+ display_name: Motion
+ description: |
+ Data acquired with Motion-Capture systems.
+nirs:
+ display_name: Near-Infrared Spectroscopy
+ description: Data acquired with NIRS.
diff --git a/bep32v01/ressources/schema/objects/suffixes.yaml b/bep32v01/ressources/schema/objects/suffixes.yaml
new file mode 100644
index 00000000..13ee57eb
--- /dev/null
+++ b/bep32v01/ressources/schema/objects/suffixes.yaml
@@ -0,0 +1,785 @@
+---
+# This file defines valid BIDS file suffixes.
+# For rules regarding how suffixes relate to datatypes, see files in `rules/files/raw/`.
+TwoPE:
+ value: 2PE
+ display_name: 2-photon excitation microscopy
+ description: |
+ 2-photon excitation microscopy imaging data
+BF:
+ value: BF
+ display_name: Bright-field microscopy
+ description: |
+ Bright-field microscopy imaging data
+Chimap:
+ value: Chimap
+ display_name: Quantitative susceptibility map (QSM)
+ description: |
+ In parts per million (ppm).
+ QSM allows for determining the underlying magnetic susceptibility of tissue
+ (Chi)
+ ([Wang & Liu, 2014](https://doi.org/10.1002/mrm.25358)).
+ Chi maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: ppm
+CARS:
+ value: CARS
+ display_name: Coherent anti-Stokes Raman spectroscopy
+ description: |
+ Coherent anti-Stokes Raman spectroscopy imaging data
+CONF:
+ value: CONF
+ display_name: Confocal microscopy
+ description: |
+ Confocal microscopy imaging data
+DIC:
+ value: DIC
+ display_name: Differential interference contrast microscopy
+ description: |
+ Differential interference contrast microscopy imaging data
+DF:
+ value: DF
+ display_name: Dark-field microscopy
+ description: |
+ Dark-field microscopy imaging data
+FLAIR:
+ value: FLAIR
+ display_name: Fluid attenuated inversion recovery image
+ description: |
+ In arbitrary units (arbitrary).
+ Structural images with predominant T2 contribution (also known as T2-FLAIR),
+ in which signal from fluids (for example, CSF) is nulled out by adjusting
+ inversion time, coupled with notably long repetition and echo times.
+ unit: arbitrary
+FLASH:
+ value: FLASH
+ display_name: Fast-Low-Angle-Shot image
+ description: |
+ FLASH (Fast-Low-Angle-Shot) is a vendor-specific implementation for spoiled
+ gradient echo acquisition.
+ It is commonly used for rapid anatomical imaging and also for many different
+ qMRI applications.
+ When used for a single file, it does not convey any information about the
+ image contrast.
+ When used in a file collection, it may result in conflicts across filenames of
+ different applications.
+ **Change:** Removed from suffixes.
+FLUO:
+ value: FLUO
+ display_name: Fluorescence microscopy
+ description: |
+ Fluorescence microscopy imaging data
+IRT1:
+ value: IRT1
+ display_name: Inversion recovery T1 mapping
+ description: |
+ The IRT1 method involves multiple inversion recovery spin-echo images
+ acquired at different inversion times
+ ([Barral et al. 2010](https://doi.org/10.1002/mrm.22497)).
+M0map:
+ value: M0map
+ display_name: Equilibrium magnetization (M0) map
+ description: |
+ In arbitrary units (arbitrary).
+ A common quantitative MRI (qMRI) fitting variable that represents the amount
+ of magnetization at thermal equilibrium.
+ M0 maps are RECOMMENDED to use this suffix if generated by qMRI applications
+ (for example, variable flip angle T1 mapping).
+ unit: arbitrary
+MEGRE:
+ value: MEGRE
+ display_name: Multi-echo Gradient Recalled Echo
+ description: |
+ Anatomical gradient echo images acquired at different echo times.
+ Please note that this suffix is not intended for the logical grouping of
+ images acquired using an Echo Planar Imaging (EPI) readout.
+MESE:
+ value: MESE
+ display_name: Multi-echo Spin Echo
+ description: |
+ The MESE method involves multiple spin echo images acquired at different echo
+ times and is primarily used for T2 mapping.
+ Please note that this suffix is not intended for the logical grouping of
+ images acquired using an Echo Planar Imaging (EPI) readout.
+MP2RAGE:
+ value: MP2RAGE
+ display_name: Magnetization Prepared Two Gradient Echoes
+ description: |
+ The MP2RAGE method is a special protocol that collects several images at
+ different flip angles and inversion times to create a parametric T1map by
+ combining the magnitude and phase images
+ ([Marques et al. 2010](https://doi.org/10.1016/j.neuroimage.2009.10.002)).
+MPE:
+ value: MPE
+ display_name: Multi-photon excitation microscopy
+ description: |
+ Multi-photon excitation microscopy imaging data
+MPM:
+ value: MPM
+ display_name: Multi-parametric Mapping
+ description: |
+ The MPM approaches (a.k.a hMRI) involves the acquisition of highly-similar
+ anatomical images that differ in terms of application of a magnetization
+ transfer RF pulse (MTon or MToff), flip angle and (optionally) echo time and
+ magnitue/phase parts
+ ([Weiskopf et al. 2013](https://doi.org/10.3389/fnins.2013.00095)).
+ See [here](https://owncloud.gwdg.de/index.php/s/iv2TOQwGy4FGDDZ) for
+ suggested MPM acquisition protocols.
+MTR:
+ value: MTR
+ display_name: Magnetization Transfer Ratio
+ description: |
+ This method is to calculate a semi-quantitative magnetization transfer ratio
+ map.
+MTRmap:
+ value: MTRmap
+ display_name: Magnetization transfer ratio image
+ description: |
+ In arbitrary units (arbitrary).
+ MTR maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ MTRmap intensity values are RECOMMENDED to be represented in percentage in
+ the range of 0-100%.
+ unit: arbitrary
+ minValue: 0
+ maxValue: 100
+MTS:
+ value: MTS
+ display_name: Magnetization transfer saturation
+ description: |
+ This method is to calculate a semi-quantitative magnetization transfer
+ saturation index map.
+ The MTS method involves three sets of anatomical images that differ in terms
+ of application of a magnetization transfer RF pulse (MTon or MToff) and flip
+ angle ([Helms et al. 2008](https://doi.org/10.1002/mrm.21732)).
+MTVmap:
+ value: MTVmap
+ display_name: Macromolecular tissue volume (MTV) image
+ description: |
+ In arbitrary units (arbitrary).
+ MTV maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: arbitrary
+MTsat:
+ value: MTsat
+ display_name: Magnetization transfer saturation image
+ description: |
+ In arbitrary units (arbitrary).
+ MTsat maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: arbitrary
+MWFmap:
+ value: MWFmap
+ display_name: Myelin water fraction image
+ description: |
+ In arbitrary units (arbitrary).
+ MWF maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ MWF intensity values are RECOMMENDED to be represented in percentage in the
+ range of 0-100%.
+ unit: arbitrary
+ minValue: 0
+ maxValue: 100
+NLO:
+ value: NLO
+ display_name: Nonlinear optical microscopy
+ description: |
+ Nonlinear optical microscopy imaging data
+OCT:
+ value: OCT
+ display_name: Optical coherence tomography
+ description: |
+ Optical coherence tomography imaging data
+PC:
+ value: PC
+ display_name: Phase-contrast microscopy
+ description: |
+ Phase-contrast microscopy imaging data
+PD:
+ value: PD
+ display_name: Proton density image
+ description: |
+ Ambiguous, may refer to a parametric image or to a conventional image.
+ **Change:** Replaced by `PDw` or `PDmap`.
+ unit: arbitrary
+PDT2:
+ value: PDT2
+ display_name: PD and T2 weighted image
+ description: |
+ In arbitrary units (arbitrary).
+ A two-volume 4D image, where the volumes are, respectively, PDw and T2w
+ images acquired simultaneously.
+ If separated into 3D volumes, the `PDw` and `T2w` suffixes SHOULD be used instead,
+ and an acquisition entity MAY be used to distinguish the images from others with
+ the same suffix, for example, `acq-PDT2_PDw.nii` and `acq-PDT2_T2w.nii`.
+ unit: arbitrary
+PDmap:
+ value: PDmap
+ display_name: Proton density image
+ description: |
+ In arbitrary units (arbitrary).
+ PD maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: arbitrary
+PDw:
+ value: PDw
+ display_name: Proton density (PD) weighted image
+ description: |
+ In arbitrary units (arbitrary).
+ The contrast of these images is mainly determined by spatial variations in
+ the spin density (1H) of the imaged specimen.
+ This contrast is achieved at short echo times and long repetition times;
+ for gradient echo, this weighting is also possible with a short TR (TR<-1 (1/s).
+ R1 maps (R1 = 1/T1) are REQUIRED to use this suffix regardless of the method
+ used to generate them.
+ unit: 1/s
+R2map:
+ value: R2map
+ display_name: True transverse relaxation rate image
+ description: |
+ In seconds-1 (1/s).
+ R2 maps (R2 = 1/T2) are REQUIRED to use this suffix regardless of the method
+ used to generate them.
+ unit: 1/s
+R2starmap:
+ value: R2starmap
+ display_name: Observed transverse relaxation rate image
+ description: |
+ In seconds-1 (1/s).
+ R2-star maps (R2star = 1/T2star) are REQUIRED to use this suffix regardless
+ of the method used to generate them.
+ unit: 1/s
+RB1COR:
+ value: RB1COR
+ display_name: RB1COR
+ description: |
+ Low resolution images acquired by the body coil
+ (in the gantry of the scanner) and the head coil using identical acquisition
+ parameters to generate a combined sensitivity map as described in
+ [Papp et al. (2016)](https://doi.org/10.1002/mrm.26058).
+RB1map:
+ value: RB1map
+ display_name: RF receive sensitivity map
+ description: |
+ In arbitrary units (arbitrary).
+ Radio frequency (RF) receive (B1-) sensitivity maps are REQUIRED to use this
+ suffix regardless of the method used to generate them.
+ RB1map intensity values are RECOMMENDED to be represented as percent
+ multiplicative factors such that Amplitudeeffective =
+ B1-intensity \*Amplitudeideal .
+ unit: arbitrary
+S0map:
+ value: S0map
+ display_name: Observed signal amplitude (S0) image
+ description: |
+ In arbitrary units (arbitrary).
+ For a multi-echo (typically fMRI) sequence, S0 maps index the baseline signal
+ before exponential (T2-star) signal decay.
+ In other words: the exponential of the intercept for a linear decay model
+ across log-transformed echos. For more information, please see, for example,
+ [the tedana documentation](https://tedana.readthedocs.io/en/latest/\
+ approach.html#monoexponential-decay-model-fit).
+ S0 maps are RECOMMENDED to use this suffix if derived from an ME-FMRI dataset.
+SEM:
+ value: SEM
+ display_name: Scanning electron microscopy
+ description: |
+ Scanning electron microscopy imaging data
+SPIM:
+ value: SPIM
+ display_name: Selective plane illumination microscopy
+ description: |
+ Selective plane illumination microscopy imaging data
+SR:
+ value: SR
+ display_name: Super-resolution microscopy
+ description: |
+ Super-resolution microscopy imaging data
+T1map:
+ value: T1map
+ display_name: Longitudinal relaxation time image
+ description: |
+ In seconds (s).
+ T1 maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ See [this interactive book on T1 mapping](https://qmrlab.org/t1_book/intro)
+ for further reading on T1-mapping.
+ unit: s
+T1rho:
+ value: T1rho
+ display_name: T1 in rotating frame (T1 rho) image
+ description: |
+ In seconds (s).
+ T1-rho maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: s
+T1w:
+ value: T1w
+ display_name: T1-weighted image
+ description: |
+ In arbitrary units (arbitrary).
+ The contrast of these images is mainly determined by spatial variations in
+ the longitudinal relaxation time of the imaged specimen.
+ In spin-echo sequences this contrast is achieved at relatively short
+ repetition and echo times.
+ To achieve this weighting in gradient-echo images, again, short repetition
+ and echo times are selected; however, at relatively large flip angles.
+ Another common approach to increase T1 weighting in gradient-echo images is
+ to add an inversion preparation block to the beginning of the imaging
+ sequence (for example, `TurboFLASH` or `MP-RAGE`).
+ unit: arbitrary
+T2map:
+ value: T2map
+ display_name: True transverse relaxation time image
+ description: |
+ In seconds (s).
+ T2 maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: s
+T2star:
+ value: T2star
+ display_name: T2\* image
+ description: |
+ Ambiguous, may refer to a parametric image or to a conventional image.
+ **Change:** Replaced by `T2starw` or `T2starmap`.
+ anyOf:
+ - unit: arbitrary
+ - unit: s
+T2starmap:
+ value: T2starmap
+ display_name: Observed transverse relaxation time image
+ description: |
+ In seconds (s).
+ T2-star maps are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ unit: s
+T2starw:
+ value: T2starw
+ display_name: T2star weighted image
+ description: |
+ In arbitrary units (arbitrary).
+ The contrast of these images is mainly determined by spatial variations in
+ the (observed) transverse relaxation time of the imaged specimen.
+ In spin-echo sequences, this effect is negated as the excitation is followed
+ by an inversion pulse.
+ The contrast of gradient-echo images natively depends on T2-star effects.
+ However, for T2-star variation to dominate the image contrast,
+ gradient-echo acquisitions are carried out at long repetition and echo times,
+ and at small flip angles.
+ unit: arbitrary
+T2w:
+ value: T2w
+ display_name: T2-weighted image
+ description: |
+ In arbitrary units (arbitrary).
+ The contrast of these images is mainly determined by spatial variations in
+ the (true) transverse relaxation time of the imaged specimen.
+ In spin-echo sequences this contrast is achieved at relatively long
+ repetition and echo times.
+ Generally, gradient echo sequences are not the most suitable option for
+ achieving T2 weighting, as their contrast natively depends on T2-star rather
+ than on T2.
+ unit: arbitrary
+TB1AFI:
+ value: TB1AFI
+ display_name: TB1AFI
+ description: |
+ This method ([Yarnykh 2007](https://doi.org/10.1002/mrm.21120))
+ calculates a B1+ map from two images acquired at interleaved (two)
+ TRs with identical RF pulses using a steady-state sequence.
+TB1DAM:
+ value: TB1DAM
+ display_name: TB1DAM
+ description: |
+ The double-angle B1+ method
+ ([Insko and Bolinger 1993](https://doi.org/10.1006/jmra.1993.1133)) is based
+ on the calculation of the actual angles from signal ratios,
+ collected by two acquisitions at different nominal excitation flip angles.
+ Common sequence types for this application include spin echo and echo planar
+ imaging.
+TB1EPI:
+ value: TB1EPI
+ display_name: TB1EPI
+ description: |
+ This B1+ mapping method
+ ([Jiru and Klose 2006](https://doi.org/10.1002/mrm.21083)) is based on two
+ EPI readouts to acquire spin echo (SE) and stimulated echo (STE) images at
+ multiple flip angles in one sequence, used in the calculation of deviations
+ from the nominal flip angle.
+TB1RFM:
+ value: TB1RFM
+ display_name: TB1RFM
+ description: |
+ The result of a Siemens `rf_map` product sequence.
+ This sequence produces two images.
+ The first image appears like an anatomical image and the second output is a
+ scaled flip angle map.
+TB1SRGE:
+ value: TB1SRGE
+ display_name: TB1SRGE
+ description: |
+ Saturation-prepared with 2 rapid gradient echoes (SA2RAGE) uses a ratio of
+ two saturation recovery images with different time delays,
+ and a simulated look-up table to estimate B1+
+ ([Eggenschwiler et al. 2011](https://doi.org/10.1002/mrm.23145)).
+ This sequence can also be used in conjunction with MP2RAGE T1 mapping to
+ iteratively improve B1+ and T1 map estimation
+ ([Marques & Gruetter 2013](https://doi.org/10.1371/journal.pone.0069294)).
+TB1TFL:
+ value: TB1TFL
+ display_name: TB1TFL
+ description: |
+ The result of a Siemens `tfl_b1_map` product sequence.
+ This sequence produces two images.
+ The first image appears like an anatomical image and the second output is a
+ scaled flip angle map.
+TB1map:
+ value: TB1map
+ display_name: RF transmit field image
+ description: |
+ In arbitrary units (arbitrary).
+ Radio frequency (RF) transmit (B1+) field maps are REQUIRED to use this
+ suffix regardless of the method used to generate them.
+ TB1map intensity values are RECOMMENDED to be represented as percent
+ multiplicative factors such that FlipAngleeffective =
+ B1+intensity \*FlipAnglenominal .
+ unit: arbitrary
+TEM:
+ value: TEM
+ display_name: Transmission electron microscopy
+ description: |
+ Transmission electron microscopy imaging data
+UNIT1:
+ value: UNIT1
+ display_name: Homogeneous (flat) T1-weighted MP2RAGE image
+ description: |
+ In arbitrary units (arbitrary).
+ UNIT1 images are REQUIRED to use this suffix regardless of the method used to
+ generate them.
+ Note that although this image is T1-weighted, regions without MR signal will
+ contain white salt-and-pepper noise that most segmentation algorithms will
+ fail on.
+ Therefore, it is important to dissociate it from `T1w`.
+ Please see [`MP2RAGE` specific notes](SPEC_ROOT/appendices/qmri.md#unit1-images)
+ in the qMRI appendix for further information.
+VFA:
+ value: VFA
+ display_name: Variable flip angle
+ description: |
+ The VFA method involves at least two spoiled gradient echo (SPGR) of
+ steady-state free precession (SSFP) images acquired at different flip angles.
+ Depending on the provided metadata fields and the sequence type,
+ data may be eligible for DESPOT1, DESPOT2 and their variants
+ ([Deoni et al. 2005](https://doi.org/10.1002/mrm.20314)).
+angio:
+ value: angio
+ display_name: Angiogram
+ description: |
+ Magnetic resonance angiography sequences focus on enhancing the contrast of
+ blood vessels (generally arteries, but sometimes veins) against other tissue
+ types.
+asl:
+ value: asl
+ display_name: Arterial Spin Labeling
+ description: |
+ The complete ASL time series stored as a 4D NIfTI file in the original
+ acquisition order, with possible volume types including: control, label,
+ m0scan, deltam, cbf.
+aslcontext:
+ value: aslcontext
+ display_name: Arterial Spin Labeling Context
+ description: |
+ A TSV file defining the image types for volumes in an associated ASL file.
+asllabeling:
+ value: asllabeling
+ display_name: ASL Labeling Screenshot
+ description: |
+ An anonymized screenshot of the planning of the labeling slab/plane
+ with respect to the imaging slab or slices.
+ This screenshot is based on DICOM macro C.8.13.5.14.
+beh:
+ value: beh
+ display_name: Behavioral recording
+ description: |
+ Behavioral recordings from tasks.
+ These files are similar to events files, but do not include the `"onset"` and
+ `"duration"` columns that are mandatory for events files.
+blood:
+ value: blood
+ display_name: Blood recording data
+ description: |
+ Blood measurements of radioactivity stored in
+ [tabular files](SPEC_ROOT/common-principles.md#tabular-files)
+ and located in the `pet/` directory along with the corresponding PET data.
+bold:
+ value: bold
+ display_name: Blood-Oxygen-Level Dependent image
+ description: |
+ Blood-Oxygen-Level Dependent contrast (specialized T2\* weighting)
+cbv:
+ value: cbv
+ display_name: Cerebral blood volume image
+ description: |
+ Cerebral Blood Volume contrast (specialized T2\* weighting or difference between T1 weighted images)
+channels:
+ value: channels
+ display_name: Channels File
+ description: |
+ Channel information.
+coordsystem:
+ value: coordsystem
+ display_name: Coordinate System File
+ description: |
+ A JSON document specifying the coordinate system(s) used for the MEG, EEG,
+ head localization coils, and anatomical landmarks.
+defacemask:
+ value: defacemask
+ display_name: Defacing Mask
+ description: |
+ A binary mask that was used to remove facial features from an anatomical MRI
+ image.
+dseg:
+ value: dseg
+ display_name: Discrete Segmentation
+ description: |
+ A discrete segmentation.
+
+ This suffix may only be used in derivative datasets.
+dwi:
+ value: dwi
+ display_name: Diffusion-weighted image
+ description: |
+ Diffusion-weighted imaging contrast (specialized T2 weighting).
+eeg:
+ value: eeg
+ display_name: Electroencephalography
+ description: |
+ Electroencephalography recording data.
+electrodes:
+ value: electrodes
+ display_name: Electrodes
+ description: |
+ File that gives the location of (i)EEG electrodes.
+epi:
+ value: epi
+ display_name: EPI
+ description: |
+ The phase-encoding polarity (PEpolar) technique combines two or more Spin Echo
+ EPI scans with different phase encoding directions to estimate the underlying
+ inhomogeneity/deformation map.
+events:
+ value: events
+ display_name: Events
+ description: |
+ Event timing information from a behavioral task.
+fieldmap:
+ value: fieldmap
+ display_name: Fieldmap
+ description: |
+ Some MR schemes such as spiral-echo imaging (SEI) sequences are able to
+ directly provide maps of the *B0 * field inhomogeneity.
+headshape:
+ value: headshape
+ display_name: Headshape File
+ description: |
+ The 3-D locations of points that describe the head shape and/or electrode
+ locations can be digitized and stored in separate files.
+hipCT:
+ value: hipCT
+ display_name: HiP-CT
+ description: |
+ Hierarchical Phase-Contrast Tomography imaging data
+ieeg:
+ value: ieeg
+ display_name: Intracranial Electroencephalography
+ description: |
+ Intracranial electroencephalography recording data.
+inplaneT1:
+ value: inplaneT1
+ display_name: Inplane T1
+ description: |
+ In arbitrary units (arbitrary).
+ T1 weighted structural image matched to a functional (task) image.
+ unit: arbitrary
+inplaneT2:
+ value: inplaneT2
+ display_name: Inplane T2
+ description: |
+ In arbitrary units (arbitrary).
+ T2 weighted structural image matched to a functional (task) image.
+ unit: arbitrary
+m0scan:
+ value: m0scan
+ display_name: M0 image
+ description: |
+ The M0 image is a calibration image, used to estimate the equilibrium
+ magnetization of blood.
+magnitude:
+ value: magnitude
+ display_name: Magnitude
+ description: |
+ Field-mapping MR schemes such as gradient-recalled echo (GRE) generate a
+ Magnitude image to be used for anatomical reference.
+ Requires the existence of Phase, Phase-difference or Fieldmap maps.
+magnitude1:
+ value: magnitude1
+ display_name: Magnitude
+ description: |
+ Magnitude map generated by GRE or similar schemes, associated with the first
+ echo in the sequence.
+magnitude2:
+ value: magnitude2
+ display_name: Magnitude
+ description: |
+ Magnitude map generated by GRE or similar schemes, associated with the second
+ echo in the sequence.
+markers:
+ value: markers
+ display_name: MEG Sensor Coil Positions
+ description: |
+ Another manufacturer-specific detail pertains to the KIT/Yokogawa/Ricoh
+ system, which saves the MEG sensor coil positions in a separate file with two
+ possible filename extensions (`.sqd`, `.mrk`).
+ For these files, the `markers` suffix MUST be used.
+ For example: `sub-01_task-nback_markers.sqd`
+mask:
+ value: mask
+ display_name: Binary Mask
+ description: |
+ A binary mask that functions as a discrete "label" for a single structure.
+
+ This suffix may only be used in derivative datasets.
+meg:
+ value: meg
+ display_name: Magnetoencephalography
+ description: |
+ Unprocessed MEG data stored in the native file format of the MEG instrument
+ with which the data was collected.
+motion:
+ value: motion
+ display_name: Motion
+ description: |
+ Data recorded from a tracking system store.
+nirs:
+ value: nirs
+ display_name: Near Infrared Spectroscopy
+ description: Data associated with a Shared Near Infrared Spectroscopy Format file.
+optodes:
+ value: optodes
+ display_name: Optodes
+ description: |
+ Either a light emitting device, sometimes called a transmitter, or a photoelectric transducer, sometimes called a
+ receiver.
+pet:
+ value: pet
+ display_name: Positron Emission Tomography
+ description: |
+ PET imaging data SHOULD be stored in 4D
+ (or 3D, if only one volume was acquired) NIfTI files with the `_pet` suffix.
+ Volumes MUST be stored in chronological order
+ (the order they were acquired in).
+phase:
+ value: phase
+ display_name: Phase image
+ description: |
+ [DEPRECATED](SPEC_ROOT/common-principles.md#definitions).
+ Phase information associated with magnitude information stored in BOLD
+ contrast.
+ This suffix should be replaced by the
+ [`part-phase`](SPEC_ROOT/appendices/entities.md#part)
+ in conjunction with the `bold` suffix.
+ anyOf:
+ - unit: arbitrary
+ - unit: rad
+phase1:
+ value: phase1
+ display_name: Phase
+ description: |
+ Phase map generated by GRE or similar schemes, associated with the first
+ echo in the sequence.
+phase2:
+ value: phase2
+ display_name: Phase
+ description: |
+ Phase map generated by GRE or similar schemes, associated with the second
+ echo in the sequence.
+phasediff:
+ value: phasediff
+ display_name: Phase-difference
+ description: |
+ Some scanners subtract the `phase1` from the `phase2` map and generate a
+ unique `phasediff` file.
+ For instance, this is a common output for the built-in fieldmap sequence of
+ Siemens scanners.
+photo:
+ value: photo
+ display_name: Photo File
+ description: |
+ Photos of the anatomical landmarks, head localization coils or tissue sample.
+physio:
+ value: physio
+ display_name: Physiological recording
+ description: |
+ Physiological recordings such as cardiac and respiratory signals.
+probseg:
+ value: probseg
+ display_name: Probabilistic Segmentation
+ description: |
+ A probabilistic segmentation.
+
+ This suffix may only be used in derivative datasets.
+sbref:
+ value: sbref
+ display_name: Single-band reference image
+ description: |
+ Single-band reference for one or more multi-band `dwi` images.
+scans:
+ value: scans
+ display_name: Scans file
+ description: |
+ The purpose of this file is to describe timing and other properties of each imaging acquisition
+ sequence (each run file) within one session.
+ Each neural recording file SHOULD be described by exactly one row. Some recordings consist of
+ multiple parts, that span several files, for example through echo-, part-, or split- entities.
+ Such recordings MUST be documented with one row per file.
+ Relative paths to files should be used under a compulsory filename header.
+ If acquisition time is included it should be listed under the acq_time header.
+ Acquisition time refers to when the first data point in each run was acquired.
+ Furthermore, if this header is provided, the acquisition times of all files that belong to a
+ recording MUST be identical.
+ Datetime should be expressed as described in Units.
+ Additional fields can include external behavioral measures relevant to the scan.
+ For example vigilance questionnaire score administered after a resting state scan.
+ All such included additional fields SHOULD be documented in an accompanying _scans.json file
+ that describes these fields in detail (see Tabular files).
+sessions:
+ value: sessions
+ display_name: Sessions file
+ description: |
+ In case of multiple sessions there is an option of adding additional sessions.tsv files
+ describing variables changing between sessions.
+ In such case one file per participant SHOULD be added.
+ These files MUST include a session_id column and describe each session by one and only one row.
+ Column names in sessions.tsv files MUST be different from group level participant key column
+ names in the participants.tsv file.
+stim:
+ value: stim
+ display_name: Continuous recording
+ description: |
+ Continuous measures, such as parameters of a film or audio stimulus.
+uCT:
+ value: uCT
+ display_name: Micro-CT
+ description: |
+ Micro-CT imaging data
diff --git a/bep32v01/ressources/schema/rules/checks/anat.yaml b/bep32v01/ressources/schema/rules/checks/anat.yaml
new file mode 100644
index 00000000..cb8a7092
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/anat.yaml
@@ -0,0 +1,42 @@
+# Rules for anatomical data that are not defined in tables
+---
+# 95
+T1wFileWithTooManyDimensions:
+ issue:
+ code: T1W_FILE_WITH_TOO_MANY_DIMENSIONS
+ message: |
+ _T1w.nii[.gz] files must have exactly three dimensions.
+ level: error
+ selectors:
+ - suffix == 'T1w'
+ - nifti_header != null
+ checks:
+ - nifti_header.dim[0] == 3
+
+PDT2Volumes:
+ issue:
+ code: PDT2_FILE_SHOULD_HAVE_TWO_VOLUMES
+ message: |
+ _PDT2.nii[.gz] files should be 4D images with exactly two volumes.
+ level: warning
+ selectors:
+ - suffix == 'PDT2'
+ - nifti_header != null
+ checks:
+ - nifti_header.dim[0] == 4
+ - nifti_header.dim[4] == 2
+
+PDT2Echos:
+ issue:
+ code: PDT2_ECHOS_SHOULD_MATCH_NIFTI_LENGTH
+ message: |
+ The EchoTime parameter for _PDT2.nii[.gz] files should have one value
+ per volume.
+ level: warning
+ selectors:
+ - suffix == 'PDT2'
+ - sidecar.EchoTime != null
+ - nifti_header.dim[0] == 4
+ checks:
+ - type(sidecar.EchoTime) == 'array'
+ - len(sidecar.EchoTime) == nifti_header.dim[4]
diff --git a/bep32v01/ressources/schema/rules/checks/asl.yaml b/bep32v01/ressources/schema/rules/checks/asl.yaml
new file mode 100644
index 00000000..1b425932
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/asl.yaml
@@ -0,0 +1,318 @@
+# Rules for ASL data that are not defined in tables.
+---
+# 157
+ASLLabelingDurationNiftiLength:
+ issue:
+ code: LABELING_DURATION_LENGTH_NOT_MATCHING_NIFTI
+ message: |
+ The number of values for 'LabelingDuration' for this file does not match the 4th dimension
+ of the NIfTI header.
+ 'LabelingDuration' is the total duration of the labeling pulse train, in seconds,
+ corresponding to the temporal width of the labeling bolus for `(P)CASL`.
+ In case all control-label volumes (or deltam or CBF) have the same `LabelingDuration`, a scalar must be
+ specified.
+ In case the control-label volumes (or deltam or cbf) have a different `LabelingDuration`,
+ an array of numbers must be specified, for which any `m0scan` in the timeseries has a `LabelingDuration` of
+ zero.
+ In case an array of numbers is provided, its length should be equal to the number of volumes specified in
+ the associated `aslcontext.tsv`. Corresponds to DICOM Tag 0018,9258 `ASL Pulse Train Duration`.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - '"LabelingDuration" in sidecar'
+ - type(sidecar.LabelingDuration) == 'array'
+ - type(nifti_header) != "null"
+ checks:
+ - length(sidecar.LabelingDuration) == nifti_header.dim[4]
+
+# 165
+ASLContextConsistent:
+ issue:
+ code: ASLCONTEXT_TSV_NOT_CONSISTENT
+ message: |
+ The number of volumes in the 'aslcontext.tsv' for this file does not match the number of
+ values in the NIfTI header.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(nifti_header) != "null"
+ checks:
+ - nifti_header.dim[4] == associations.aslcontext.n_rows
+
+# 168
+ASLFlipAngleNiftiLength:
+ issue:
+ code: FLIP_ANGLE_NOT_MATCHING_NIFTI
+ message: |
+ The number of values for 'FlipAngle' for this file does not match the 4th dimension of the NIfTI header.
+ 'FlipAngle' is the flip angle (FA) for the acquisition, specified in degrees.
+ Corresponds to: DICOM Tag 0018, 1314 `Flip Angle`.
+ 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 flip 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 flip
+ angle fMRI sequences.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - '"FlipAngle" in sidecar'
+ - type(sidecar.FlipAngle) == 'array'
+ - type(nifti_header) != "null"
+ checks:
+ - length(sidecar.FlipAngle) == nifti_header.dim[4]
+
+# 172
+ASLFlipAngleASLContextLength:
+ issue:
+ code: FLIP_ANGLE_NOT_MATCHING_ASLCONTEXT_TSV
+ message: |
+ The number of values for 'FlipAngle' for this file does not match the number of volumes in the
+ associated 'aslcontext.tsv'.
+ 'FlipAngle' is the flip angle (FA) for the acquisition, specified in degrees.
+ Corresponds to: DICOM Tag 0018, 1314 `Flip Angle`.
+ 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 flip 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 flip angle fMRI sequences.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.FlipAngle) == 'array'
+ checks:
+ - length(sidecar.FlipAngle) == associations.aslcontext.n_rows
+
+# 173
+ASLPostLabelingDelayNiftiLength:
+ issue:
+ code: POST_LABELING_DELAY_NOT_MATCHING_NIFTI
+ message: |
+ The number of values for 'PostLabelingDelay' for this file does not match the 4th dimension of the NIfTI
+ header.
+ 'PostLabelingDelay' is the time, in seconds, after the end of the labeling (for (P)CASL) or middle of the
+ labeling pulse (for PASL) until the middle of the excitation pulse applied to the imaging slab
+ (for 3D acquisition) or first slice (for 2D acquisition).
+ Can be a number (for a single-PLD time series) or an array of numbers (for multi-PLD and Look-Locker).
+ In the latter case, the array of numbers contains the PLD of each volume
+ (that is, each 'control' and 'label')
+ in the acquisition order. Any image within the time-series without a PLD (for example, an 'm0scan') is
+ indicated by a zero.
+ Based on DICOM Tags 0018,9079 Inversion Times and 0018,0082 InversionTime.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.PostLabelingDelay) == 'array'
+ - type(nifti_header) != "null"
+ checks:
+ - length(sidecar.PostLabelingDelay) == nifti_header.dim[4]
+
+# 174
+ASLPostLabelingDelayASLContextLength:
+ issue:
+ code: POST_LABELING_DELAY_NOT_MATCHING_ASLCONTEXT_TSV
+ message: |
+ The number of values for 'PostLabelingDelay' for this file does not match the number of volumes
+ in the associated 'aslcontext.tsv'.
+ 'PostLabelingDelay' is the time, in seconds, after the end of the labeling (for (P)CASL) or
+ middle of the labeling pulse (for PASL) until the middle of the excitation pulse applied to
+ the imaging slab (for 3D acquisition) or first slice (for 2D acquisition).
+ Can be a number (for a single-PLD time series) or an array of numbers (for multi-PLD and Look-Locker).
+ In the latter case, the array of numbers contains the PLD of each volume
+ (that is, each 'control' and 'label')
+ in the acquisition order.
+ Any image within the time-series without a PLD (for example, an 'm0scan') is indicated by a zero.
+ Based on DICOM Tags 0018,9079 Inversion Times and 0018,0082 InversionTime.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.PostLabelingDelay) == 'array'
+ checks:
+ - length(sidecar.PostLabelingDelay) == associations.aslcontext.n_rows
+
+# 175
+ASLLabelingDurationASLContextLength:
+ issue:
+ code: LABELLING_DURATION_NOT_MATCHING_ASLCONTEXT_TSV
+ message: |
+ The number of values for 'LabelingDuration' for this file does not match the number of volumes
+ in the associated 'aslcontext.tsv'.
+ 'LabelingDuration' is the total duration of the labeling pulse train, in seconds,
+ corresponding to the temporal width of the labeling bolus for `(P)CASL`.
+ In case all control-label volumes (or deltam or CBF) have the same `LabelingDuration`,
+ a scalar must be specified.
+ In case the control-label volumes (or deltam or cbf) have a different `LabelingDuration`,
+ an array of numbers must be specified, for which any `m0scan` in the timeseries has a
+ `LabelingDuration` of zero.
+ In case an array of numbers is provided, its length should be equal to the number of volumes
+ specified in the associated `aslcontext.tsv`.
+ Corresponds to DICOM Tag 0018,9258 `ASL Pulse Train Duration`.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.LabelingDuration) == 'array'
+ checks:
+ - length(sidecar.LabelingDuration) == associations.aslcontext.n_rows
+
+# 177
+ASLRepetitionTimePreparationASLContextLength:
+ issue:
+ code: REPETITIONTIMEPREPARATION_NOT_MATCHING_ASLCONTEXT_TSV
+ message: |
+ The number of values of 'RepetitionTimePreparation' for this file does not match the number of
+ volumes in the associated 'aslcontext.tsv'.
+ 'RepetitionTimePreparation' is the interval, in seconds, that it takes a preparation pulse block to
+ re-appear at the beginning of the succeeding (essentially identical) pulse sequence block.
+ The data type number may apply to files from any MRI modality concerned with a single value for this field.
+ 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.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.RepetitionTimePreparation) == 'array'
+ checks:
+ - length(sidecar.RepetitionTimePreparation) == associations.aslcontext.n_rows
+
+# 180
+ASLBackgroundSuppressionNumberPulses:
+ issue:
+ code: BACKGROUND_SUPPRESSION_PULSE_NUMBER_NOT_CONSISTENT
+ message: |
+ The 'BackgroundSuppressionNumberPulses' field is not consistent with the length of
+ 'BackgroundSuppressionPulseTime'.
+ 'BackgroundSuppressionNumberPulses' is the number of background suppression pulses used.
+ Note that this excludes any effect of background suppression pulses applied before the labeling.
+ level: warning
+ selectors:
+ - suffix == "asl"
+ - '"BackgroundSuppressionNumberPulses" in sidecar'
+ - '"BackgroundSuppressionPulseTime" in sidecar'
+ - type(sidecar.BackgroundSuppressionPulseTime) == 'array'
+ checks:
+ - length(sidecar.BackgroundSuppressionPulseTime) == sidecar.BackgroundSuppressionNumberPulses
+
+# 181
+ASLTotalAcquiredVolumesASLContextLength:
+ issue:
+ code: TOTAL_ACQUIRED_VOLUMES_NOT_CONSISTENT
+ message: |
+ The number of values for 'TotalAcquiredVolumes' 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
+ associated 'aslcontext.tsv'.
+ level: warning
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - '"TotalAcquiredVolumes" in sidecar'
+ checks:
+ - aslcontext.n_rows == sidecar.TotalAcquiredVolumes
+
+# 184
+PostLabelingDelayGreater:
+ issue:
+ code: POST_LABELING_DELAY_GREATER
+ message: |
+ 'PostLabelingDelay' is greater than 10. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - suffix == "asl"
+ - sidecar.PostLabelingDelay != null
+ checks:
+ - sidecar.PostLabelingDelay <= 10
+
+# 186
+BolusCutOffDelayTimeGreater:
+ issue:
+ code: BOLUS_CUT_OFF_DELAY_TIME_GREATER
+ message: |
+ 'BolusCutOffDelayTime' is greater than 10. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - sidecar.BolusCutOffDelayTime != null
+ checks:
+ - sidecar.BolusCutOffDelayTime <= 10
+
+# 187
+LabelingDurationGreater:
+ issue:
+ code: LABELING_DURATION_GREATER
+ message: |
+ 'LabelingDuration' is greater than 10. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - sidecar.LabelingDuration != null
+ checks:
+ - sidecar.LabelingDuration <= 10
+
+# 196
+ASLEchoTimeASLContextLength:
+ issue:
+ code: ECHO_TIME_NOT_CONSISTENT
+ message: |
+ The number of values for 'EchoTime' for this file does not match number of volumes in the
+ associated 'aslcontext.tsv'.
+ 'EchoTime' is the echo time (TE) for the acquisition, specified in seconds.
+ level: warning
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(sidecar.EchoTime) == 'array'
+ checks:
+ - length(sidecar.EchoTime) == associations.aslcontext.n_rows
+
+## 197 ECHO_TIME_ELEMENTS duplicates 165 and 196 (length(sidecar.EchoTime) == nifti_header.dim[4])
+
+# 198
+ASLM0TypeAbsentScan:
+ issue:
+ code: M0Type_SET_INCORRECTLY_TO_ABSENT
+ message: |
+ You defined M0Type as 'absent' while including a separate 'm0scan.nii[.gz]' and
+ 'm0scan.json', or defining the 'M0Estimate' field.
+ This is not allowed, please check that this field are filled correctly.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - type(associations.m0scan) != "null"
+ - '"M0Type" in sidecar'
+ checks:
+ - sidecar.M0Type != "absent"
+
+# 199
+ASLM0TypeAbsentASLContext:
+ issue:
+ code: M0Type_SET_INCORRECTLY_TO_ABSENT_IN_ASLCONTEXT
+ message: |
+ You defined M0Type as 'absent' while including an m0scan volume within the associated
+ 'aslcontext.tsv'.
+ This is not allowed, please check that this field are filled correctly.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - intersects(associations.aslcontext.volume_type, ["m0scan"])
+ - '"M0Type" in sidecar'
+ checks:
+ - sidecar.M0Type != "absent"
+
+# 202
+ASLM0TypeIncorrect:
+ issue:
+ code: M0Type_SET_INCORRECTLY
+ message: |
+ M0Type was not defined correctly.
+ If 'M0Type' is equal to 'separate', the dataset should include an associated
+ 'm0scan.nii[.gz]' and 'm0scan.json' file.
+ level: error
+ selectors:
+ - suffix == "asl"
+ - type(associations.aslcontext) != "null"
+ - sidecar.M0Type == "separate"
+ checks:
+ - type(associations.m0scan) != "null"
diff --git a/bep32v01/ressources/schema/rules/checks/common_derivatives.yaml b/bep32v01/ressources/schema/rules/checks/common_derivatives.yaml
new file mode 100644
index 00000000..723ddf0e
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/common_derivatives.yaml
@@ -0,0 +1,18 @@
+---
+ResInSidecar:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - intersects([modality], ["mri", "pet"])
+ - match(extension, '^\.nii(\.gz)?$')
+ - type(sidecar.Resolution) == "object"
+ checks:
+ - entities.resolution in sidecar.Resolution
+
+DenInSidecar:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - intersects([modality], ["mri", "pet"])
+ - match(extension, '^\.nii(\.gz)?$')
+ - type(sidecar.Density) == "object"
+ checks:
+ - entities.density in sidecar.Density
diff --git a/bep32v01/ressources/schema/rules/checks/dataset.yaml b/bep32v01/ressources/schema/rules/checks/dataset.yaml
new file mode 100644
index 00000000..b0f0aba6
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/dataset.yaml
@@ -0,0 +1,92 @@
+# Rules for datasets
+# For now use `path == dataset_description.json` to ensure something only happens once
+---
+# 45
+SubjectFolders:
+ issue:
+ code: SUBJECT_FOLDERS
+ message: |
+ There are no subject directories (labeled "sub-*") in the root of this dataset.
+ level: error
+ selectors:
+ - path == 'dataset_description.json'
+ checks:
+ - length(dataset.subjects.sub_dirs) > 0
+
+# 49
+ParticipantIDMismtach:
+ issue:
+ code: PARTICIPANT_ID_MISMATCH
+ message: |
+ Participant labels found in this dataset did not match the values in participant_id column
+ found in the participants.tsv file.
+ level: error
+ selectors:
+ - path == 'participants.tsv'
+ checks:
+ - sorted(columns.participant_label) == sorted(dataset.subjects.sub_dirs)
+
+# 51
+PhenotypeSubjectsMissing:
+ issue:
+ code: PHENOTYPE_SUBJECTS_MISSING
+ message: |
+ A phenotype/ .tsv file lists subjects that were not found in the dataset.
+ level: error
+ selectors:
+ - path == 'dataset_description.json'
+ checks:
+ - sorted(dataset.subjects.phenotype) == sorted(dataset.subjects.sub_dirs)
+
+# 214
+SamplesTSVMissing:
+ issue:
+ code: SAMPLES_TSV_MISSING
+ message: |
+ The compulsory file '/samples.tsv' is missing.
+ See 'Modality agnostic files' section of the BIDS specification.
+ level: error
+ selectors:
+ - path == 'dataset_description.json'
+ - '"micr" in dataset.modalities'
+ checks:
+ - "'samples.tsv' in dataset.files"
+
+UnknownVersion:
+ issue:
+ code: UNKNOWN_BIDS_VERSION
+ message: |
+ The BIDSVersion field of 'dataset_description.json' does not match a known release.
+ The BIDS Schema used for validation may be out of date.
+ level: warning
+ selectors:
+ - path == 'dataset_description.json'
+ checks:
+ - intersects([json.BIDSVersion], schema.meta.versions)
+
+SingleSourceAuthors:
+ issue:
+ code: AUTHORS_AND_CITATION_FILE_MUTUALLY_EXCLUSIVE
+ level: error
+ message: |
+ 'CITATION.cff' file found. The "Authors" field of 'dataset_description.json'
+ must be removed to avoid inconsistency.
+ selectors:
+ - path == 'CITATION.cff'
+ checks:
+ - '!("Authors" in dataset.dataset_description)'
+
+SingleSourceCitationFields:
+ issue:
+ code: SINGLE_SOURCE_CITATION_FIELDS
+ level: warning
+ message: |
+ CITATION.cff file found.
+ The "HowToAckowledge", "License", and "ReferencesAndLinks" fields of
+ 'dataset_description.json' should be removed to avoid inconsistency.
+ selectors:
+ - path == 'CITATION.cff'
+ checks:
+ - '!("HowToAcknowledge" in dataset.dataset_description)'
+ - '!("License" in dataset.dataset_description)'
+ - '!("ReferencesAndLinks" in dataset.dataset_description)'
diff --git a/bep32v01/ressources/schema/rules/checks/dwi.yaml b/bep32v01/ressources/schema/rules/checks/dwi.yaml
new file mode 100644
index 00000000..d0b71d9a
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/dwi.yaml
@@ -0,0 +1,70 @@
+# Rules for DWI data that are not defined in tables.
+---
+# 29
+DWIVolumeCount:
+ issue:
+ code: VOLUME_COUNT_MISMATCH
+ message: |
+ The number of volumes in this scan does not match the number of volumes in the
+ associated '.bvec' and '.bval' files.
+ level: error
+ selectors:
+ - suffix == "dwi"
+ - '"bval" in associations'
+ - '"bvec" in associations'
+ - type(nifti_header) != "null"
+ checks:
+ - associations.bval.n_cols == nifti_header.dim[4]
+ - associations.bvec.n_cols == nifti_header.dim[4]
+
+# 30
+DWIBvalRows:
+ issue:
+ code: BVAL_MULTIPLE_ROWS
+ message: |
+ '.bval' files should contain exactly one row of values.
+ level: error
+ selectors:
+ - suffix == "dwi"
+ - '"bval" in associations'
+ checks:
+ - associations.bval.n_rows == 1
+
+# 31
+DWIBvecRows:
+ issue:
+ code: BVEC_NUMBER_ROWS
+ message: |
+ '.bvec' files should contain exactly three rows of values.
+ level: error
+ selectors:
+ - suffix == "dwi"
+ - '"bvec" in associations'
+ checks:
+ - associations.bvec.n_rows == 3
+
+# 32
+DWIMissingBvec:
+ issue:
+ code: DWI_MISSING_BVEC
+ message: |
+ DWI scans must have a corresponding '.bvec' file.
+ level: error
+ selectors:
+ - suffix == "dwi"
+ - match(extension, '^\.nii(\.gz)?$')
+ checks:
+ - '"bvec" in associations'
+
+# 33
+DWIMissingBval:
+ issue:
+ code: DWI_MISSING_BVAL
+ message: |
+ DWI scans must have a corresponding '.bval' file.
+ level: error
+ selectors:
+ - suffix == "dwi"
+ - match(extension, '^\.nii(\.gz)?$')
+ checks:
+ - '"bval" in associations'
diff --git a/bep32v01/ressources/schema/rules/checks/events.yaml b/bep32v01/ressources/schema/rules/checks/events.yaml
new file mode 100644
index 00000000..cd8fd414
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/events.yaml
@@ -0,0 +1,29 @@
+# Rules for events data that are not defined in tables.
+---
+# 25
+EventsMissing:
+ issue:
+ code: EVENTS_TSV_MISSING
+ message: |
+ Task scans should have a corresponding 'events.tsv' file.
+ If this is a resting state scan you can ignore this warning or rename the task to include the word "rest".
+ level: warning # could be an error with the proper selectors, I think
+ selectors:
+ - dataset.dataset_description.DatasetType == "raw"
+ - '"task" in entities'
+ - '!match(entities.task, "rest")'
+ - suffix != "events"
+ checks:
+ - '"events" in associations'
+
+StimulusFileMissing:
+ issue:
+ code: STIMULUS_FILE_MISSING
+ message: |
+ A stimulus file was declared but not found in the dataset.
+ level: error
+ selectors:
+ - suffix == "events"
+ - columns.stim_file != null
+ checks:
+ - exists(columns.stim_file, "stimuli") == length(columns.stim_file) - count(columns.stim_file, "n/a")
diff --git a/bep32v01/ressources/schema/rules/checks/fmap.yaml b/bep32v01/ressources/schema/rules/checks/fmap.yaml
new file mode 100644
index 00000000..af042351
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/fmap.yaml
@@ -0,0 +1,51 @@
+# Rules for fieldmap data that are not defined in tables.
+---
+# 83
+EchoTime12DifferenceUnreasonable:
+ issue:
+ code: ECHOTIME1_2_DIFFERENCE_UNREASONABLE
+ message: |
+ The value of (EchoTime2 - EchoTime1) should be within the range of 0.0001 - 0.01.
+ level: error
+ selectors:
+ - suffix == "phasediff"
+ checks:
+ - sidecar.EchoTime2 - sidecar.EchoTime1 >= 0.0001
+ - sidecar.EchoTime2 - sidecar.EchoTime1 <= 0.01
+
+# 91
+FmapFieldmapWithoutMagnitude:
+ issue:
+ code: FIELDMAP_WITHOUT_MAGNITUDE_FILE
+ message: |
+ 'fieldmap.nii[.gz]' file does not have an associated 'magnitude.nii[.gz]' file.
+ level: error
+ selectors:
+ - suffix == "fieldmap"
+ checks:
+ - '"magnitude" in associations'
+
+# 92
+FmapPhasediffWithoutMagnitude:
+ issue:
+ code: MISSING_MAGNITUDE1_FILE
+ message: |
+ 'phasediff.nii[.gz]' file does not have an associated 'magnitude1.nii[.gz]' file.
+ level: warning
+ selectors:
+ - suffix == "phasediff"
+ checks:
+ - '"magnitude1" in associations'
+
+# 94
+MagnitudeFileWithTooManyDimensions:
+ issue:
+ code: MAGNITUDE_FILE_WITH_TOO_MANY_DIMENSIONS
+ message: |
+ 'magnitude1.nii[.gz]' and 'magnitude2.nii[.gz]' files must have exactly three dimensions.
+ level: error
+ selectors:
+ - intersects([suffix], ['magnitude1', 'magnitude2'])
+ - nifti_header != null
+ checks:
+ - nifti_header.dim[0] == 3
diff --git a/bep32v01/ressources/schema/rules/checks/func.yaml b/bep32v01/ressources/schema/rules/checks/func.yaml
new file mode 100644
index 00000000..cce740a1
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/func.yaml
@@ -0,0 +1,129 @@
+# Rules for functional data that are not defined in tables.
+---
+PhaseSuffixDeprecated:
+ issue:
+ code: PHASE_SUFFIX_DEPRECATED
+ message: |
+ DEPRECATED. Phase information associated with magnitude information stored in BOLD contrast.
+ This suffix should be replaced by the 'part-phase' entity in conjunction with the 'bold' suffix.
+ For backwards compatibility, 'phase' is considered equivalent to 'part-phase_bold'.
+ When the 'phase' suffix is not used, each file shares the same name with the exception of the
+ 'part-' or 'part-' key/value.
+ level: warning
+ selectors:
+ - datatype == "func"
+ checks:
+ - suffix != "phase"
+
+# 2
+RepetitionTimeGreaterThan:
+ issue:
+ code: REPETITION_TIME_GREATER_THAN
+ message: |
+ 'RepetitionTime' is greater than 100. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - suffix == "bold"
+ - type(sidecar.RepetitionTime) != "null"
+ checks:
+ - sidecar.RepetitionTime <= 100
+
+# 12
+RepetitionTimeMismatch:
+ issue:
+ code: REPETITION_TIME_MISMATCH
+ message: |
+ Repetition time did not match between the scan's header and the associated JSON metadata file.
+ level: error
+ selectors:
+ - suffix == "bold"
+ - type(sidecar.RepetitionTime) != "null"
+ - type(nifti_header) != "null"
+ checks:
+ - sidecar.RepetitionTime == nifti_header.pixdim[4]
+
+# 54
+BoldNot4d:
+ issue:
+ code: BOLD_NOT_4D
+ message: |
+ BOLD scans must be 4 dimensional.
+ level: error
+ selectors:
+ - suffix == "bold"
+ - type(nifti_header) != "null"
+ checks:
+ - nifti_header.dim[0] == 4
+
+# 66
+SliceTimingGreaterThanRepetitionTime:
+ issue:
+ code: SLICETIMING_VALUES_GREATER_THAN_REPETITION_TIME
+ message: |
+ 'SliceTiming' contains invalid value(s) greater than 'RepetitionTime'.
+ 'SliceTiming' values should be in seconds, not milliseconds (common mistake).
+ level: error
+ selectors:
+ - suffix == "bold"
+ - type(sidecar.SliceTiming) != "null"
+ - type(sidecar.RepetitionTime) != "null"
+ checks:
+ - max(sidecar.SliceTiming) <= sidecar.RepetitionTime
+
+### The following rules implement the functional imaging acquisition timing rules
+### For the sake of informative errors, they are implemented in more rules than
+### strictly necessary
+### The selectors/checks are implemented with the least likely case in the selector
+### for efficiency.
+
+# 178
+VolumeTimingRepetitionTimeMutex:
+ issue:
+ code: VOLUME_TIMING_AND_REPETITION_TIME_MUTUALLY_EXCLUSIVE
+ message: |
+ The fields 'VolumeTiming' and 'RepetitionTime' for this file are mutually exclusive.
+ Choose 'RepetitionTime' when the same repetition time is used for all volumes,
+ or 'VolumeTiming' when variable times are used.
+ level: error
+ selectors:
+ - type(sidecar.VolumeTiming) != "null"
+ checks:
+ - type(sidecar.RepetitionTime) == "null"
+
+RepetitionTimeAcquisitionDurationMutex:
+ issue:
+ code: REPETITION_TIME_AND_ACQUISITION_DURATION_MUTUALLY_EXCLUSIVE
+ message: |
+ The fields 'RepetitionTime' and 'AcquisitionDuration' for this file are mutually exclusive.
+ To specify acquisition duration, use 'SliceTiming' or 'DelayTime'
+ (RepetitionTime - AcquisitionDuration).
+ level: error
+ selectors:
+ - type(sidecar.AcquistionDuration) != "null"
+ checks:
+ - type(sidecar.RepetitionTime) == "null"
+
+VolumeTimingDelayTimeMutex:
+ issue:
+ code: VOLUME_TIMING_AND_DELAY_TIME_MUTUALLY_EXCLUSIVE
+ message: |
+ The fields 'VolumeTiming' and 'DelayTime' for this file are mutually exclusive.
+ To specify acquisition duration, use 'AcquisitionDuration' or 'SliceTiming'.
+ level: error
+ selectors:
+ - type(sidecar.VolumeTiming) != "null"
+ checks:
+ - type(sidecar.DelayTime) == "null"
+
+SliceTimingAcquisitionDurationMutex:
+ issue:
+ code: SLICE_TIMING_AND_DURATION_MUTUALLY_EXCLUSIVE
+ message: |
+ 'SliceTiming' is defined for this file.
+ Neither 'DelayTime' nor 'AcquisitionDuration' may be defined in addition.
+ level: error
+ selectors:
+ - type(sidecar.SliceTiming) != "null"
+ checks:
+ - type(sidecar.AcquisitionDuration) == "null"
+ - type(sidecar.DelayTime) == "null"
diff --git a/bep32v01/ressources/schema/rules/checks/general.yaml b/bep32v01/ressources/schema/rules/checks/general.yaml
new file mode 100644
index 00000000..b0505250
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/general.yaml
@@ -0,0 +1,25 @@
+---
+# BIDS Validator Original Issue Code #74
+# Was DUPLICATE_NIFTI_FILES, but applies generally
+DuplicateFiles:
+ issue:
+ code: DUPLICATE_FILES
+ message: |
+ File exists with and without `.gz` extension.
+ level: error
+ selectors:
+ - match(extension, '\.gz$')
+ checks:
+ - exists(substr(path, 0, length(path) - 3), "dataset") == 0
+
+ReadmeFileSmall:
+ issue:
+ code: README_FILE_SMALL
+ message: |
+ The recommended file '/README' is very small.
+ Please consider expanding it with additional information about the dataset.
+ level: warning
+ selectors:
+ - match(path, '^README')
+ checks:
+ - size > 150
diff --git a/bep32v01/ressources/schema/rules/checks/hints.yaml b/bep32v01/ressources/schema/rules/checks/hints.yaml
new file mode 100644
index 00000000..7c733d8d
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/hints.yaml
@@ -0,0 +1,52 @@
+---
+# This file is for warnings that are not specified by BIDS, but are frequently indicative
+# of an issue with a dataset.
+
+### Dataset level
+
+# 102
+TooFewAuthors:
+ issue:
+ code: TOO_FEW_AUTHORS
+ message: |
+ The 'Authors' field of 'dataset_description.json' should contain an array of values -
+ with one author per value.
+ This was triggered based on the presence of only one author field.
+ Please ignore if all contributors are already properly listed.
+ level: warning
+ selectors:
+ - path == '/dataset_description.json'
+ checks:
+ - length(json.Authors) > 1
+
+### Functional files
+
+# 85
+SuspiciouslyLongBOLDDesign:
+ issue:
+ code: SUSPICIOUSLY_LONG_EVENT_DESIGN
+ message: |
+ The onset of the last event is after the total duration of the corresponding scan.
+ This design is suspiciously long.
+ level: warning
+ selectors:
+ - suffix == "bold"
+ - associations.events != null
+ - type(nifti_header) != "null"
+ checks:
+ - max(associations.events.onset) < nifti_header.pixdim[4] * nifti_header.dim[4]
+
+# 86
+SuspiciouslyShortBOLDDesign:
+ issue:
+ code: SUSPICIOUSLY_SHORT_EVENT_DESIGN
+ message: |
+ The onset of the last event is less than half the total duration of the corresponding scan.
+ This design is suspiciously short.
+ level: warning
+ selectors:
+ - suffix == "bold"
+ - associations.events != null
+ - type(nifti_header) != "null"
+ checks:
+ - max(associations.events.onset) > nifti_header.pixdim[4] * nifti_header.dim[4] / 2
diff --git a/bep32v01/ressources/schema/rules/checks/micr.yaml b/bep32v01/ressources/schema/rules/checks/micr.yaml
new file mode 100644
index 00000000..bf2f4c55
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/micr.yaml
@@ -0,0 +1,38 @@
+---
+# 221
+PixelSizeInconsistent:
+ issue:
+ code: PIXEL_SIZE_INCONSISTENT
+ message: |
+ 'PixelSize' need to be consistent with the 'PhysicalSizeX', 'PhysicalSizeY' and 'PhysicalSizeZ'
+ OME metadata fields.
+ level: error
+ selectors:
+ - ome != null
+ - sidecar.PixelSize != null
+ - sidecar.PixelSizeUnit != null
+ checks:
+ - |
+ ome.PhysicalSizeX * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeXUnit))
+ == sidecar.PixelSize[0] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
+ - |
+ ome.PhysicalSizeY * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeYUnit))
+ == sidecar.PixelSize[1] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
+ - |
+ ome.PhysicalSizeZ * 10 ** (-3 * index(["mm", "um", "nm"], ome.PhysicalSizeZUnit))
+ == sidecar.PixelSize[2] * 10 ** (-3 * index(["mm", "um", "nm"], sidecar.PixelSizeUnit))
+
+# 227
+InconsistentTiffExtension:
+ issue:
+ code: INCONSISTENT_TIFF_EXTENSION
+ message: |
+ Inconsistent TIFF file type and extension
+ level: error
+ selectors:
+ - tiff != null
+ - intersects([extension], ['.ome.tif', '.ome.btf'])
+ checks:
+ - tiff.version == 42 || tiff.version == 43
+ - (extension == '.ome.tif') == (tiff.version == 42)
+ - (extension == '.ome.btf') == (tiff.version == 43)
diff --git a/bep32v01/ressources/schema/rules/checks/mri.yaml b/bep32v01/ressources/schema/rules/checks/mri.yaml
new file mode 100644
index 00000000..8837f5fa
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/mri.yaml
@@ -0,0 +1,129 @@
+---
+PhasePartUnits:
+ issue:
+ code: PHASE_UNITS
+ message: |
+ Phase images (with the `part-phase` entity) must have units "rad" or "arbitrary".
+ level: error
+ selectors:
+ - modality == "mri"
+ - entities.part == "phase"
+ - '"Units" in sidecar'
+ checks:
+ - intersects([sidecar.Units], ["rad", "arbitrary"])
+
+# 3
+EchoTimeGreaterThan:
+ issue:
+ code: ECHO_TIME_GREATER_THAN
+ message: |
+ 'EchoTime' is greater than 1. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - modality == "mri"
+ - sidecar.EchoTime
+ checks:
+ - sidecar.EchoTime <= 1
+
+# 5
+TotalReadoutTimeGreaterThan:
+ issue:
+ code: TOTAL_READOUT_TIME_GREATER_THAN
+ message: |
+ 'TotalReadoutTime' is greater than 10. Are you sure it's expressed in seconds?
+ level: warning
+ selectors:
+ - modality == "mri"
+ - sidecar.TotalReadoutTime
+ checks:
+ - sidecar.TotalReadoutTime <= 10
+
+# 76
+EffectiveEchoSpacingTooLarge:
+ issue:
+ code: EFFECTIVEECHOSPACING_TOO_LARGE
+ message: |
+ Abnormally high value of 'EffectiveEchoSpacing'.
+ level: error
+ selectors:
+ - modality == "mri"
+ - type(sidecar.RepetitionTime) != "null"
+ - type(sidecar.EffectiveEchoSpacing) != "null"
+ - type(sidecar.PhaseEncodingDirection) != "null"
+ - type(nifti_header) != "null"
+ checks:
+ - |
+ sidecar.RepetitionTime >= (
+ sidecar.EffectiveEchoSpacing
+ * nifti_header.dim[index(["i", "j", "k"], sidecar.PhaseEncodingDirection[0])]
+ )
+
+# 87
+SliceTimingElements:
+ issue:
+ code: SLICETIMING_ELEMENTS
+ message: |
+ The number of elements in the 'SliceTiming' array should match the 'k'
+ dimension of the corresponding NIfTI volume.
+ level: warning
+ selectors:
+ - modality == "mri"
+ - type(sidecar.SliceTiming) != "null"
+ - type(nifti_header) != "null"
+ checks:
+ - length(sidecar.SliceTiming) == nifti_header.dim[3]
+
+# 93
+EESGreaterThanTRT:
+ issue:
+ code: EFFECTIVEECHOSPACING_LARGER_THAN_TOTALREADOUTTIME
+ message: |
+ 'EffectiveEchoSpacing' should always be smaller than 'TotalReadoutTime'.
+ level: error
+ selectors:
+ - modality == "mri"
+ - sidecar.EffectiveEchoSpacing != null
+ - sidecar.TotalReadoutTime != null
+ checks:
+ - sidecar.EffectiveEchoSpacing < sidecar.TotalReadoutTime
+
+# 188
+VolumeTimingNotMonotonicallyIncreasing:
+ issue:
+ code: VOLUME_TIMING_NOT_MONOTONICALLY_INCREASING
+ message: |
+ 'VolumeTiming' is not monotonically increasing.
+ level: error
+ selectors:
+ - modality == "mri"
+ - sidecar.VolumeTiming != null
+ checks:
+ - sorted(sidecar.VolumeTiming) == sidecar.VolumeTiming
+
+# 192
+BolusCutOffDelayTimeNotMonotonicallyIncreasing:
+ issue:
+ code: BOLUS_CUT_OFF_DELAY_TIME_NOT_MONOTONICALLY_INCREASING
+ message: |
+ 'BolusCutOffDelayTime' is not monotonically increasing.
+ level: error
+ selectors:
+ - modality == "mri"
+ - sidecar.BolusCutoffDelayTime != null
+ checks:
+ - sorted(sidecar.BolusCutoffDelayTime) == sidecar.BolusCutoffDelayTime
+
+# 201
+RepetitionTimePreparationNotConsistent:
+ issue:
+ code: REPETITIONTIME_PREPARATION_NOT_CONSISTENT
+ message: |
+ The number of values for 'RepetitionTimePreparation' for this file does
+ not match the 4th dimension of the NIfTI header.
+ level: error
+ selectors:
+ - modality == "mri"
+ - type(sidecar.RepetitionTimePreparation) == "array"
+ - type(nifti_header) != "null"
+ checks:
+ - length(sidecar.RepetitionTimePreparation) == nifti_header.dim[4]
diff --git a/bep32v01/ressources/schema/rules/checks/nifti.yaml b/bep32v01/ressources/schema/rules/checks/nifti.yaml
new file mode 100644
index 00000000..eb160f20
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/nifti.yaml
@@ -0,0 +1,51 @@
+---
+# 40
+NiftiDimension:
+ issue:
+ code: NIFTI_DIMENSION
+ message: |
+ NIfTI file's header field for dimension information is blank or too short.
+ level: warning
+ selectors:
+ - type(nifti_header) != "null"
+ checks:
+ - length(nifti_header.shape) > 0
+ - min(nifti_header.shape) > 0
+
+# 41
+NiftiUnit:
+ issue:
+ code: NIFTI_UNIT
+ message: |
+ NIfTI file's header field for unit information for x, y, z, and t dimensions is empty or too short.
+ level: warning
+ selectors:
+ - type(nifti_header) != "null"
+ checks:
+ - nifti_header.xyzt_units.xyz != 'unknown'
+ - nifti_header.dim[0] < 4 || nifti_header.xyzt_units.t != 'unknown'
+
+# 42
+NiftiPixdim:
+ issue:
+ code: NIFTI_PIXDIM
+ message: |
+ NIfTI file's header field for pixel dimension information is empty or too short.
+ level: warning
+ selectors:
+ - type(nifti_header) != "null"
+ checks:
+ - min(nifti_header.voxel_sizes) > 0
+
+# 60
+XformCodes0:
+ issue:
+ code: SFORM_AND_QFORM_IN_IMAGE_HEADER_ARE_ZERO
+ message: |
+ sform_code and qform_code in the image header are 0.
+ The image/file will be considered invalid or assumed to be in LAS orientation.
+ level: warning
+ selectors:
+ - nifti_header != null
+ checks:
+ - nifti_header.qform_code != 0 || nifti_header.sform_code != 0
diff --git a/bep32v01/ressources/schema/rules/checks/nirs.yaml b/bep32v01/ressources/schema/rules/checks/nirs.yaml
new file mode 100644
index 00000000..3ec07ce1
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/nirs.yaml
@@ -0,0 +1,105 @@
+---
+NASamplingFreq:
+ selectors:
+ - suffix == "nirs"
+ - samplingFrequency == "n/a"
+ checks:
+ - associations.channels.sampling_frequency != null
+
+NIRSChannelCount:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ checks:
+ - |
+ sidecar.NIRSChannelCount
+ == count(associations.channels.type, "NIRSCWAMPLITUDE")
+ + count(associations.channels.type, "NIRSCWFLUORESCENSEAMPLITUDE")
+ + count(associations.channels.type, "NIRSCWOPTICALDENSITY")
+ + count(associations.channels.type, "NIRSCWHBO")
+ + count(associations.channels.type, "NIRSCWHBR")
+ + count(associations.channels.type, "NIRSCWMUA")
+
+ACCELChannelCountReq:
+ selectors:
+ - suffix == "nirs"
+ - count(associations.channels.type, "ACCEL") > 0
+ checks:
+ - sidecar.ACCELChannelCount == count(associations.channels.type, "ACCEL")
+
+GYROChannelCountReq:
+ selectors:
+ - suffix == "nirs"
+ - count(associations.channels.type, "GYRO") > 0
+ checks:
+ - sidecar.GYROChannelCount == count(associations.channels.type, "GYRO")
+
+MAGNChannelCountReq:
+ selectors:
+ - suffix == "nirs"
+ - count(associations.channels.type, "MAGN") > 0
+ checks:
+ - sidecar.MAGNChannelCount == count(associations.channels.type, "MAGN")
+
+ShortChannelCountReq:
+ selectors:
+ - suffix == "nirs"
+ - '"ShortChannelCount" in sidecar'
+ checks:
+ - sidecar.ShortChannelCount == count(associations.channels.short_channel, "true")
+
+Component:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "channels"
+ - extension == ".tsv"
+ - intersects(columns.type, ["ACCEL", "GYRO", "MAGN"])
+ checks:
+ - columns.component != null
+
+RecommendedChannels:
+ issue:
+ code: NIRS_RECOMMENDED_CHANNELS
+ message: |
+ NIRS files SHOULD have an associated channels.tsv file.
+ level: warning
+ selectors:
+ - suffix == "nirs"
+ - extension == ".snirf"
+ checks:
+ - associations.channels != null
+
+RequiredTemplateX:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "optodes"
+ - extension == ".tsv"
+ - intersects(columns.x, ["n/a"])
+ checks:
+ - columns.template_x != null
+
+RequiredTemplateY:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "optodes"
+ - extension == ".tsv"
+ - intersects(columns.y, ["n/a"])
+ checks:
+ - columns.template_y != null
+
+RequiredTemplateZ:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "optodes"
+ - extension == ".tsv"
+ - intersects(columns.z, ["n/a"])
+ checks:
+ - columns.template_z != null
+
+RequiredCoordsystem:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "optodes"
+ - extension == ".tsv"
+ checks:
+ - associations.coordsystem != null
diff --git a/bep32v01/ressources/schema/rules/checks/privacy.yaml b/bep32v01/ressources/schema/rules/checks/privacy.yaml
new file mode 100644
index 00000000..c9e2ecf0
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/privacy.yaml
@@ -0,0 +1,29 @@
+---
+GzipHeaderFields:
+ issue:
+ code: GZIP_HEADER_DATA
+ 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.
+ level: warning
+ selectors:
+ - match(extension, ".gz$")
+ - gzip != null
+ checks:
+ - gzip.timestamp == 0
+ - gzip.filename == ""
+ - gzip.comment == ""
+
+CheckAge89:
+ issue:
+ code: AGE_89
+ message: |
+ As per section 164.514(C) of "The De-identification Standard" under HIPAA guidelines,
+ participants with age 89 or higher should be tagged as 89+. More information can be found at
+ https://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification/#standard.
+ level: warning
+ selectors:
+ - path == 'participants.tsv'
+ - columns.age != null
+ checks:
+ - max(columns.age) < 89
diff --git a/bep32v01/ressources/schema/rules/checks/references.yaml b/bep32v01/ressources/schema/rules/checks/references.yaml
new file mode 100644
index 00000000..cbbc8f54
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/checks/references.yaml
@@ -0,0 +1,43 @@
+---
+SubjectRelativeIntendedFor:
+ selectors:
+ - datatype != "ieeg"
+ - type(sidecar.IntendedFor) != "null"
+ checks:
+ - exists(sidecar.IntendedFor, "bids-uri") || exists(sidecar.IntendedFor, "subject")
+
+DatasetRelativeIntendedFor:
+ selectors:
+ - datatype == "ieeg"
+ - type(sidecar.IntendedFor) != "null"
+ checks:
+ - exists(sidecar.IntendedFor, "bids-uri") || exists(sidecar.IntendedFor, "dataset")
+
+AssociatedEmptyRoom:
+ selectors:
+ - suffix == "meg"
+ - type(sidecar.AssociatedEmptyRoom) != "null"
+ checks:
+ - exists(sidecar.AssociatedEmptyRoom, "bids-uri") || exists(sidecar.AssociatedEmptyRoom, "dataset")
+
+Stimuli:
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+ - type(columns.stim_file) != "null"
+ checks:
+ - exists(columns.stim_file, "stimuli")
+
+Sources:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivatives"
+ - type(sidecar.Sources) != "null"
+ checks:
+ - exists(sidecar.Sources, "bids-uri") || exists(sidecar.Sources, "dataset")
+
+SpatialReferences:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivatives"
+ - type(sidecar.SpatialReference.URI) != "null"
+ checks:
+ - exists(sidecar.SpatialReference.URI, "bids-uri") || exists(sidecar.SpatialReference.URI, "dataset")
diff --git a/bep32v01/ressources/schema/rules/common_principles.yaml b/bep32v01/ressources/schema/rules/common_principles.yaml
new file mode 100644
index 00000000..8fac3a81
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/common_principles.yaml
@@ -0,0 +1,18 @@
+---
+# This file simply defines the order in which the Common Principles are presented in the specification.
+# The actual term definitions appear in `objects/common_principles.yaml`.
+- dataset
+- modality
+- data_type
+- subject
+- session
+- sample
+- data_acquisition
+- task
+- event
+- run
+- index
+- label
+- suffix
+- extension
+- deprecated
diff --git a/bep32v01/ressources/schema/rules/dataset_metadata.yaml b/bep32v01/ressources/schema/rules/dataset_metadata.yaml
new file mode 100644
index 00000000..d0a92081
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/dataset_metadata.yaml
@@ -0,0 +1,50 @@
+---
+dataset_description:
+ selectors:
+ - path == "/dataset_description.json"
+ fields:
+ Name: required
+ BIDSVersion: required
+ DatasetType: recommended
+ License: recommended
+ Authors:
+ level: recommended
+ issue:
+ code: NO_AUTHORS
+ message: |
+ The Authors field of dataset_description.json should contain an array of fields -
+ with one author per field. This was triggered because there are no authors, which
+ will make DOI registration from dataset metadata impossible.
+ Acknowledgements: optional
+ HowToAcknowledge: optional
+ Funding: optional
+ EthicsApprovals: optional
+ ReferencesAndLinks: optional
+ DatasetDOI: optional
+ GeneratedBy: recommended
+ SourceDatasets: recommended
+
+derivative_description:
+ selectors:
+ - path == "/dataset_description.json"
+ - json.DatasetType == "derivative"
+ fields:
+ GeneratedBy: required
+
+dataset_description_with_genetics:
+ selectors:
+ - path == "/dataset_description.json"
+ - intersects(dataset.files, ["/genetic_info.json"])
+ fields:
+ Genetics: required
+
+genetic_info:
+ selectors:
+ - path == "/genetic_info.json"
+ fields:
+ GeneticLevel: required
+ SampleOrigin: required
+ AnalyticalApproach: optional
+ TissueOrigin: optional
+ BrainLocation: optional
+ CellType: optional
diff --git a/bep32v01/ressources/schema/rules/directories.yaml b/bep32v01/ressources/schema/rules/directories.yaml
new file mode 100644
index 00000000..db3db194
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/directories.yaml
@@ -0,0 +1,112 @@
+---
+# This file defines layouts of directories.
+#
+# A layout defines a collection of directory specifiers.
+# Each specifier has a naming convention, requirement level, opacity, and subdirectories.
+#
+# Naming conventions may take three forms:
+# - name: The directory name has exactly this value.
+# - entity: The directory name takes the form of {key}-{value} for the specified entity
+# - value: The directory name takes the form of {value} for the specified term (like datatype)
+#
+# The requirement level indicates whether a directory MUST (required) or MAY (optional) exist.
+#
+# The opaque field indicates whether the contents of the directory are specified.
+#
+# The special "root" specifier describes the root of the dataset and only defines subdirectories.
+# No naming convention applies, and the requirement level and opacity would be superfluous.
+#
+raw:
+ root:
+ subdirs:
+ - code
+ - derivatives
+ - phenotype
+ - sourcedata
+ - stimuli
+ - subject
+ code:
+ name: code
+ level: optional
+ opaque: true
+ derivatives:
+ name: derivatives
+ level: optional
+ opaque: true
+ phenotype:
+ name: phenotype
+ level: optional
+ opaque: false
+ sourcedata:
+ name: sourcedata
+ level: optional
+ opaque: true
+ stimuli:
+ name: stimuli
+ level: optional
+ opaque: true
+ subject:
+ entity: subject
+ level: required
+ opaque: false
+ subdirs:
+ - oneOf:
+ - session
+ - datatype
+ session:
+ entity: session
+ level: optional
+ opaque: false
+ subdirs:
+ - datatype
+ datatype:
+ value: datatype
+ level: required
+ opaque: false
+
+derivative:
+ root:
+ subdirs:
+ - code
+ - derivatives
+ - phenotype
+ - sourcedata
+ - stimuli
+ - subject
+ code:
+ name: code
+ level: optional
+ opaque: true
+ derivatives:
+ name: derivatives
+ level: optional
+ opaque: true
+ phenotype:
+ name: phenotype
+ level: optional
+ opaque: false
+ sourcedata:
+ name: sourcedata
+ level: optional
+ opaque: true
+ stimuli:
+ name: stimuli
+ level: optional
+ opaque: true
+ subject:
+ entity: subject
+ level: optional
+ opaque: false
+ subdirs:
+ - session
+ - datatype
+ session:
+ entity: session
+ level: optional
+ opaque: false
+ subdirs:
+ - datatype
+ datatype:
+ value: datatype
+ level: optional
+ opaque: false
diff --git a/bep32v01/ressources/schema/rules/entities.yaml b/bep32v01/ressources/schema/rules/entities.yaml
new file mode 100644
index 00000000..2194a61a
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/entities.yaml
@@ -0,0 +1,32 @@
+---
+# This file simply defines the order in which entities should appear within filenames.
+# Entity definitions appear in the `objects/entities.yaml` file.
+- subject
+- session
+- sample
+- task
+- tracksys
+- acquisition
+- ceagent
+- tracer
+- stain
+- reconstruction
+- direction
+- run
+- modality
+- echo
+- flip
+- inversion
+- mtransfer
+- part
+- processing
+- hemisphere
+- space
+- split
+- recording
+- chunk
+- segmentation
+- resolution
+- density
+- label
+- description
diff --git a/bep32v01/ressources/schema/rules/errors.yaml b/bep32v01/ressources/schema/rules/errors.yaml
new file mode 100644
index 00000000..5c8fd069
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/errors.yaml
@@ -0,0 +1,248 @@
+---
+# This file describes rules for broad "standard" errors in the specification.
+
+# BIDS Validator Original Issue Code #0
+InternalError:
+ code: INTERNAL_ERROR
+ message: |
+ Internal error. SOME VALIDATION STEPS MAY NOT HAVE OCCURRED.
+ level: error
+
+# BIDS Validator Original Issue Code #1
+NotIncluded:
+ code: NOT_INCLUDED
+ message: |
+ Files with such naming scheme are not part of BIDS specification. This error is
+ most commonly caused by typos in filenames that make them not BIDS compatible.
+ Please consult the specification and make sure your files are named correctly.
+ level: error
+
+# BIDS Validator Original Issue Code #26
+NiftiHeaderUnreadable:
+ code: NIFTI_HEADER_UNREADABLE
+ message: |
+ We were unable to parse header data from this NIfTI file.
+ Please ensure it is not corrupted or mislabeled.
+ level: error
+ selectors:
+ - match(extension, '^\.nii(\.gz)?$')
+
+# BIDS Validator Original Issue Code #27
+JsonInvalid:
+ code: JSON_INVALID
+ message: |
+ Not a valid JSON file.
+ level: error
+ selectors:
+ - extension == ".json"
+
+# BIDS Validator Original Issue Code #28
+GzNotGzipped:
+ code: GZ_NOT_GZIPPED
+ message: |
+ This file ends in the .gz extension but is not actually gzipped.
+ level: error
+ selectors:
+ - match(extension, '\.gz$')
+
+# BIDS Validator Original Issue Code #36
+NiftiTooSmall:
+ code: NIFTI_TOO_SMALL
+ message: |
+ This file is too small to contain the minimal NIfTI header.
+ level: error
+ selectors:
+ - match(extension, '^\.nii(\.gz)?$')
+
+# BIDS Validator Original Issue Code #43
+OrphanedSymlink:
+ code: ORPHANED_SYMLINK
+ message: |
+ This file appears to be an orphaned symlink.
+ Make sure it correctly points to its referent.
+ level: error
+
+# BIDS Validator Original Issue Code #44
+FileRead:
+ code: FILE_READ
+ message: |
+ We were unable to read this file.
+ Make sure it contains data (file size > 0 kB) and is not corrupted,
+ incorrectly named, or incorrectly symlinked.
+ level: error
+
+# BIDS Validator Original Issue Code #46
+BvecRowLength:
+ code: BVEC_ROW_LENGTH
+ message: |
+ Each row in a .bvec file should contain the same number of values.
+ level: error
+ selectors:
+ - extension == ".bvec"
+
+# BIDS Validator Original Issue Code #47
+BFile:
+ code: B_FILE
+ message: |
+ .bval and .bvec files must be single space delimited
+ and contain only numerical values.
+ level: error
+ selectors:
+ - intersects([extension], [".bval", ".bvec"])
+
+# BIDS Validator Original Issue Code #55
+JsonSchemaValidationError:
+ code: JSON_SCHEMA_VALIDATION_ERROR
+ message: |
+ Invalid JSON file. The file is not formatted according the schema.
+ level: error
+ selectors:
+ - extension == ".json"
+
+# BIDS Validator Original Issue Code #67
+NoValidDataFoundForSubject:
+ code: NO_VALID_DATA_FOUND_FOR_SUBJECT
+ message: |
+ No BIDS compatible data found for at least one subject.
+ level: error
+
+# BIDS Validator Original Issue Code #70
+WrongNewLine:
+ code: WRONG_NEW_LINE
+ message: |
+ All TSV files must use Line Feed '\n' characters to denote new lines.
+ This files uses Carriage Return '\r'.
+ level: error
+ selectors:
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #88
+MalformedBvec:
+ code: MALFORMED_BVEC
+ message: |
+ The contents of this .bvec file are undefined or severely malformed.
+ level: error
+ selectors:
+ - extension == ".bvec"
+
+# BIDS Validator Original Issue Code #89
+MalformedBval:
+ code: MALFORMED_BVAL
+ message: |
+ The contents of this .bval file are undefined or severely malformed.
+ level: error
+ selectors:
+ - extension == ".bval"
+
+# BIDS Validator Original Issue Code #90
+SidecarWithoutDatafile:
+ code: SIDECAR_WITHOUT_DATAFILE
+ message: |
+ A json sidecar file was found without a corresponding data file.
+ level: error
+ selectors:
+ - extension == ".json"
+
+# BIDS Validator Original Issue Code #97
+MissingSession:
+ code: MISSING_SESSION
+ message: |
+ Not all subjects contain the same sessions.
+ level: warning
+
+# BIDS Validator Original Issue Code #98
+InaccessibleRemoteFile:
+ code: INACCESSIBLE_REMOTE_FILE
+ message: |
+ This file appears to be a symlink to a remote annexed file,
+ but could not be accessed from any of the configured remotes.
+ level: error
+
+# BIDS Validator Original Issue Code #99
+EmptyFile:
+ code: EMPTY_FILE
+ message: |
+ Empty files not allowed.
+ level: error
+
+# BIDS Validator Original Issue Code #100
+BrainvisionLinksBroken:
+ code: BRAINVISION_LINKS_BROKEN
+ message: |
+ Internal file pointers in BrainVision file triplet (*.eeg, *.vhdr,
+ and *.vmrk) are broken or some files do not exist.
+ level: error
+ selectors:
+ - intersects([extension], [".eeg", ".vhdr", ".vmrk"])
+
+# BIDS Validator Original Issue Code #104
+HedError:
+ code: HED_ERROR
+ message: |
+ The validation on this HED string returned an error.
+ level: error
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #105
+HedWarning:
+ code: HED_WARNING
+ message: |
+ The validation on this HED string returned a warning.
+ level: warning
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #106
+HedInternalError:
+ code: HED_INTERNAL_ERROR
+ message: |
+ An internal error occurred during HED validation.
+ level: error
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #107
+HedInternalWarning:
+ code: HED_INTERNAL_WARNING
+ message: |
+ An internal warning occurred during HED validation.
+ level: warning
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #108
+HedMissingValueInSidecar:
+ code: HED_MISSING_VALUE_IN_SIDECAR
+ message: |
+ The json sidecar does not contain this column value as
+ a possible key to a HED string.
+ level: warning
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #109
+HedVersionNotDefined:
+ code: HED_VERSION_NOT_DEFINED
+ message: |
+ You should define 'HEDVersion' for this file.
+ If you don't provide this information, the HED validation will use
+ the latest version available.
+ level: warning
+ selectors:
+ - suffix == "events"
+ - extension == ".tsv"
+
+# BIDS Validator Original Issue Code #123
+InvalidJsonEncoding:
+ code: INVALID_JSON_ENCODING
+ message: |
+ JSON files must be valid utf-8.
+ level: error
+ selectors:
+ - extension == ".json"
diff --git a/bep32v01/ressources/schema/rules/files/common/core.yaml b/bep32v01/ressources/schema/rules/files/common/core.yaml
new file mode 100644
index 00000000..2fad28f4
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/common/core.yaml
@@ -0,0 +1,39 @@
+---
+# Core files are files and directories that can be found at the top level
+# of a dataset.
+# The keys of this file must match keys in objects/files.yaml
+dataset_description:
+ level: required
+ path: dataset_description.json
+CITATION:
+ level: optional
+ path: CITATION.cff
+README:
+ level: recommended
+ stem: README
+ extensions:
+ - ''
+ - .md
+ - .rst
+ - .txt
+CHANGES:
+ level: optional
+ path: CHANGES
+LICENSE:
+ level: optional
+ path: LICENSE
+genetic_info:
+ level: optional
+ path: genetic_info.json
+code:
+ level: optional
+ path: code
+derivatives:
+ level: optional
+ path: derivatives
+sourcedata:
+ level: optional
+ path: sourcedata
+stimuli:
+ level: optional
+ path: stimuli
diff --git a/bep32v01/ressources/schema/rules/files/common/tables.yaml b/bep32v01/ressources/schema/rules/files/common/tables.yaml
new file mode 100644
index 00000000..5a304dbf
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/common/tables.yaml
@@ -0,0 +1,32 @@
+---
+participants:
+ level: optional
+ stem: participants
+ extensions:
+ - .tsv
+ - .json
+samples:
+ level: optional
+ stem: samples
+ extensions:
+ - .tsv
+ - .json
+scans:
+ level: optional
+ suffixes:
+ - scans
+ extensions:
+ - .tsv
+ - .json
+ entities:
+ subject: required
+ session: optional # session is required if session is present in the dataset.
+sessions: # This file may only exist if session is present in the dataset.
+ level: optional
+ suffixes:
+ - sessions
+ extensions:
+ - .tsv
+ - .json
+ entities:
+ subject: required
diff --git a/bep32v01/ressources/schema/rules/files/deriv/imaging.yaml b/bep32v01/ressources/schema/rules/files/deriv/imaging.yaml
new file mode 100644
index 00000000..e037dcc1
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/deriv/imaging.yaml
@@ -0,0 +1,220 @@
+---
+anat_parametric_volumetric:
+ $ref: rules.files.raw.anat.parametric
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+anat_nonparametric_volumetric:
+ $ref: rules.files.raw.anat.nonparametric
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+dwi_volumetric:
+ $ref: rules.files.raw.dwi.dwi
+ entities:
+ $ref: rules.files.raw.dwi.dwi.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+func_volumetric:
+ $ref: rules.files.raw.func.func
+ entities:
+ $ref: rules.files.raw.func.func.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+anat_parametric_mask:
+ $ref: rules.files.raw.anat.parametric
+ suffixes:
+ - mask
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+anat_nonparametric_mask:
+ $ref: rules.files.raw.anat.nonparametric
+ suffixes:
+ - mask
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+dwi_mask:
+ $ref: rules.files.raw.dwi.dwi
+ suffixes:
+ - mask
+ entities:
+ $ref: rules.files.raw.dwi.dwi.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+func_mask:
+ $ref: rules.files.raw.func.func
+ suffixes:
+ - mask
+ entities:
+ $ref: rules.files.raw.func.func.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+anat_parametric_discrete_segmentation:
+ $ref: rules.files.raw.anat.parametric
+ suffixes:
+ - dseg
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ - .tsv
+
+anat_nonparametric_discrete_segmentation:
+ $ref: rules.files.raw.anat.nonparametric
+ suffixes:
+ - dseg
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ - .tsv
+
+func_discrete_segmentation:
+ $ref: rules.files.raw.func.func
+ suffixes:
+ - dseg
+ entities:
+ $ref: rules.files.raw.func.func.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+dwi_discrete_segmentation:
+ $ref: rules.files.raw.dwi.dwi
+ suffixes:
+ - dseg
+ entities:
+ $ref: rules.files.raw.dwi.dwi.entities
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+anat_parametric_probabilistic_segmentation:
+ $ref: rules.files.raw.anat.parametric
+ suffixes:
+ - probseg
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+anat_nonparametric_probabilistic_segmentation:
+ $ref: rules.files.raw.anat.nonparametric
+ suffixes:
+ - probseg
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+func_probabilistic_segmentation:
+ $ref: rules.files.raw.func.func
+ suffixes:
+ - probseg
+ entities:
+ $ref: rules.files.raw.func.func.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+dwi_probabilistic_segmentation:
+ $ref: rules.files.raw.dwi.dwi
+ suffixes:
+ - probseg
+ entities:
+ $ref: rules.files.raw.dwi.dwi.entities
+ space: optional
+ resolution: optional
+ density: optional
+ label: optional
+ description: optional
+
+anat_parametic_discrete_surface:
+ $ref: rules.files.raw.anat.parametric
+ suffixes:
+ - dseg
+ extensions:
+ - .label.gii
+ - .dlabel.nii
+ - .json
+ - .tsv
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ hemisphere: optional
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
+
+anat_nonparametic_discrete_surface:
+ $ref: rules.files.raw.anat.nonparametric
+ suffixes:
+ - dseg
+ extensions:
+ - .label.gii
+ - .dlabel.nii
+ - .json
+ - .tsv
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ hemisphere: optional
+ space: optional
+ resolution: optional
+ density: optional
+ description: optional
diff --git a/bep32v01/ressources/schema/rules/files/deriv/preprocessed_data.yaml b/bep32v01/ressources/schema/rules/files/deriv/preprocessed_data.yaml
new file mode 100644
index 00000000..5503b200
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/deriv/preprocessed_data.yaml
@@ -0,0 +1,224 @@
+---
+anat_nonparametric_common:
+ $ref: rules.files.raw.anat.nonparametric
+ entities:
+ $ref: rules.files.raw.anat.nonparametric.entities
+ space: optional
+ description: optional
+
+anat_parametric_common:
+ $ref: rules.files.raw.anat.parametric
+ entities:
+ $ref: rules.files.raw.anat.parametric.entities
+ space: optional
+ description: optional
+
+anat_defacemask_common:
+ $ref: rules.files.raw.anat.defacemask
+ entities:
+ $ref: rules.files.raw.anat.defacemask.entities
+ space: optional
+ description: optional
+
+anat_multiecho_common:
+ $ref: rules.files.raw.anat.multiecho
+ entities:
+ $ref: rules.files.raw.anat.multiecho.entities
+ space: optional
+ description: optional
+
+anat_multiflip_common:
+ $ref: rules.files.raw.anat.multiflip
+ entities:
+ $ref: rules.files.raw.anat.multiflip.entities
+ space: optional
+ description: optional
+
+anat_multiinversion_common:
+ $ref: rules.files.raw.anat.multiinversion
+ entities:
+ $ref: rules.files.raw.anat.multiinversion.entities
+ space: optional
+ description: optional
+
+anat_mp2rage_common:
+ $ref: rules.files.raw.anat.mp2rage
+ entities:
+ $ref: rules.files.raw.anat.mp2rage.entities
+ space: optional
+ description: optional
+
+anat_vfamt_common:
+ $ref: rules.files.raw.anat.vfamt
+ entities:
+ $ref: rules.files.raw.anat.vfamt.entities
+ space: optional
+ description: optional
+
+anat_mtr_common:
+ $ref: rules.files.raw.anat.mtr
+ entities:
+ $ref: rules.files.raw.anat.mtr.entities
+ space: optional
+ description: optional
+
+beh_noncontinuous_common:
+ $ref: rules.files.raw.beh.noncontinuous
+ entities:
+ $ref: rules.files.raw.beh.noncontinuous.entities
+ space: optional
+ description: optional
+
+dwi_dwi_common:
+ $ref: rules.files.raw.dwi.dwi
+ entities:
+ $ref: rules.files.raw.dwi.dwi.entities
+ space: optional
+ description: optional
+
+dwi_sbref_common:
+ $ref: rules.files.raw.dwi.sbref
+ entities:
+ $ref: rules.files.raw.dwi.sbref.entities
+ space: optional
+ description: optional
+
+eeg_eeg_common:
+ $ref: rules.files.raw.eeg.eeg
+ entities:
+ $ref: rules.files.raw.eeg.eeg.entities
+ space: optional
+ description: optional
+
+fmap_fieldmaps_common:
+ $ref: rules.files.raw.fmap.fieldmaps
+ entities:
+ $ref: rules.files.raw.fmap.fieldmaps.entities
+ space: optional
+ description: optional
+
+fmap_pepolar_common:
+ $ref: rules.files.raw.fmap.pepolar
+ entities:
+ $ref: rules.files.raw.fmap.pepolar.entities
+ space: optional
+ description: optional
+
+fmap_TB1DAM_common:
+ $ref: rules.files.raw.fmap.TB1DAM
+ entities:
+ $ref: rules.files.raw.fmap.TB1DAM.entities
+ space: optional
+ description: optional
+
+fmap_TB1EPI_common:
+ $ref: rules.files.raw.fmap.TB1EPI
+ entities:
+ $ref: rules.files.raw.fmap.TB1EPI.entities
+ space: optional
+ description: optional
+
+fmap_RFFieldMaps_common:
+ $ref: rules.files.raw.fmap.RFFieldMaps
+ entities:
+ $ref: rules.files.raw.fmap.RFFieldMaps.entities
+ space: optional
+ description: optional
+
+fmap_TB1SRGE_common:
+ $ref: rules.files.raw.fmap.TB1SRGE
+ entities:
+ $ref: rules.files.raw.fmap.TB1SRGE.entities
+ space: optional
+ description: optional
+
+fmap_parametric_common:
+ $ref: rules.files.raw.fmap.parametric
+ entities:
+ $ref: rules.files.raw.fmap.parametric.entities
+ space: optional
+ description: optional
+
+func_func_common:
+ $ref: rules.files.raw.func.func
+ entities:
+ $ref: rules.files.raw.func.func.entities
+ space: optional
+ description: optional
+
+func_phase_common:
+ $ref: rules.files.raw.func.phase
+ entities:
+ $ref: rules.files.raw.func.phase.entities
+ space: optional
+ description: optional
+
+ieeg_ieeg_common:
+ $ref: rules.files.raw.ieeg.ieeg
+ entities:
+ $ref: rules.files.raw.ieeg.ieeg.entities
+ space: optional
+ description: optional
+
+meg_meg_common:
+ $ref: rules.files.raw.meg.meg
+ entities:
+ $ref: rules.files.raw.meg.meg.entities
+ space: optional
+ description: optional
+
+meg_calibration_common:
+ $ref: rules.files.raw.meg.calibration
+ entities:
+ $ref: rules.files.raw.meg.calibration.entities
+ space: optional
+ description: optional
+
+meg_crosstalk_common:
+ $ref: rules.files.raw.meg.crosstalk
+ entities:
+ $ref: rules.files.raw.meg.crosstalk.entities
+ space: optional
+ description: optional
+
+meg_headshape_common:
+ $ref: rules.files.raw.meg.headshape
+ entities:
+ $ref: rules.files.raw.meg.headshape.entities
+ space: optional
+ description: optional
+
+meg_markers_common:
+ $ref: rules.files.raw.meg.markers
+ entities:
+ $ref: rules.files.raw.meg.markers.entities
+ space: optional
+ description: optional
+
+micr_microscopy_common:
+ $ref: rules.files.raw.micr.microscopy
+ entities:
+ $ref: rules.files.raw.micr.microscopy.entities
+ space: optional
+ description: optional
+
+perf_asl_common:
+ $ref: rules.files.raw.perf.asl
+ entities:
+ $ref: rules.files.raw.perf.asl.entities
+ space: optional
+ description: optional
+
+pet_pet_common:
+ $ref: rules.files.raw.pet.pet
+ entities:
+ $ref: rules.files.raw.pet.pet.entities
+ space: optional
+ description: optional
+
+pet_blood_common:
+ $ref: rules.files.raw.pet.blood
+ entities:
+ $ref: rules.files.raw.pet.blood.entities
+ space: optional
+ description: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/anat.yaml b/bep32v01/ressources/schema/rules/files/raw/anat.yaml
new file mode 100644
index 00000000..7a8a3234
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/anat.yaml
@@ -0,0 +1,219 @@
+---
+nonparametric:
+ suffixes:
+ - T1w
+ - T2w
+ - PDw
+ - T2starw
+ - FLAIR
+ - inplaneT1
+ - inplaneT2
+ - PDT2
+ - angio
+ - T2star # deprecated
+ - FLASH # deprecated
+ - PD # deprecated
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ part: optional
+ chunk: optional
+
+parametric:
+ suffixes:
+ - T1map
+ - T2map
+ - T2starmap
+ - R1map
+ - R2map
+ - R2starmap
+ - PDmap
+ - MTRmap
+ - MTsat
+ - UNIT1
+ - T1rho
+ - MWFmap
+ - MTVmap
+ - Chimap
+ - S0map
+ - M0map
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ chunk: optional
+
+defacemask:
+ suffixes:
+ - defacemask
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ modality: optional
+ chunk: optional
+
+multiecho:
+ suffixes:
+ - MESE
+ - MEGRE
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: required
+ part: optional
+ chunk: optional
+
+multiflip:
+ suffixes:
+ - VFA
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ flip: required
+ part: optional
+ chunk: optional
+
+multiinversion:
+ suffixes:
+ - IRT1
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ inversion: required
+ part: optional
+ chunk: optional
+
+mp2rage:
+ suffixes:
+ - MP2RAGE
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ flip: optional
+ inversion: required
+ part: optional
+ chunk: optional
+
+vfamt:
+ suffixes:
+ - MPM
+ - MTS
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ flip: required
+ mtransfer: required
+ part: optional
+ chunk: optional
+
+mtr:
+ suffixes:
+ - MTR
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - anat
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ mtransfer: required
+ part: optional
+ chunk: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/beh.yaml b/bep32v01/ressources/schema/rules/files/raw/beh.yaml
new file mode 100644
index 00000000..61930152
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/beh.yaml
@@ -0,0 +1,16 @@
+---
+# Non-continuous data
+noncontinuous:
+ suffixes:
+ - beh
+ extensions:
+ - .tsv
+ - .json
+ datatypes:
+ - beh
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/channels.yaml b/bep32v01/ressources/schema/rules/files/raw/channels.yaml
new file mode 100644
index 00000000..06c213be
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/channels.yaml
@@ -0,0 +1,95 @@
+---
+channels:
+ suffixes:
+ - channels
+ extensions:
+ - .json
+ - .tsv
+ datatypes:
+ - eeg
+ - ieeg
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+
+# MEG has an additional entity available
+channels__meg:
+ $ref: rules.files.raw.channels.channels
+ datatypes:
+ - meg
+ entities:
+ $ref: rules.files.raw.channels.channels.entities
+ processing: optional
+
+# motion has an additional entity available
+channels__motion:
+ $ref: rules.files.raw.channels.channels
+ datatypes:
+ - motion
+ entities:
+ $ref: rules.files.raw.channels.channels.entities
+ tracksys: required
+
+coordsystem:
+ suffixes:
+ - coordsystem
+ extensions:
+ - .json
+ datatypes:
+ - meg
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+
+# (i)EEG has a space entity
+coordsystem__eeg:
+ $ref: rules.files.raw.channels.coordsystem
+ datatypes:
+ - eeg
+ - ieeg
+ entities:
+ $ref: rules.files.raw.channels.coordsystem.entities
+ space: optional
+
+electrodes:
+ suffixes:
+ - electrodes
+ extensions:
+ - .json
+ - .tsv
+ datatypes:
+ - eeg
+ - ieeg
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ space: optional
+
+# MEG has an additional entity available
+electrodes__meg:
+ $ref: rules.files.raw.channels.electrodes
+ datatypes:
+ - meg
+ entities:
+ $ref: rules.files.raw.channels.electrodes.entities
+ processing: optional
+
+optodes:
+ suffixes:
+ - optodes
+ extensions:
+ - .tsv
+ - .json
+ datatypes:
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/dwi.yaml b/bep32v01/ressources/schema/rules/files/raw/dwi.yaml
new file mode 100644
index 00000000..22b224b0
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/dwi.yaml
@@ -0,0 +1,40 @@
+---
+dwi:
+ suffixes:
+ - dwi
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ - .bvec
+ - .bval
+ datatypes:
+ - dwi
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+ part: optional
+ chunk: optional
+
+sbref:
+ suffixes:
+ - sbref
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - dwi
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+ part: optional
+ chunk: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/eeg.yaml b/bep32v01/ressources/schema/rules/files/raw/eeg.yaml
new file mode 100644
index 00000000..676d66dc
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/eeg.yaml
@@ -0,0 +1,21 @@
+---
+eeg:
+ suffixes:
+ - eeg
+ extensions:
+ - .json
+ - .edf
+ - .vhdr
+ - .vmrk
+ - .eeg
+ - .set
+ - .fdt
+ - .bdf
+ datatypes:
+ - eeg
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/fmap.yaml b/bep32v01/ressources/schema/rules/files/raw/fmap.yaml
new file mode 100644
index 00000000..056ed1d6
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/fmap.yaml
@@ -0,0 +1,151 @@
+---
+fieldmaps:
+ suffixes:
+ - phasediff
+ - phase1
+ - phase2
+ - magnitude1
+ - magnitude2
+ - magnitude
+ - fieldmap
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ run: optional
+ chunk: optional
+
+pepolar:
+ suffixes:
+ - epi
+ - m0scan
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ direction: required
+ run: optional
+ part: optional
+ chunk: optional
+
+TB1DAM:
+ suffixes:
+ - TB1DAM
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ flip: required
+ inversion: optional
+ part: optional
+ chunk: optional
+
+TB1EPI:
+ suffixes:
+ - TB1EPI
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: required
+ flip: required
+ inversion: optional
+ part: optional
+ chunk: optional
+
+RFFieldMaps:
+ suffixes:
+ - TB1AFI
+ - TB1TFL
+ - TB1RFM
+ - RB1COR
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ flip: optional
+ inversion: optional
+ part: optional
+ chunk: optional
+
+TB1SRGE:
+ suffixes:
+ - TB1SRGE
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ echo: optional
+ flip: required
+ inversion: required
+ part: optional
+ chunk: optional
+
+parametric:
+ suffixes:
+ - TB1map
+ - RB1map
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - fmap
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ run: optional
+ chunk: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/func.yaml b/bep32v01/ressources/schema/rules/files/raw/func.yaml
new file mode 100644
index 00000000..5e2c42b8
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/func.yaml
@@ -0,0 +1,45 @@
+---
+func:
+ suffixes:
+ - bold
+ - cbv
+ - sbref
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - func
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+ echo: optional
+ part: optional
+ chunk: optional
+
+phase:
+ suffixes:
+ - phase # deprecated
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - func
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ ceagent: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+ echo: optional
+ chunk: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/ieeg.yaml b/bep32v01/ressources/schema/rules/files/raw/ieeg.yaml
new file mode 100644
index 00000000..587f9bcb
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/ieeg.yaml
@@ -0,0 +1,22 @@
+---
+ieeg:
+ suffixes:
+ - ieeg
+ extensions:
+ - .mefd/
+ - .json
+ - .edf
+ - .vhdr
+ - .eeg
+ - .vmrk
+ - .set
+ - .fdt
+ - .nwb
+ datatypes:
+ - ieeg
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/meg.yaml b/bep32v01/ressources/schema/rules/files/raw/meg.yaml
new file mode 100644
index 00000000..a25ed566
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/meg.yaml
@@ -0,0 +1,86 @@
+---
+meg:
+ suffixes:
+ - meg
+ extensions:
+ - / # corresponds to BTi/4D data
+ - .ds/
+ - .json
+ - .fif
+ - .sqd
+ - .con
+ - .raw
+ - .ave
+ - .mrk
+ - .kdf
+ - .mhd
+ - .trg
+ - .chn
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+ processing: optional
+ split: optional
+
+calibration:
+ suffixes:
+ - meg
+ extensions:
+ - .dat
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ acquisition:
+ level: required
+ enum:
+ - $ref: objects.enums.calibration.value
+
+crosstalk:
+ suffixes:
+ - meg
+ extensions:
+ - .fif
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ acquisition:
+ level: required
+ enum:
+ - $ref: objects.enums.crosstalk.value
+
+headshape:
+ suffixes:
+ - headshape
+ extensions:
+ - .*
+ - .pos
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+
+markers:
+ suffixes:
+ - markers
+ extensions:
+ - .sqd
+ - .mrk
+ datatypes:
+ - meg
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ acquisition: optional
+ space: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/micr.yaml b/bep32v01/ressources/schema/rules/files/raw/micr.yaml
new file mode 100644
index 00000000..52d1adb7
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/micr.yaml
@@ -0,0 +1,38 @@
+---
+microscopy:
+ suffixes:
+ - TEM
+ - SEM
+ - uCT
+ - BF
+ - DF
+ - PC
+ - DIC
+ - FLUO
+ - CONF
+ - PLI
+ - CARS
+ - 2PE
+ - MPE
+ - SR
+ - NLO
+ - OCT
+ - SPIM
+ - hipCT
+ extensions:
+ - .ome.tif
+ - .ome.btf
+ - .ome.zarr/
+ - .png
+ - .tif
+ - .json
+ datatypes:
+ - micr
+ entities:
+ subject: required
+ session: optional
+ sample: required
+ acquisition: optional
+ stain: optional
+ run: optional
+ chunk: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/motion.yaml b/bep32v01/ressources/schema/rules/files/raw/motion.yaml
new file mode 100644
index 00000000..5ac18a4e
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/motion.yaml
@@ -0,0 +1,16 @@
+---
+motion:
+ suffixes:
+ - motion
+ extensions:
+ - .tsv
+ - .json
+ datatypes:
+ - motion
+ entities:
+ subject: required
+ session: optional
+ task: required
+ tracksys: required
+ acquisition: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/nirs.yaml b/bep32v01/ressources/schema/rules/files/raw/nirs.yaml
new file mode 100644
index 00000000..8dfc41e8
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/nirs.yaml
@@ -0,0 +1,15 @@
+---
+nirs:
+ suffixes:
+ - nirs
+ extensions:
+ - .snirf
+ - .json
+ datatypes:
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/perf.yaml b/bep32v01/ressources/schema/rules/files/raw/perf.yaml
new file mode 100644
index 00000000..2964cff3
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/perf.yaml
@@ -0,0 +1,49 @@
+---
+asl:
+ suffixes:
+ - asl
+ - m0scan
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - perf
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+
+aslcontext:
+ suffixes:
+ - aslcontext
+ extensions:
+ - .tsv
+ datatypes:
+ - perf
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ reconstruction: optional
+ direction: optional
+ run: optional
+
+asllabeling:
+ suffixes:
+ - asllabeling
+ extensions:
+ - .jpg
+ - .png
+ - .tif
+ datatypes:
+ - perf
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ reconstruction: optional
+ run: optional
diff --git a/bep32v01/ressources/schema/rules/files/raw/pet.yaml b/bep32v01/ressources/schema/rules/files/raw/pet.yaml
new file mode 100644
index 00000000..a94cb9ad
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/pet.yaml
@@ -0,0 +1,34 @@
+---
+pet:
+ suffixes:
+ - pet
+ extensions:
+ - .nii.gz
+ - .nii
+ - .json
+ datatypes:
+ - pet
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ tracer: optional
+ reconstruction: optional
+ run: optional
+
+blood:
+ suffixes:
+ - blood
+ extensions:
+ - .tsv
+ - .json
+ datatypes:
+ - pet
+ entities:
+ subject: required
+ session: optional
+ task: optional
+ tracer: optional
+ reconstruction: optional
+ run: optional
+ recording: required
diff --git a/bep32v01/ressources/schema/rules/files/raw/photo.yaml b/bep32v01/ressources/schema/rules/files/raw/photo.yaml
new file mode 100644
index 00000000..f5969e2d
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/photo.yaml
@@ -0,0 +1,30 @@
+---
+photo:
+ suffixes:
+ - photo
+ extensions:
+ - .jpg
+ - .png
+ - .tif
+ datatypes:
+ - eeg
+ - ieeg
+ - meg
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+
+photo__micr:
+ $ref: rules.files.raw.photo.photo
+ extensions:
+ - .jpg
+ - .png
+ - .tif
+ - .json
+ datatypes:
+ - micr
+ entities:
+ $ref: rules.files.raw.photo.photo.entities
+ sample: required
diff --git a/bep32v01/ressources/schema/rules/files/raw/task.yaml b/bep32v01/ressources/schema/rules/files/raw/task.yaml
new file mode 100644
index 00000000..b7171e56
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/files/raw/task.yaml
@@ -0,0 +1,132 @@
+---
+events:
+ suffixes:
+ - events
+ extensions:
+ - .tsv
+ - .json
+ datatypes:
+ - beh
+ - eeg
+ - ieeg
+ - meg
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+
+timeseries:
+ suffixes:
+ - physio
+ - stim
+ extensions:
+ - .tsv.gz
+ - .json
+ datatypes:
+ - beh
+ - eeg
+ - ieeg
+ - nirs
+ entities:
+ subject: required
+ session: optional
+ task: required
+ acquisition: optional
+ run: optional
+ recording: optional
+
+timeseries__mri_no_task:
+ suffixes:
+ - physio
+ - stim
+ extensions:
+ - .tsv.gz
+ - .json
+ datatypes:
+ - dwi
+ - perf
+ entities:
+ subject: required
+ session: optional
+ acquisition: optional
+ run: optional
+ reconstruction: optional
+ direction: optional
+ recording: optional
+
+# Specializations
+# In these rules, we use $ref to retrieve most of an object, and then override
+
+events__mri:
+ $ref: rules.files.raw.task.events
+ datatypes:
+ - func
+ entities:
+ $ref: rules.files.raw.task.events.entities
+ ceagent: optional
+ reconstruction: optional
+ direction: optional
+
+events__motion:
+ $ref: rules.files.raw.task.events
+ datatypes:
+ - motion
+ entities:
+ $ref: rules.files.raw.task.events.entities
+ tracksys: optional
+
+events__pet:
+ $ref: rules.files.raw.task.events
+ datatypes:
+ - pet
+ entities:
+ # Most events allow acquisition, PET doesn't
+ subject: required
+ session: optional
+ task: required
+ tracer: optional
+ reconstruction: optional
+ run: optional
+
+timeseries__func:
+ $ref: rules.files.raw.task.timeseries
+ datatypes:
+ - func
+ entities:
+ $ref: rules.files.raw.task.timeseries.entities
+ ceagent: optional
+ reconstruction: optional
+ direction: optional
+
+timeseries__meg:
+ $ref: rules.files.raw.task.timeseries
+ datatypes:
+ - meg
+ entities:
+ $ref: rules.files.raw.task.timeseries.entities
+ processing: optional
+
+timeseries__motion:
+ $ref: rules.files.raw.task.timeseries
+ datatypes:
+ - motion
+ entities:
+ $ref: rules.files.raw.task.timeseries.entities
+ tracksys: optional
+
+timeseries__pet:
+ $ref: rules.files.raw.task.timeseries
+ datatypes:
+ - pet
+ entities:
+ # Most timeseries allow acquisition, PET doesn't
+ subject: required
+ session: optional
+ task: required
+ tracer: optional
+ reconstruction: optional
+ run: optional
+ recording: optional
diff --git a/bep32v01/ressources/schema/rules/modalities.yaml b/bep32v01/ressources/schema/rules/modalities.yaml
new file mode 100644
index 00000000..2f290ca0
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/modalities.yaml
@@ -0,0 +1,33 @@
+---
+# This file defines which data types fall under each modality.
+mri:
+ datatypes:
+ - anat
+ - dwi
+ - fmap
+ - func
+ - perf
+eeg:
+ datatypes:
+ - eeg
+ieeg:
+ datatypes:
+ - ieeg
+meg:
+ datatypes:
+ - meg
+beh:
+ datatypes:
+ - beh
+pet:
+ datatypes:
+ - pet
+micr:
+ datatypes:
+ - micr
+motion:
+ datatypes:
+ - motion
+nirs:
+ datatypes:
+ - nirs
diff --git a/bep32v01/ressources/schema/rules/sidecars/anat.yaml b/bep32v01/ressources/schema/rules/sidecars/anat.yaml
new file mode 100644
index 00000000..70a18cae
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/anat.yaml
@@ -0,0 +1,33 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Anatomy imaging data
+
+MRIAnatomyCommonMetadataFields:
+ selectors:
+ - datatype == "anat"
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ ContrastBolusIngredient: optional
+ RepetitionTimeExcitation: optional
+ RepetitionTimePreparation: optional
+
+TaskMetadata:
+ selectors:
+ - datatype == "anat"
+ - entity.task != null
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ TaskName:
+ level: recommended
+ level_addendum: if `task` entity is present
+ TaskDescription:
+ level: recommended
+ level_addendum: if `task` entity is present
+ Instructions:
+ level: recommended
+ level_addendum: if `task` entity is present
diff --git a/bep32v01/ressources/schema/rules/sidecars/asl.yaml b/bep32v01/ressources/schema/rules/sidecars/asl.yaml
new file mode 100644
index 00000000..ab540b53
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/asl.yaml
@@ -0,0 +1,201 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Fields described in text, but not in tables
+MRIASLTextOnly:
+ selectors:
+ - datatype == "perf"
+ - intersects([suffix], ["asl", "m0scan"])
+ fields:
+ RepetitionTimePreparation: required
+
+# Common metadata fields applicable to both (P)CASL and PASL
+MRIASLCommonMetadataFields:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ fields:
+ ArterialSpinLabelingType: required
+ PostLabelingDelay: required
+ BackgroundSuppression: required
+ M0Type: required
+ TotalAcquiredPairs: required
+ VascularCrushing: recommended
+ AcquisitionVoxelSize: recommended
+ LabelingOrientation: recommended
+ LabelingDistance: recommended
+ LabelingLocationDescription: recommended
+ LookLocker: optional
+ LabelingEfficiency: optional
+
+MRIASLCommonMetadataFieldsM0TypeRec:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.M0Type != "Estimate"
+ fields:
+ M0Estimate:
+ level: optional
+ level_addendum: required if `M0Type` is `Estimate`
+
+MRIASLCommonMetadataFieldsM0TypeReq:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.M0Type == "Estimate"
+ fields:
+ M0Estimate:
+ level: required
+ issue:
+ code: M0ESTIMATE_NOT_DEFINED
+ message: |
+ You must define `M0Estimate` for this file, because `M0Type` is set to
+ 'Estimate'. `M0Estimate` is a single numerical whole-brain M0 value
+ (referring to the M0 of blood), only if obtained externally (for example
+ retrieved from CSF in a separate measurement).
+
+MRIASLCommonMetadataFieldsBackgroundSuppressionOpt:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.BackgroundSuppression == false
+ fields:
+ BackgroundSuppressionNumberPulses:
+ level: optional
+ level_addendum: recommended if `BackgroundSuppression` is `true`
+ BackgroundSuppressionPulseTime:
+ level: optional
+ level_addendum: recommended if `BackgroundSuppression` is `true`
+
+MRIASLCommonMetadataFieldsBackgroundSuppressionReq:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.BackgroundSuppression == true
+ fields:
+ BackgroundSuppressionNumberPulses: recommended
+ BackgroundSuppressionPulseTime: recommended
+
+MRIASLCommonMetadataFieldsVascularCrushingOpt:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.VascularCrushing == false
+ fields:
+ VascularCrushingVENC:
+ level: optional
+ level_addendum: recommended if `VascularCrushing` is `true`
+
+MRIASLCommonMetadataFieldsVascularCrushingRec:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.VascularCrushing == true
+ fields:
+ VascularCrushingVENC: recommended
+
+MRIASLCaslPcaslSpecific:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - intersects([sidecar.ArterialSpinLabelingType], ["CASL", "PCASL"])
+ fields:
+ LabelingDuration: required
+ LabelingPulseAverageGradient: recommended
+ LabelingPulseMaximumGradient: recommended
+ LabelingPulseAverageB1: recommended
+ LabelingPulseDuration: recommended
+ LabelingPulseFlipAngle: recommended
+ LabelingPulseInterval: recommended
+
+MRIASLPcaslSpecific:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.ArterialSpinLabelingType == "PCASL"
+ fields:
+ PCASLType:
+ level: recommended
+ level_addendum: if `ArterialSpinLabelingType` is `"PCASL"`
+
+MRIASLCaslSpecific:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.ArterialSpinLabelingType == "CASL"
+ fields:
+ CASLType:
+ level: recommended
+ level_addendum: if `ArterialSpinLabelingType` is `"CASL"`
+
+MRIASLPaslSpecific:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.ArterialSpinLabelingType == "PASL"
+ fields:
+ BolusCutOffFlag: required
+ PASLType: recommended
+ LabelingSlabThickness: recommended
+
+MRIASLPASLSpecificBolusCutOffFlagFalse:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.ArterialSpinLabelingType == "PASL"
+ - sidecar.BolusCutOffFlag == false
+ fields:
+ BolusCutOffDelayTime:
+ level: optional
+ level_addendum: required if `BolusCutOffFlag` is `true`
+ BolusCutOffTechnique:
+ level: optional
+ level_addendum: required if `BolusCutOffFlag` is `true`
+
+MRIASLPaslSpecificBolusCutOffFlagTrue:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - sidecar.ArterialSpinLabelingType == "PASL"
+ - sidecar.BolusCutOffFlag == true
+ fields:
+ BolusCutOffDelayTime:
+ level: required
+ issue:
+ code: PASL_BOLUS_CUT_OFF_DELAY_TIME
+ message: |
+ It is required to define 'BolusCutOffDelayTime' for this file,
+ when 'BolusCutOffFlag' is set to true. 'BolusCutOffDelayTime' is
+ the duration between the end of the labeling and the start of the
+ bolus cut-off saturation pulse(s), in seconds. This can be a number
+ or array of numbers, of which the values must be non-negative and
+ monotonically increasing, depending on the number of bolus cut-off
+ saturation pulses. For Q2TIPS, only the values for the first and last
+ bolus cut-off saturation pulses are provided. Based on DICOM Tag
+ 0018,925F ASL Bolus Cut-off Delay Time.
+ BolusCutOffTechnique:
+ level: required
+ issue:
+ code: PASL_BOLUS_CUT_OFF_TECHINIQUE
+ message: |
+ It is required to define `BolusCutOffTechnique` for this file,
+ when `BolusCutOffFlag` is set to `true`. `BolusCutOffTechnique`,
+ is the name of the technique used
+ (for example, Q2TIPS, QUIPSS or QUIPSSII).
+ Corresponds to DICOM Tag 0018,925E `ASL Bolus Cut-off Technique`.
+
+# m0scan metadata fields
+MRIASLM0Scan:
+ selectors:
+ - datatype == "perf"
+ - suffix == "m0scan"
+ fields:
+ IntendedFor:
+ level: required
+ description_addendum: |
+ This is used to refer to the ASL time series for which the `*_m0scan.nii[.gz]` is intended.
+ AcquisitionVoxelSize: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/beh.yaml b/bep32v01/ressources/schema/rules/sidecars/beh.yaml
new file mode 100644
index 00000000..1221bf84
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/beh.yaml
@@ -0,0 +1,25 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Metadata for either beh or events files
+BEHTaskInformation:
+ selectors:
+ - intersects([suffix], ["beh", "events"])
+ fields:
+ TaskName: recommended
+ Instructions: recommended
+ TaskDescription: recommended
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+BEHInstitutionInformation:
+ selectors:
+ - intersects([suffix], ["beh", "events"])
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/continuous.yaml b/bep32v01/ressources/schema/rules/sidecars/continuous.yaml
new file mode 100644
index 00000000..2e74912f
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/continuous.yaml
@@ -0,0 +1,25 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Metadata for either physio or stim files
+Continuous:
+ selectors:
+ - intersects([suffix], ["physio", "stim"])
+ fields:
+ SamplingFrequency: required
+ StartTime: required
+ Columns: required
+
+# Other recommended metadata for physiological data
+Physio:
+ selectors:
+ - suffix == "physio"
+ fields:
+ Manufacturer: recommended
+ ManufacturersModelName: recommended
+ SoftwareVersions: recommended
+ DeviceSerialNumber: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/derivatives/common_derivatives.yaml b/bep32v01/ressources/schema/rules/sidecars/derivatives/common_derivatives.yaml
new file mode 100644
index 00000000..fbc05937
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/derivatives/common_derivatives.yaml
@@ -0,0 +1,76 @@
+---
+CommonDerivativeFields:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ fields:
+ Description:
+ level: recommended
+ description_addendum: This describes the nature of the file.
+ Sources: optional
+ RawSources: deprecated
+
+SpatialReferenceEntity:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - '"space" in entities'
+ fields:
+ SpatialReference:
+ level: recommended
+ level_addendum: |
+ if the derivative is aligned to a standard template listed in
+ [Standard template identifiers][templates]. Required otherwise.
+
+SpatialReferenceNonStandard:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - '!intersects(schema.objects.metadata._StandardTemplateCoordSys, [entities.space])'
+ fields:
+ SpatialReference: required
+
+# this needs to come before density and resolution overrides selected in a
+# different way
+MaskDerivatives:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - suffix == "mask"
+ fields:
+ Type: recommended
+ Sources: recommended
+ RawSources: deprecated
+
+SegmentationCommon:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - 'intersects([suffix], ["dseg", "probseg"])'
+ fields:
+ Manual: optional
+
+# Derivatives -> Imaging data types
+ImageDerivatives:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - 'intersects([modality], ["mri", "pet"])'
+ - 'match(extension, "^\.nii(\.gz)?$")'
+ - '!intersects([suffix], ["dseg", "probseg", "mask"])'
+ fields:
+ SkullStripped: required
+
+ImageDerivativeResEntity:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - 'intersects([modality], ["mri", "pet"])'
+ - '"res" in entities'
+ fields:
+ Resolution:
+ level: required
+ level_addendum: if `res` is present
+
+ImageDerivativeDenEntity:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - 'intersects([modality], ["mri", "pet"])'
+ - '"den" in entities'
+ fields:
+ Density:
+ level: required
+ level_addendum: if `den` is present
diff --git a/bep32v01/ressources/schema/rules/sidecars/dwi.yaml b/bep32v01/ressources/schema/rules/sidecars/dwi.yaml
new file mode 100644
index 00000000..51ae4b33
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/dwi.yaml
@@ -0,0 +1,20 @@
+---
+# Multipart (split) DWI schemes
+# NOTE: I don't think this can be schemafied, since it depends on owner intent.
+MRIDiffusionMultipart:
+ selectors:
+ - datatype == "dwi"
+ - suffix == "dwi"
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ MultipartID: optional
+
+# Other recommended metadata
+MRIDiffusionOtherMetadata:
+ selectors:
+ - datatype == "dwi"
+ - suffix == "dwi"
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ PhaseEncodingDirection: recommended
+ TotalReadoutTime: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/eeg.yaml b/bep32v01/ressources/schema/rules/sidecars/eeg.yaml
new file mode 100644
index 00000000..7a7252d6
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/eeg.yaml
@@ -0,0 +1,176 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+EEGHardware:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ Manufacturer: recommended
+ ManufacturersModelName: recommended
+ SoftwareVersions: recommended
+ DeviceSerialNumber: recommended
+
+EEGTaskInformation:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ TaskName:
+ level: required
+ description_addendum: |
+ A recommended convention is to name resting state task using labels
+ beginning with `rest`.
+ TaskDescription: recommended
+ Instructions:
+ level: recommended
+ description_addendum: |
+ This is especially important in context of resting state recordings and
+ distinguishing between eyes open and eyes closed paradigms.
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+EEGInstitutionInformation:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+# Specific EEG fields MUST be present
+EEGRequired:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ EEGReference: required
+ SamplingFrequency:
+ level: required
+ description_addendum: |
+ The sampling frequency of data channels that deviate from the main sampling
+ frequency SHOULD be specified in the `channels.tsv` file.
+ PowerLineFrequency: required
+ SoftwareFilters: required
+
+# Specific EEG fields SHOULD be present
+EEGRecommended:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ CapManufacturer: recommended
+ CapManufacturersModelName: recommended
+ EEGChannelCount: recommended
+ ECGChannelCount: recommended
+ EMGChannelCount: recommended
+ EOGChannelCount: recommended
+ MISCChannelCount: recommended
+ TriggerChannelCount: recommended
+ RecordingDuration: recommended
+ RecordingType: recommended
+ EpochLength: recommended
+ EEGGround: recommended
+ HeadCircumference: recommended
+ EEGPlacementScheme: recommended
+ HardwareFilters: recommended
+ SubjectArtefactDescription: recommended
+
+# Specific EEG fields MAY be present
+EEGOptional:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "eeg"
+ fields:
+ ElectricalStimulation: optional
+ ElectricalStimulationParameters: optional
+
+# General fields
+EEGCoordsystemGeneral:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ fields:
+ IntendedFor:
+ level: optional
+ description_addendum: |
+ This identifies the MRI or CT scan associated with the electrodes,
+ landmarks, and fiducials.
+
+# Fields relating to the EEG electrode positions
+EEGCoordsystemPositions:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ fields:
+ EEGCoordinateSystem: required
+ EEGCoordinateUnits: required
+ EEGCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if `EEGCoordinateSystem` is `"Other"`
+
+EEGCoordsystemOther:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ - '"EEGCoordinateSystem" in sidecar'
+ - sidecar.EEGCoordinateSystem == "Other"
+ fields:
+ EEGCoordinateSystemDescription: required
+
+# Fields relating to the position of fiducials measured during an EEG session/run
+EEGCoordsystemFiducials:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ fields:
+ FiducialsDescription: optional
+ FiducialsCoordinates: recommended
+ FiducialsCoordinateSystem: recommended
+ FiducialsCoordinateUnits: recommended
+ FiducialsCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if `FiducialsCoordinateSystem` is `"Other"`
+
+EEGCoordsystemOtherFiducialCoordinateSystem:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ - sidecar.FiducialsCoordinateSystem == "Other"
+ fields:
+ FiducialsCoordinateSystemDescription: required
+
+# Fields relating to the position of anatomical landmark measured during an EEG session/run
+EEGCoordsystemLandmark:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ fields:
+ AnatomicalLandmarkCoordinates: recommended
+ AnatomicalLandmarkCoordinateSystem:
+ level: recommended
+ description_addendum: Preferably the same as the `EEGCoordinateSystem`.
+ AnatomicalLandmarkCoordinateUnits: recommended
+
+EEGCoordsystemLandmarkDescriptionRec:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ - sidecar.AnatomicalLandmarkCoordinateSystem != "Other"
+ fields:
+ AnatomicalLandmarkCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if `AnatomicalLandmarkCoordinateSystem` is `"Other"`
+
+EEGCoordsystemLandmarkDescriptionReq:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "coordsystem"
+ - sidecar.AnatomicalLandmarkCoordinateSystem == "Other"
+ fields:
+ AnatomicalLandmarkCoordinateSystemDescription: required
diff --git a/bep32v01/ressources/schema/rules/sidecars/entity_rules.yaml b/bep32v01/ressources/schema/rules/sidecars/entity_rules.yaml
new file mode 100644
index 00000000..be8f5603
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/entity_rules.yaml
@@ -0,0 +1,70 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Entities
+
+EntitiesTaskMetadata:
+ selectors:
+ - '"task" in entities'
+ fields:
+ TaskName: recommended
+
+EntitiesCeMetadata:
+ selectors:
+ - '"ce" in entities'
+ fields:
+ ContrastBolusIngredient: optional
+
+EntitiesStainMetadata:
+ selectors:
+ - '"stain" in entities'
+ fields:
+ SampleStaining: recommended
+ SamplePrimaryAntibody: recommended
+ SampleSecondaryAntibody: recommended
+
+EntitiesEchoMetadata:
+ selectors:
+ - '"echo" in entities'
+ fields:
+ EchoTime: required
+
+EntitiesFlipMetadata:
+ selectors:
+ - '"flip" in entities'
+ fields:
+ FlipAngle: required
+
+EntitiesInvMetadata:
+ selectors:
+ - '"inv" in entities'
+ fields:
+ InversionTime: required
+
+EntitiesMTMetadata:
+ selectors:
+ - '"mt" in entities'
+ fields:
+ MTState: required
+
+EntitiesPartMetadata:
+ selectors:
+ - entities.part == "phase"
+ fields:
+ Units: required
+
+EntitiesResMetadata:
+ selectors:
+ - '"res" in entities'
+ fields:
+ Resolution: required
+
+EntitiesDenMetadata:
+ selectors:
+ - '"den" in entities'
+ fields:
+ Density: required
diff --git a/bep32v01/ressources/schema/rules/sidecars/events.yaml b/bep32v01/ressources/schema/rules/sidecars/events.yaml
new file mode 100644
index 00000000..abd58db7
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/events.yaml
@@ -0,0 +1,14 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Metadata for events files
+StimulusPresentation:
+ selectors:
+ - suffix == "events"
+ fields:
+ StimulusPresentation: recommended
+ VisionCorrection: optional
diff --git a/bep32v01/ressources/schema/rules/sidecars/fmap.yaml b/bep32v01/ressources/schema/rules/sidecars/fmap.yaml
new file mode 100644
index 00000000..c6423947
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/fmap.yaml
@@ -0,0 +1,71 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Fieldmap data
+MRIFieldmapIntendedFor:
+ selectors:
+ - datatype == "fmap"
+ - match(extension, '\.nii(\.gz)?$')
+ fields:
+ IntendedFor:
+ level: optional
+ description_addendum: |
+ This field is optional, and in case the fieldmaps do not correspond
+ to any particular scans, it does not have to be filled.
+
+MRIFieldmapB0FieldIdentifier:
+ selectors:
+ - datatype == "fmap"
+ - match(extension, '\.nii(\.gz)?$')
+ - '!("IntendedFor" in sidecar)'
+ fields:
+ B0FieldIdentifier: recommended
+
+# Case 1: Phase-difference map and at least one magnitude image
+MRIFieldmapPhaseDifferencePhasediff:
+ selectors:
+ - datatype == "fmap"
+ - suffix == "phasediff"
+ - match(extension, '\.nii(\.gz)?$')
+ fields:
+ EchoTime1: required
+ EchoTime2: required
+
+# Case 2: Two phase maps and two magnitude images
+# NOTE: Need to check for presence of related files.
+# For example, magnitude1 needs EchoTime__fmap only if phase1 file exists,
+# but EchoTime1 if phasediff exists.
+MRIFieldmapTwoPhase:
+ selectors:
+ - datatype == "fmap"
+ - intersects([suffix], ["phase1", "phase2"])
+ - match(extension, '\.nii(\.gz)?$')
+ fields:
+ EchoTime__fmap: required
+
+# Case 3: Direct field mapping
+MRIFieldmapDirectFieldMapping:
+ selectors:
+ - datatype == "fmap"
+ - suffix == "fieldmap"
+ - match(extension, '\.nii(\.gz)?$')
+ fields:
+ Units:
+ level: required
+ description_addendum: |
+ Fieldmaps must be in units of Hertz (`"Hz"`),
+ radians per second (`"rad/s"`), or Tesla (`"T"`).
+
+# Case 4: Multiple phase encoded directions ("pepolar")
+MRIFieldmapPepolar:
+ selectors:
+ - datatype == "fmap"
+ - suffix == "epi"
+ - match(extension, '\.nii(\.gz)?$')
+ fields:
+ PhaseEncodingDirection: required
+ TotalReadoutTime: required
diff --git a/bep32v01/ressources/schema/rules/sidecars/func.yaml b/bep32v01/ressources/schema/rules/sidecars/func.yaml
new file mode 100644
index 00000000..f3b7e70b
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/func.yaml
@@ -0,0 +1,88 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Task imaging data
+
+# Required fields
+MRIFuncRequired:
+ selectors:
+ - datatype == "func"
+ - suffix == "bold"
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ TaskName:
+ level: required
+ description_addendum: |
+ A recommended convention is to name resting state task using labels
+ beginning with `rest`.
+
+MRIFuncRepetitionTime:
+ selectors:
+ - datatype == "func"
+ - suffix == "bold"
+ - '!("VolumeTiming" in sidecar)'
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ RepetitionTime:
+ level: required
+ level_addendum: mutually exclusive with `VolumeTiming`
+
+MRIFuncVolumeTiming:
+ selectors:
+ - datatype == "func"
+ - suffix == "bold"
+ - '!("RepetitionTime" in sidecar)'
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ VolumeTiming:
+ level: required
+ level_addendum: mutually exclusive with `RepetitionTime`
+
+# Timing Parameters
+MRIFuncTimingParameters:
+ selectors:
+ - datatype == "func"
+ - suffix == "bold"
+ fields:
+ NumberOfVolumesDiscardedByScanner: recommended
+ NumberOfVolumesDiscardedByUser: recommended
+ DelayTime: recommended
+ AcquisitionDuration:
+ level: recommended
+ level_addendum: |
+ required for sequences that are described with the `VolumeTiming`
+ field and that do not have the `SliceTiming` field set to allow for
+ accurate calculation of "acquisition time"
+ issue:
+ name: VOLUME_TIMING_MISSING_ACQUISITION_DURATION
+ message: |
+ The field 'VolumeTiming' requires 'AcquisitionDuration' or 'SliceTiming' to be defined.
+ DelayAfterTrigger: recommended
+
+# fMRI task information
+MRIFuncTaskInformation:
+ selectors:
+ - datatype == "func"
+ - suffix == "bold"
+ fields:
+ Instructions:
+ level: recommended
+ description_addendum: |
+ This is especially important in context of resting state recordings and
+ distinguishing between eyes open and eyes closed paradigms.
+ TaskDescription: recommended
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+# Should now be `part-phase_bold.nii`, but still require units
+PhaseSuffixUnits:
+ selectors:
+ - datatype == "func"
+ - suffix == "phase"
+ - match(extension, "^\.nii(\.gz)?$")
+ fields:
+ Units: required
diff --git a/bep32v01/ressources/schema/rules/sidecars/ieeg.yaml b/bep32v01/ressources/schema/rules/sidecars/ieeg.yaml
new file mode 100644
index 00000000..066e17a8
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/ieeg.yaml
@@ -0,0 +1,140 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+iEEGHardware:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ Manufacturer:
+ level: recommended
+ description_addendum: For example, `"TDT"`, `"Blackrock"`.
+ ManufacturersModelName: recommended
+ SoftwareVersions: recommended
+ DeviceSerialNumber: recommended
+
+iEEGTaskInformation:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ TaskName:
+ level: required
+ description_addendum: |
+ A recommended convention is to name resting state task using labels
+ beginning with `rest`.
+ TaskDescription: recommended
+ Instructions:
+ level: recommended
+ description_addendum: |
+ This is especially important in context of resting state recordings and
+ distinguishing between eyes open and eyes closed paradigms.
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+iEEGInstitutionInformation:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+# Specific iEEG fields MUST be present
+iEEGRequired:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ iEEGReference: required
+ SamplingFrequency:
+ level: required
+ description_addendum: |
+ The sampling frequency of data channels that deviate from the main sampling
+ frequency SHOULD be specified in the `channels.tsv` file.
+ PowerLineFrequency: required
+ SoftwareFilters: required
+
+# Specific iEEG fields SHOULD be present
+iEEGRecommended:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ DCOffsetCorrection: deprecated
+ HardwareFilters: recommended
+ ElectrodeManufacturer: recommended
+ ElectrodeManufacturersModelName: recommended
+ ECOGChannelCount: recommended
+ SEEGChannelCount: recommended
+ EEGChannelCount: recommended
+ EOGChannelCount: recommended
+ ECGChannelCount: recommended
+ EMGChannelCount: recommended
+ MiscChannelCount: recommended
+ TriggerChannelCount: recommended
+ RecordingDuration: recommended
+ RecordingType: recommended
+ EpochLength: recommended
+ iEEGGround: recommended
+ iEEGPlacementScheme: recommended
+ iEEGElectrodeGroups: recommended
+ SubjectArtefactDescription: recommended
+
+# Specific iEEG fields MAY be present
+iEEGOptional:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "ieeg"
+ fields:
+ ElectricalStimulation: optional
+ ElectricalStimulationParameters: optional
+
+# General fields
+iEEGCoordsystemGeneral:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "coordsystem"
+ fields:
+ IntendedFor__ds_relative:
+ level: optional
+ description_addendum: |
+ If only a surface reconstruction is available, this should point to
+ the surface reconstruction file.
+ Note that this file should have the same coordinate system
+ specified in `iEEGCoordinateSystem`.
+ For example, **T1**: `'bids::sub-/ses-/anat/sub-01_T1w.nii.gz'`
+ **Surface**: `'bids::derivatives/surfaces/sub-/ses-/anat/
+ sub-01_hemi-R_desc-T1w_pial.surf.gii'`
+ **Operative photo**: `'bids::sub-/ses-/ieeg/
+ sub-0001_ses-01_acq-photo1_photo.jpg'`
+ **Talairach**: `'bids::derivatives/surfaces/sub-Talairach/ses-01/anat/
+ sub-Talairach_hemi-R_pial.surf.gii'`
+
+# Fields relating to the iEEG electrode positions
+iEEGCoordsystemPositions:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "coordsystem"
+ fields:
+ iEEGCoordinateSystem: required
+ iEEGCoordinateUnits: required
+ iEEGCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if `iEEGCoordinateSystem` is `"Other"`
+ iEEGCoordinateProcessingDescription: recommended
+ iEEGCoordinateProcessingReference: recommended
+
+iEEGCoordsystemOther:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "coordsystem"
+ - '"iEEGCoordinateSystem" in sidecar'
+ - sidecar.iEEGCoordinateSystem == "Other"
+ fields:
+ iEEGCoordinateSystemDescription: required
diff --git a/bep32v01/ressources/schema/rules/sidecars/meg.yaml b/bep32v01/ressources/schema/rules/sidecars/meg.yaml
new file mode 100644
index 00000000..a989d40f
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/meg.yaml
@@ -0,0 +1,266 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Magnetoencephalography
+#
+# Note: "task" in entities identifies MEG data files and excludes calibration/crosstalk scans
+
+# Sidecar JSON (*_meg.json)
+MEGHardware:
+ selectors:
+ - datatype == "meg"
+ - '"task" in entities'
+ - suffix == "meg"
+ fields:
+ Manufacturer:
+ level: recommended
+ description_addendum: |
+ For MEG scanners, this must be one of:
+ `"CTF"`, `"Elekta/Neuromag"`, `"BTi/4D"`, `"KIT/Yokogawa"`,
+ `"ITAB"`, `"KRISS"`, `"Other"`.
+ See the [MEG Systems Appendix](SPEC_ROOT/appendices/meg-systems.md) for
+ preferred names.
+ ManufacturersModelName:
+ level: recommended
+ description_addendum: |
+ See the [MEG Systems Appendix](SPEC_ROOT/appendices/meg-systems.md) for
+ preferred names.
+ SoftwareVersions: recommended
+ DeviceSerialNumber: recommended
+
+MEGTaskInformation:
+ selectors:
+ - datatype == "meg"
+ - '"task" in entities'
+ - suffix == "meg"
+ fields:
+ TaskName:
+ level: required
+ description_addendum: |
+ A recommended convention is to name resting state task using labels
+ beginning with `rest`.
+ TaskDescription: recommended
+ Instructions:
+ level: recommended
+ description_addendum: |
+ This is especially important in context of resting state recordings and
+ distinguishing between eyes open and eyes closed paradigms.
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+MEGInstitutionInformation:
+ selectors:
+ - datatype == "meg"
+ - '"task" in entities'
+ - suffix == "meg"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+# Specific MEG fields MUST be present
+MEGRequired:
+ selectors:
+ - datatype == "meg"
+ - '"task" in entities'
+ - suffix == "meg"
+ fields:
+ SamplingFrequency:
+ level: required
+ description_addendum: |
+ The sampling frequency of data channels that deviate from the main sampling
+ frequency SHOULD be specified in the `channels.tsv` file.
+ PowerLineFrequency: required
+ DewarPosition: required
+ SoftwareFilters: required
+ DigitizedLandmarks: required
+ DigitizedHeadPoints: required
+
+# Specific MEG fields SHOULD be present
+MEGRecommended:
+ selectors:
+ - datatype == "meg"
+ - '"task" in entities'
+ - suffix == "meg"
+ fields:
+ MEGChannelCount: recommended
+ MEGREFChannelCount: recommended
+ EEGChannelCount: recommended
+ ECOGChannelCount: recommended
+ SEEGChannelCount: recommended
+ EOGChannelCount: recommended
+ ECGChannelCount: recommended
+ EMGChannelCount: recommended
+ MiscChannelCount: recommended
+ TriggerChannelCount: recommended
+ RecordingDuration: recommended
+ RecordingType: recommended
+ EpochLength: recommended
+ ContinuousHeadLocalization: recommended
+ HeadCoilFrequency: recommended
+ MaxMovement: recommended
+ SubjectArtefactDescription: recommended
+ AssociatedEmptyRoom: recommended
+ HardwareFilters: recommended
+
+# Specific MEG fields MAY be present
+MEGOptional:
+ selectors:
+ - datatype == "meg"
+ - suffix == "meg"
+ fields:
+ ElectricalStimulation: optional
+ ElectricalStimulationParameters: optional
+
+# Specific EEG fields
+# NOTE: I'm not sure if "EEG is present" is enough to indicate simultaneous EEG/MEG.
+MEGwithEEG:
+ selectors:
+ - datatype == "meg"
+ - suffix == "meg"
+ - intersects(dataset.modalities, ["eeg"])
+ fields:
+ EEGPlacementScheme: optional
+ CapManufacturer: optional
+ CapManufacturersModelName: optional
+ EEGReference: optional
+
+# MEG and EEG sensors
+MEGCoordsystemWithEEG:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ fields:
+ MEGCoordinateSystem: required
+ MEGCoordinateUnits: required
+ MEGCoordinateSystemDescription:
+ level: optional
+ level_addendum: required if `MEGCoordinateSystem` is `Other`
+ EEGCoordinateSystem:
+ level: optional
+ description_addendum: |
+ See [Recording EEG simultaneously with MEG]
+ (/modality-specific-files/magnetoencephalography.html#recording-eeg-simultaneously-with-meg).
+ Preferably the same as the `MEGCoordinateSystem`.
+ EEGCoordinateUnits: optional
+ EEGCoordinateSystemDescription:
+ level: optional
+ level_addendum: required if `EEGCoordinateSystem` is `Other`
+ description_addendum: |
+ See [Recording EEG simultaneously with MEG]
+ (/modality-specific-files/magnetoencephalography.html#recording-eeg-simultaneously-with-meg).
+
+# NOTE: The JSON isn't really a sidecar, so "sidecar.MEGCoordinateSystem" is misleading.
+MEGCoordsystemWithEEGMEGCoordinateSystem:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - '"MEGCoordinateSystem" in sidecar'
+ - sidecar.MEGCoordinateSystem == "Other"
+ fields:
+ MEGCoordinateSystemDescription: required
+
+# NOTE: Not sure if this requires simult. EEG
+MEGCoordsystemWithEEGEEGCoordinateSystem:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - '"EEGCoordinateSystem" in sidecar'
+ - sidecar.EEGCoordinateSystem == "Other"
+ fields:
+ EEGCoordinateSystemDescription: required
+
+# Head localization coils
+MEGCoordsystemHeadLocalizationCoils:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ fields:
+ HeadCoilCoordinates: optional
+ HeadCoilCoordinateSystem: optional
+ HeadCoilCoordinateUnits: optional
+ HeadCoilCoordinateSystemDescription:
+ level: optional
+ level_addendum: required if `HeadCoilCoordinateSystem` is `Other`
+
+MEGCoordsystemHeadLocalizationCoilsHeadCoilCoordinateSystem:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - '"HeadCoilCoordinateSystem" in sidecar'
+ - sidecar.HeadCoilCoordinateSystem == "Other"
+ fields:
+ HeadCoilCoordinateSystemDescription: required
+
+# Digitized head points
+MEGCoordsystemDigitizedHeadPoints:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ fields:
+ DigitizedHeadPoints: optional
+ DigitizedHeadPointsCoordinateSystem: optional
+ DigitizedHeadPointsCoordinateUnits: optional
+ DigitizedHeadPointsCoordinateSystemDescription:
+ level: optional
+ level_addendum: required if `DigitizedHeadPointsCoordinateSystem` is `Other`
+
+MEGCoordsystemDigitizedHeadPointsDigitizedHeadPointsCoordinateSystem:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - '"DigitizedHeadPointsCoordinateSystem" in sidecar'
+ - sidecar.DigitizedHeadPointsCoordinateSystem == "Other"
+ fields:
+ DigitizedHeadPointsCoordinateSystemDescription: required
+
+# Anatomical MRI
+MEGCoordsystemAnatomicalMRI:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - intersects(dataset.datatypes, ["anat"])
+ fields:
+ IntendedFor:
+ level: optional
+ description_addendum: |
+ This is used to identify the structural MRI(s),
+ possibly of different types if a list is specified,
+ to be used with the MEG recording.
+
+# Anatomical landmarks
+MEGCoordsystemAnatomicalLandmarks:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ fields:
+ AnatomicalLandmarkCoordinates: optional
+ AnatomicalLandmarkCoordinateSystem:
+ level: optional
+ description_addendum: |
+ Preferably the same as the `MEGCoordinateSystem`.
+ AnatomicalLandmarkCoordinateUnits: optional
+ AnatomicalLandmarkCoordinateSystemDescription:
+ level: optional
+ level_addendum: required if `AnatomicalLandmarkCoordinateSystem` is `Other`
+
+MEGCoordsystemAnatomicalLandmarksAnatomicalLandmarkCoordinateSystem:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ - '"AnatomicalLandmarkCoordinateSystem" in sidecar'
+ - sidecar.AnatomicalLandmarkCoordinateSystem == "Other"
+ fields:
+ AnatomicalLandmarkCoordinateSystemDescription: required
+
+# Fiducials information
+MEGCoordsystemFiducialsInformation:
+ selectors:
+ - datatype == "meg"
+ - suffix == "coordsystem"
+ fields:
+ FiducialsDescription: optional
diff --git a/bep32v01/ressources/schema/rules/sidecars/micr.yaml b/bep32v01/ressources/schema/rules/sidecars/micr.yaml
new file mode 100644
index 00000000..f2f49095
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/micr.yaml
@@ -0,0 +1,100 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# Device Hardware
+MicroscopyHardware:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ fields:
+ Manufacturer: recommended
+ ManufacturersModelName: recommended
+ DeviceSerialNumber: recommended
+ StationName: recommended
+ SoftwareVersions: recommended
+
+MicroscopyInstitutionInformation:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+# Image Acquisition
+MicroscopyImageAcquisition:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ fields:
+ PixelSize: required
+ PixelSizeUnits: required
+ Immersion: optional
+ NumericalAperture: optional
+ Magnification: optional
+ ImageAcquisitionProtocol: optional
+ OtherAcquisitionParameters: optional
+
+# Sample
+MicroscopySample:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ fields:
+ BodyPart:
+ level: recommended
+ description_addendum: |
+ From [DICOM Body Part
+ Examined](https://dicom.nema.org/medical/dicom/current/output/chtml/part16/chapter_L.html#chapter_L)
+ (for example `"BRAIN"`).
+ BodyPartDetails: recommended
+ BodyPartDetailsOntology: optional
+ SampleEnvironment: recommended
+ SampleEmbedding: optional
+ SampleFixation: optional
+ SampleStaining: recommended
+ SamplePrimaryAntibody: recommended
+ SampleSecondaryAntibody: recommended
+ SliceThickness: optional
+ TissueDeformationScaling: optional
+ SampleExtractionProtocol: optional
+ SampleExtractionInstitution: optional
+
+# Chunk Transformations
+MicroscopyChunkTransformations:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ - '"chunk" in entities'
+ fields:
+ ChunkTransformationMatrix:
+ level: recommended
+ level_addendum: if `chunk-` is used in filenames
+
+MicroscopyChunkTransformationsMatrixAxis:
+ selectors:
+ - datatype == "micr"
+ - suffix != "photo"
+ - '"chunk" in entities'
+ - '"ChunkTransformationMatrix" in sidecar'
+ fields:
+ ChunkTransformationMatrixAxis:
+ level: required
+ level_addendum: if `ChunkTransformationMatrix` is present
+
+Photo:
+ selectors:
+ - datatype == "micr"
+ - suffix == "photo"
+ fields:
+ PhotoDescription: optional
+ IntendedFor:
+ level: optional
+ description_addendum: |
+ This field is OPTIONAL, in case the photos do not correspond
+ to any particular images, it does not have to be filled.
diff --git a/bep32v01/ressources/schema/rules/sidecars/motion.yaml b/bep32v01/ressources/schema/rules/sidecars/motion.yaml
new file mode 100644
index 00000000..2a3630f7
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/motion.yaml
@@ -0,0 +1,76 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+motionHardware:
+ selectors:
+ - datatype == "motion"
+ - suffix == "motion"
+ fields:
+ DeviceSerialNumber: recommended
+ Manufacturer: recommended
+ ManufacturersModelName: recommended
+ SoftwareVersions: recommended
+
+motionInstitutionInformation:
+ selectors:
+ - datatype == "motion"
+ - suffix == "motion"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+motionTaskInformation:
+ selectors:
+ - datatype == "motion"
+ - suffix == "motion"
+ fields:
+ TaskName:
+ level: required
+ description_addendum: |
+ Task names for motion datasets usually contain information
+ about the specific motion task (for example, "`walking`").
+ TaskDescription: recommended
+ Instructions: recommended
+
+motionRequired:
+ selectors:
+ - datatype == "motion"
+ - suffix == "motion"
+ fields:
+ SamplingFrequency:
+ level: required
+ description_addendum: |
+ This field refers to the nominal sampling frequency. For motion data one can use
+ "`SamplingFrequencyEffective`" if nominal and effective differ.
+ The sampling frequency of data channels that deviate from the main (nominal) sampling
+ frequency SHOULD be specified in the "`_tracksys-_channels.tsv`" file.
+
+motionRecommended:
+ selectors:
+ - datatype == "motion"
+ - suffix == "motion"
+ fields:
+ ACCELChannelCount: recommended
+ ANGACCELChannelCount: recommended
+ GYROChannelCount: recommended
+ JNTANGChannelCount: recommended
+ LATENCYChannelCount: recommended
+ MAGNChannelCount: recommended
+ MISCChannelCount: recommended
+ MissingValues: recommended
+ MotionChannelCount: recommended
+ ORNTChannelCount: recommended
+ POSChannelCount: recommended
+ SamplingFrequencyEffective:
+ level: recommended
+ description_addendum: |
+ If not available, the field takes value `n/a`.
+ SubjectArtefactDescription: recommended
+ TrackedPointsCount: recommended
+ TrackingSystemName: optional
+ VELChannelCount: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/mri.yaml b/bep32v01/ressources/schema/rules/sidecars/mri.yaml
new file mode 100644
index 00000000..d9967c13
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/mri.yaml
@@ -0,0 +1,315 @@
+#
+# Groups of related metadata fields
+#
+# Assumptions: never need disjunction of selectors
+# Assumptions: top-to-bottom overrides is sufficient logic
+
+---
+# MRI Common metadata fields
+MRIHardware:
+ selectors:
+ - modality == "mri"
+ fields:
+ Manufacturer:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 0070 `Manufacturer`.
+ ManufacturersModelName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 1090 `Manufacturers Model Name`.
+ DeviceSerialNumber:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0018, 1000 `DeviceSerialNumber`.
+ StationName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 1010 `Station Name`.
+ SoftwareVersions:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0018, 1020 `Software Versions`.
+ HardcopyDeviceSoftwareVersion: DEPRECATED
+ MagneticFieldStrength:
+ level: recommended, but required for Arterial Spin Labeling
+ ReceiveCoilName: recommended
+ ReceiveCoilActiveElements: recommended
+ GradientSetType: recommended
+ MRTransmitCoilSequence: recommended
+ MatrixCoilMode: recommended
+ CoilCombinationMethod: recommended
+
+MRISample:
+ selectors:
+ - modality == "mri"
+ fields:
+ BodyPart:
+ level: optional
+ description_addendum: Corresponds to DICOM Tag 0018, 0015 `Body Part Examined`.
+ BodyPartDetails: optional
+ BodyPartDetailsOntology: optional
+
+MRIScannerHardwareASL:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ - intersects([suffix], ["asl", "m0scan"])
+ fields:
+ MagneticFieldStrength: required
+
+MRISequenceSpecifics:
+ selectors:
+ - modality == "mri"
+ fields:
+ PulseSequenceType: recommended
+ ScanningSequence: recommended
+ SequenceVariant: recommended
+ ScanOptions: recommended
+ SequenceName: recommended
+ PulseSequenceDetails: recommended
+ NonlinearGradientCorrection: |
+ recommended, but required if [PET](./positron-emission-tomography.md) data are present
+ MRAcquisitionType: recommended, but required for Arterial Spin Labeling
+ MTState: recommended
+ MTOffsetFrequency: optional
+ MTPulseBandwidth: optional
+ MTNumberOfPulses: optional
+ MTPulseShape: optional
+ MTPulseDuration: optional
+ SpoilingState: recommended
+ SpoilingType: optional
+ SpoilingRFPhaseIncrement: optional
+ SpoilingGradientMoment: optional
+ SpoilingGradientDuration: optional
+
+PETMRISequenceSpecifics:
+ selectors:
+ - modality == "mri"
+ - intersects(dataset.modalities, ["pet"])
+ fields:
+ NonlinearGradientCorrection: required
+
+ASLMRISequenceSpecifics:
+ selectors:
+ - datatype == "perf"
+ - suffix == "asl"
+ fields:
+ MRAcquisitionType: required
+
+MTParameters:
+ selectors:
+ - sidecar.MTState == true
+ fields:
+ MTOffsetFrequency: recommended
+ MTPulseBandwidth: recommended
+ MTNumberOfPulses: recommended
+ MTPulseShape: recommended
+ MTPulseDuration: recommended
+
+SpoilingType:
+ selectors:
+ - sidecar.SpoilingState == true
+ fields:
+ SpoilingType: recommended
+
+SpoilingRF:
+ selectors:
+ - intersects([sidecar.SpoilingType], ["RF", "COMBINED"])
+ fields:
+ SpoilingRFPhaseIncrement: recommended
+
+SpoilingGradient:
+ selectors:
+ - intersects([sidecar.SpoilingType], ["GRADIENT", "COMBINED"])
+ fields:
+ SpoilingGradientMoment: recommended
+ SpoilingGradientDuration: recommended
+
+MRISpatialEncoding:
+ selectors:
+ - modality == "mri"
+ fields:
+ NumberShots: recommended
+ ParallelReductionFactorInPlane: recommended
+ ParallelReductionFactorOutOfPlane: recommended
+ ParallelAcquisitionTechnique: recommended
+ PartialFourier: recommended
+ PartialFourierDirection: recommended
+ EffectiveEchoSpacing:
+ level: recommended
+ level_addendum: required if corresponding fieldmap data present
+ description_addendum: 2
+ MixingTime: recommended
+
+PhaseEncodingDirectionRec:
+ selectors:
+ - modality == "mri"
+ - suffix != "epi"
+ fields:
+ PhaseEncodingDirection:
+ level: recommended
+ level_addendum: |
+ required if corresponding fieldmap data is present
+ or when using multiple runs with different phase encoding directions
+ (which can be later used for field inhomogeneity correction).
+ TotalReadoutTime:
+ level: recommended
+ level_addendum: |
+ required if corresponding 'field/distortion' maps
+ acquired with opposing phase encoding directions are present
+ (see [Case 4: Multiple phase encoded
+ directions](#case-4-multiple-phase-encoded-directions-pepolar))
+
+PhaseEncodingDirectionReq:
+ selectors:
+ - modality == "mri"
+ - suffix == "epi"
+ fields:
+ PhaseEncodingDirection:
+ level: required
+ issue:
+ name: PHASE_ENCODING_DIRECTION_MUST_DEFINE
+ issue: |
+ You have to define 'PhaseEncodingDirection' for this file.
+ TotalReadoutTime:
+ level: required
+ description_addendum: 3
+ issue:
+ name: TOTAL_READOUT_TIME_MUST_DEFINE
+ message: |
+ You have to define 'TotalReadoutTime' for this file.
+
+MRITimingParameters:
+ selectors:
+ - modality == "mri"
+ 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:
+ name: 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
+
+SliceTimingMRI:
+ selectors:
+ - modality == "mri"
+ - sidecar.MRAcquisitionType == "2D"
+ fields:
+ SliceTiming:
+ level: recommended
+ level_addendum: |
+ required for sparse sequences that do not have the `DelayTime` field set,
+ and Arterial Spin Labeling with `MRAcquisitionType` set on `2D`.
+ SliceEncodingDirection: recommended
+
+SliceTimingASL:
+ selectors:
+ - datatype == "perf"
+ - intersects([suffix], ["asl", "m0scan"])
+ - sidecar.MRAcquisitionType == "2D"
+ fields:
+ EchoTime: required
+ SliceTiming:
+ level: required
+ issue:
+ code: SLICE_TIMING_NOT_DEFINED_2D_ASL
+ message: |
+ You should define `SliceTiming` for this file, because `SequenceType` is set
+ to a 2D sequence. `SliceTiming` is the time at which each slice was
+ acquired within each volume (frame) of the acquisition. Slice timing
+ is not slice order -- rather, it is a list of times containing the
+ time (in seconds) of each slice acquisition in relation to the beginning
+ of volume acquisition. The list goes through the slices along the slice
+ axis in the slice encoding dimension (see below). Note that to ensure the
+ proper interpretation of the `SliceTiming` field, it is important to check
+ if the optional `SliceEncodingDirection` exists. In particular, if
+ `SliceEncodingDirection` is negative, the entries in `SliceTiming` are
+ defined in reverse order with respect to the slice axis, such that the
+ 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"
+ fields:
+ NegativeContrast: optional
+
+MRIFlipAngleLookLockerFalse:
+ selectors:
+ - modality == "mri"
+ - sidecar.LookLocker != true
+ fields:
+ FlipAngle:
+ level: recommended
+ level_addendum: required if LookLocker is set to `true`
+
+MRIFlipAngleLookLockerTrue:
+ selectors:
+ - modality == "mri"
+ - sidecar.LookLocker == true
+ fields:
+ FlipAngle:
+ level: required
+ issue:
+ name: LOOK_LOCKER_FLIP_ANGLE_MISSING
+ message: |
+ You should define 'FlipAngle' for this file, in
+ case of a LookLocker acquisition. 'FlipAngle' is the
+ flip angle (FA) for the acquisition, specified in degrees.
+ Corresponds to: DICOM Tag 0018, 1314 `Flip Angle`. 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
+ flip 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 flip angle fMRI sequences.
+
+MRISliceAcceleration:
+ selectors:
+ - modality == "mri"
+ fields:
+ MultibandAccelerationFactor: recommended
+
+MRIAnatomicalLandmarks:
+ selectors:
+ - modality == "mri"
+ fields:
+ AnatomicalLandmarkCoordinates__mri: recommended
+
+MRIEchoPlanarImagingAndB0Mapping:
+ selectors:
+ - modality == "mri"
+ fields:
+ B0FieldIdentifier: recommended
+ B0FieldSource: recommended
+
+MRIInstitutionInformation:
+ selectors:
+ - modality == "mri"
+ fields:
+ InstitutionName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 0080 `InstitutionName`.
+ InstitutionAddress:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 0081 `InstitutionAddress`.
+ InstitutionalDepartmentName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 1040 `Institutional Department Name`.
diff --git a/bep32v01/ressources/schema/rules/sidecars/nirs.yaml b/bep32v01/ressources/schema/rules/sidecars/nirs.yaml
new file mode 100644
index 00000000..de84a855
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/nirs.yaml
@@ -0,0 +1,180 @@
+---
+CoordinateSystem:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ fields:
+ NIRSCoordinateSystem: required
+ NIRSCoordinateUnits: required
+ NIRSCoordinateProcessingDescription: recommended
+
+Fiducials:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ fields:
+ FiducialsDescription: optional
+ FiducialsCoordinates: recommended
+ FiducialsCoordinateUnits: recommended
+ FiducialsCoordinateSystem: recommended
+
+AnatomicalLandmark:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ fields:
+ AnatomicalLandmarkCoordinates: recommended
+ AnatomicalLandmarkCoordinateSystem: recommended
+ AnatomicalLandmarkCoordinateUnits: recommended
+
+CoordsystemGeneral:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ fields:
+ IntendedFor:
+ level: optional
+ description_addendum: |
+ This identifies the MRI or CT scan associated with the optodes,
+ landmarks, and fiducials.
+
+CoordinateSystemDescriptionRec:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.NIRSCoordinateSystem != "other"
+ fields:
+ NIRSCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if NIRSCoordinateSystem is "other"
+
+CoordinateSystemDescriptionReq:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.NIRSCoordinateSystem == "other"
+ fields:
+ NIRSCoordinateSystemDescription: required
+
+AnatomicalLandmarkCoordinateSystemDescriptionRec:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.AnatomicalLandmarkCoordinateSystem != "other"
+ fields:
+ AnatomicalLandmarkCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if NIRSCoordinateSystem is "other"
+
+AnatomicalLandmarkCoordinateSystemDescriptionReq:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.AnatomicalLandmarkCoordinateSystem == "other"
+ fields:
+ AnatomicalLandmarkCoordinateSystemDescription: required
+
+FiducialsCoordinateSystemDescriptionRec:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.FiducialsCoordinateSystem != "other"
+ fields:
+ FiducialsCoordinateSystemDescription:
+ level: recommended
+ level_addendum: required if FiducialsCoordinateSystem is "other"
+
+FiducialsCoordinateSystemDescriptionReq:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "coordsystem"
+ - json.FiducialsCoordinateSystem == "other"
+ fields:
+ FiducialsCoordinateSystemDescription: required
+
+NirsHardware:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ Manufacturer: recommended
+ ManufacturersModelName: recommended
+ SoftwareVersions: recommended
+ DeviceSerialNumber: recommended
+
+NirsBase:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ RecordingDuration: recommended
+ HeadCircumference: recommended
+ HardwareFilters: recommended
+ SubjectArtefactDescription: recommended
+
+NirsTaskInformation:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ TaskName: required
+ TaskDescription: recommended
+ Instructions: recommended
+ CogAtlasID: recommended
+ CogPOID: recommended
+
+NirsInstitutionInformation:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ InstitutionName: recommended
+ InstitutionAddress: recommended
+ InstitutionalDepartmentName: recommended
+
+NirsRequired:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ SamplingFrequency__nirs:
+ level: required
+ description_addendum: |
+ Sampling frequency (in Hz) of all the data in the recording, regardless of their type (for example, `12`). If
+ individual channels have different sampling rates, then the field here MUST be specified as `n/a` and the
+ values MUST be specified in the `sampling_frequency` column in channels.tsv.")
+ NIRSChannelCount: required
+ NIRSSourceOptodeCount: required
+ NIRSDetectorOptodeCount: required
+ # Following counts required conditions enforced in checks
+ ACCELChannelCount:
+ level: optional
+ level_addendum: required if any channel type is ACCEL
+ GYROChannelCount:
+ level: optional
+ level_addendum: required if any channel type is GYRO
+ MAGNChannelCount:
+ level: optional
+ level_addendum: required if any channel type is MAGN
+
+NirsRecommend:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "nirs"
+ fields:
+ CapManufacturer:
+ level: recommended
+ description_addendum: |
+ If no cap was used, such as with optodes
+ that are directly taped to the scalp, then the string `none` MUST be used and the `NIRSPlacementScheme` field
+ MAY be used to specify the optode placement.
+ CapManufacturersModelName:
+ level: recommended
+ description_addendum: |
+ If there is no official model number then a description may be provided (for example, `Headband with print
+ (S-M)`). If a cap from a manufacturer was modified, then the field MUST be set to `custom`. If no cap
+ was used, then the `CapManufacturer` field MUST be `none` and this field MUST be `n/a`.")
+ SourceType: recommended
+ DetectorType: recommended
+ ShortChannelCount: recommended
+ NIRSPlacementScheme: recommended
diff --git a/bep32v01/ressources/schema/rules/sidecars/pet.yaml b/bep32v01/ressources/schema/rules/sidecars/pet.yaml
new file mode 100644
index 00000000..dc4ff9a5
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/sidecars/pet.yaml
@@ -0,0 +1,278 @@
+---
+# PET common metadata fields
+PETHardware:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ Manufacturer:
+ level: required
+ description_addendum: Corresponds to DICOM Tag 0008, 0070 `Manufacturer`.
+ ManufacturersModelName:
+ level: required
+ description_addendum: Corresponds to DICOM Tag 0008, 1090 `Manufacturers Model Name`.
+ Units:
+ level: required
+ description_addendum: |
+ SI unit for radioactivity (Becquerel) should be used (for example, "Bq/mL").
+ Corresponds to DICOM Tag 0054, 1001 `Units`.
+ BodyPart:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0018, 0015 `Body Part Examined`.
+
+PETInstitutionInformation:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ InstitutionName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 0080 `InstitutionName`.
+ InstitutionAddress:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 0081 `InstitutionAddress`.
+ InstitutionalDepartmentName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag 0008, 1040 `Institutional Department Name`.
+
+PETSample:
+ selectors:
+ - modality == "pet"
+ - suffix == "pet"
+ fields:
+ BodyPart:
+ level: optional
+ description_addendum: Corresponds to DICOM Tag 0018, 0015 `Body Part Examined`.
+ BodyPartDetails: optional
+ BodyPartDetailsOntology: optional
+
+PETRadioChemistry:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ TracerName:
+ level: required
+ description_addendum: |
+ Corresponds to DICOM Tags (0008,0105) `Mapping Resource` and
+ (0008,0122) `Mapping Resource Name`.
+ TracerRadionuclide:
+ level: required
+ description_addendum: |
+ Corresponds to DICOM Tags (0008,0104) `CodeValue` and (0008,0104) `CodeMeaning`.
+ InjectedRadioactivity: required
+ InjectedRadioactivityUnits: required
+ InjectedMass: required
+ InjectedMassUnits: required
+ SpecificRadioactivity: required
+ SpecificRadioactivityUnits: required
+ ModeOfAdministration: required
+ TracerRadLex: recommended
+ TracerSNOMED: recommended
+ TracerMolecularWeight: recommended
+ TracerMolecularWeightUnits: recommended
+ InjectedMassPerWeight: recommended
+ InjectedMassPerWeightUnits: recommended
+ SpecificRadioactivityMeasTime: recommended
+ MolarActivity: recommended
+ MolarActivityUnits: recommended
+ MolarActivityMeasTime: recommended
+ InfusionRadioactivity:
+ level: recommended
+ level_addendum: required if ModeOfAdministration is `'bolus-infusion'`
+ InfusionStart:
+ level: recommended
+ level_addendum: required if ModeOfAdministration is `'bolus-infusion'`
+ InfusionSpeed:
+ level: recommended
+ level_addendum: required if ModeOfAdministration is `'bolus-infusion'`
+ InfusionSpeedUnits:
+ level: recommended
+ level_addendum: required if ModeOfAdministration is `'bolus-infusion'`
+ InjectedVolume:
+ level: recommended
+ level_addendum: required if ModeOfAdministration is `'bolus-infusion'`
+ Purity: recommended
+
+# PET Infusion conditionally required entities
+EntitiesBolusMetadata:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ - sidecar.ModeOfAdministration == 'bolus-infusion'
+ fields:
+ InfusionRadioactivity: required
+ InfusionStart: required
+ InfusionSpeed: required
+ InfusionSpeedUnits: required
+ InjectedVolume: required
+
+PETPharmaceuticals:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ PharmaceuticalName:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag (0008,0034) `Intervention Drug Name`.
+ PharmaceuticalDoseAmount:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag (0008,0028) `Intervention Drug Dose`.
+ PharmaceuticalDoseUnits: recommended
+ PharmaceuticalDoseRegimen: recommended
+ PharmaceuticalDoseTime:
+ level: recommended
+ description_addendum: |
+ Corresponds to a combination of DICOM Tags (0008,0027) `Intervention Drug Stop Time`
+ and (0008,0035) `Intervention Drug Start Time`.
+ Anaesthesia: optional
+
+PETTime:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ TimeZero: required
+ ScanStart: required
+ InjectionStart:
+ level: required
+ description_addendum: Corresponds to DICOM Tag (0018,1072) `Radiopharmaceutical Start Time`.
+ FrameTimesStart: required
+ FrameDuration: required
+ InjectionEnd:
+ level: recommended
+ description_addendum: |
+ Corresponds to DICOM Tag (0018,1073) `Radiopharmaceutical Stop Time`
+ converted to seconds relative to TimeZero.
+ ScanDate:
+ level: deprecated
+ description_addendum: Corresponds to DICOM Tag (0008,0022) `Acquisition Date`.
+
+PETReconstruction:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ fields:
+ AcquisitionMode: required
+ ImageDecayCorrected: required
+ ImageDecayCorrectionTime: required
+ ReconMethodName:
+ level: required
+ description_addendum: This partly matches the DICOM Tag (0054,1103) `Reconstruction Method`.
+ ReconMethodParameterLabels:
+ level: required
+ description_addendum: This partly matches the DICOM Tag (0054,1103) `Reconstruction Method`.
+ ReconMethodParameterUnits:
+ level: recommended
+ level_addendum: required if `ReconMethodParameterLabels` does not contain `"none"`
+ description_addendum: This partly matches the DICOM Tag (0054,1103) `Reconstruction Method`.
+ ReconMethodParameterValues:
+ level: recommended
+ level_addendum: required if `ReconMethodParameterLabels` does not contain `"none"`
+ description_addendum: This partly matches the DICOM Tag (0054,1103) `Reconstruction Method`.
+ ReconFilterType:
+ level: required
+ description_addendum: This partly matches the DICOM Tag (0018,1210) `Convolution Kernel`.
+ ReconFilterSize:
+ level: recommended
+ level_addendum: required if `ReconFilterType` is not `"none"`
+ description_addendum: This partly matches the DICOM Tag (0018,1210) `Convolution Kernel`.
+ AttenuationCorrection:
+ level: required
+ description_addendum: This corresponds to DICOM Tag (0054,1101) `Attenuation Correction Method`.
+ ReconMethodImplementationVersion: recommended
+ AttenuationCorrectionMethodReference: recommended
+ ScaleFactor: recommended
+ ScatterFraction:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag (0054,1323) `Scatter Fraction Factor`.
+ DecayCorrectionFactor:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag (0054,1321) `Decay Factor`.
+ DoseCalibrationFactor:
+ level: recommended
+ description_addendum: Corresponds to DICOM Tag (0054,1322) `Dose Calibration Factor`.
+ PromptRate: recommended
+ SinglesRate: recommended
+ RandomRate: recommended
+
+# set required reconstruction fields to optional when "none" is provided as a parameter label
+EntitiesReconMethodMetadata:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ - '!intersects(sidecar.ReconMethodParameterLabels, ["none"])'
+ fields:
+ ReconMethodParameterValues: required
+ ReconMethodParameterUnits: required
+
+# set required recon filter fields to optional when FilterType is "None"
+EntitiesReconFilterMetadata:
+ selectors:
+ - datatype == "pet"
+ - suffix == "pet"
+ - '!intersects(sidecar.ReconFilterType, ["none"])'
+ fields:
+ ReconFilterSize: required
+
+BloodRecording:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ fields:
+ PlasmaAvail: required
+ MetaboliteAvail: required
+ WholeBloodAvail: required
+ DispersionCorrected: required
+ WithdrawalRate: recommended
+ TubingType: recommended
+ TubingLength: recommended
+ DispersionConstant: recommended
+ Haematocrit: recommended
+ BloodDensity: recommended
+
+BloodPlasmaFreeFraction:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - sidecar.PlasmaAvail == true
+ fields:
+ PlasmaFreeFraction:
+ level: recommended
+ level_addendum: if `PlasmaAvail` is `true`
+ PlasmaFreeFractionMethod:
+ level: recommended
+ level_addendum: if `PlasmaAvail` is `true`
+
+BloodMetaboliteMethod:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - sidecar.MetaboliteAvail == true
+ fields:
+ MetaboliteMethod:
+ level: required
+ level_addendum: if `MetaboliteAvail` is `true`
+ MetaboliteRecoveryCorrectionApplied:
+ level: required
+ level_addendum: if `MetaboliteAvail` is `true`
+
+# PET task information
+PETTask:
+ selectors:
+ - datatype == "pet"
+ - '"task" in entities'
+ fields:
+ TaskName:
+ level: recommended
+ description_addendum: |
+ If used to denote resting scans, a RECOMMENDED convention is to use labels
+ beginning with `rest`.
+ Instructions:
+ level: recommended
+ description_addendum: |
+ This is especially important in context of resting state recordings
+ and distinguishing between eyes open and eyes closed paradigms.
+ TaskDescription: recommended
+ CogAtlasID: recommended
+ CogPOID: recommended
diff --git a/bep32v01/ressources/schema/rules/tabular_data/derivatives/common_derivatives.yaml b/bep32v01/ressources/schema/rules/tabular_data/derivatives/common_derivatives.yaml
new file mode 100644
index 00000000..3fef5e88
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/derivatives/common_derivatives.yaml
@@ -0,0 +1,12 @@
+---
+SegmentationLookup:
+ selectors:
+ - dataset.dataset_description.DatasetType == "derivative"
+ - intersects([suffix], ["dseg", "probseg"])
+ columns:
+ index: required
+ name__segmentations: required
+ abbreviation: optional
+ color: optional
+ mapping: optional
+ index_columns: [index]
diff --git a/bep32v01/ressources/schema/rules/tabular_data/eeg.yaml b/bep32v01/ressources/schema/rules/tabular_data/eeg.yaml
new file mode 100644
index 00000000..ae31c5f6
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/eeg.yaml
@@ -0,0 +1,45 @@
+---
+EEGChannels:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - type__channels
+ - units
+ columns:
+ name__channels: required
+ type__channels: required
+ units: required
+ description: optional
+ sampling_frequency: optional
+ reference__eeg: optional
+ low_cutoff: optional
+ high_cutoff: optional
+ notch: optional
+ status: optional
+ status_description: optional
+ index_columns: [name__channels]
+ additional_columns: allowed_if_defined
+
+EEGElectrodes:
+ selectors:
+ - datatype == "eeg"
+ - suffix == "electrodes"
+ - extension == ".tsv"
+ initial_columns:
+ - name__electrodes
+ - x
+ - y
+ - z
+ columns:
+ name__electrodes: required
+ x: required
+ y: required
+ z: required
+ type__electrodes: recommended
+ material: recommended
+ impedance: recommended
+ index_columns: [name__electrodes]
+ additional_columns: allowed_if_defined
diff --git a/bep32v01/ressources/schema/rules/tabular_data/ieeg.yaml b/bep32v01/ressources/schema/rules/tabular_data/ieeg.yaml
new file mode 100644
index 00000000..ad40a980
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/ieeg.yaml
@@ -0,0 +1,68 @@
+---
+iEEGChannels:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - type__channels
+ - units
+ - low_cutoff
+ - high_cutoff
+ columns:
+ name__channels:
+ level: required
+ description_addendum: |
+ When a corresponding electrode is specified in `_electrodes.tsv`,
+ the name of that electrode MAY be specified here and the reference electrode
+ name MAY be provided in the `reference` column.
+ type__channels: required
+ units: required
+ low_cutoff: required
+ high_cutoff: required
+ reference__ieeg: optional
+ group__channel:
+ level: optional
+ description_addendum: |
+ Note that any groups specified in `_electrodes.tsv` must match those present here.
+ sampling_frequency: optional
+ description: optional
+ notch: optional
+ status: optional
+ status_description: optional
+ index_columns: [name__channels]
+ additional_columns: allowed_if_defined
+
+iEEGElectrodes:
+ selectors:
+ - datatype == "ieeg"
+ - suffix == "electrodes"
+ - extension == ".tsv"
+ initial_columns:
+ - name__electrodes
+ - x
+ - y
+ - z
+ - size
+ columns:
+ name__electrodes: required
+ x: required
+ y: required
+ z:
+ level: required
+ description_addendum: |
+ If electrodes are in 2D space this should be a column of `n/a` values.
+ size: required
+ material: recommended
+ manufacturer: recommended
+ group__channel:
+ level: recommended
+ description_addendum: |
+ Note that any group specified here should match a group specified in `_channels.tsv`.
+ hemisphere: recommended
+ type__electrodes: optional
+ impedance: optional
+ dimension: optional
+ index_columns: [name__electrodes]
+ additional_columns: allowed_if_defined
diff --git a/bep32v01/ressources/schema/rules/tabular_data/meg.yaml b/bep32v01/ressources/schema/rules/tabular_data/meg.yaml
new file mode 100644
index 00000000..ff8e5a75
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/meg.yaml
@@ -0,0 +1,24 @@
+---
+MEGChannels:
+ selectors:
+ - datatype == "meg"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - type__channels
+ - units
+ columns:
+ name__channels: required
+ type__channels: required
+ units: required
+ description: optional
+ sampling_frequency: optional
+ low_cutoff: optional
+ high_cutoff: optional
+ notch: optional
+ software_filters: optional
+ status: optional
+ status_description: optional
+ index_columns: [name__channels]
+ additional_columns: allowed_if_defined
diff --git a/bep32v01/ressources/schema/rules/tabular_data/modality_agnostic.yaml b/bep32v01/ressources/schema/rules/tabular_data/modality_agnostic.yaml
new file mode 100644
index 00000000..f33f2b59
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/modality_agnostic.yaml
@@ -0,0 +1,62 @@
+---
+Participants:
+ selectors:
+ - path == "participants.tsv"
+ initial_columns:
+ - participant_id
+ columns:
+ participant_id:
+ level: required
+ description_addendum: |
+ There MUST be exactly one row for each participant.
+ species: recommended
+ age: recommended
+ sex: recommended
+ handedness: recommended
+ strain: recommended
+ strain_rrid: recommended
+ index_columns: [participant_id]
+ additional_columns: allowed
+
+Samples:
+ selectors:
+ - path == "samples.tsv"
+ columns:
+ sample_id: required
+ participant_id: required
+ sample_type: required
+ pathology: recommended
+ derived_from: recommended
+ index_columns: [sample_id, participant_id]
+ additional_columns: allowed
+
+Scans:
+ selectors:
+ - suffix == "scans"
+ - extension == ".tsv"
+ initial_columns:
+ - filename
+ columns:
+ filename:
+ level: required
+ description_addendum: |
+ There MUST be exactly one row for each file.
+ acq_time__scans: optional
+ index_columns: [filename]
+ additional_columns: allowed
+
+Sessions:
+ selectors:
+ - suffix == "sessions"
+ - extension == ".tsv"
+ initial_columns:
+ - session_id
+ columns:
+ session_id:
+ level: required
+ description_addendum: |
+ There MUST be exactly one row for each session.
+ acq_time__sessions: optional
+ pathology: recommended
+ index_columns: [session_id]
+ additional_columns: allowed
diff --git a/bep32v01/ressources/schema/rules/tabular_data/motion.yaml b/bep32v01/ressources/schema/rules/tabular_data/motion.yaml
new file mode 100644
index 00000000..3f2f86ae
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/motion.yaml
@@ -0,0 +1,25 @@
+---
+motionChannels:
+ selectors:
+ - datatype == "motion"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - component
+ - type__channels
+ - tracked_point__channels
+ - units__motion
+ columns:
+ name__channels: required
+ component: required
+ type__channels: required
+ tracked_point__channels: required
+ units__motion: required
+ placement__motion: recommended
+ reference_frame: recommended
+ description: optional
+ sampling_frequency: optional
+ status: optional
+ status_description: optional
+ additional_columns: allowed_if_defined
diff --git a/bep32v01/ressources/schema/rules/tabular_data/nirs.yaml b/bep32v01/ressources/schema/rules/tabular_data/nirs.yaml
new file mode 100644
index 00000000..996b5bc5
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/nirs.yaml
@@ -0,0 +1,66 @@
+---
+nirsChannels:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "channels"
+ - extension == ".tsv"
+ initial_columns:
+ - name__channels
+ - type__channels
+ - source__channels
+ - detector__channels
+ - wavelength_nominal
+ - units__nirs
+ columns:
+ name__channels: required
+ type__channels: required
+ source__channels: required
+ detector__channels: required
+ wavelength_nominal: required
+ units__nirs: required
+ sampling_frequency:
+ level: optional
+ level_addendum: required if `SamplingFrequency` is `n/a` in `_nirs.json`
+ component:
+ level: optional
+ level_addendum: required if `type` is `ACCEL`, `GYRO` or `MAGN`
+ wavelength_actual: optional
+ low_cutoff: optional
+ high_cutoff: optional
+ description: optional
+ wavelength_emission_actual: optional
+ short_channel: optional
+ status: optional
+ status_description: optional
+ additional_columns: allowed_if_defined
+
+nirsOptodes:
+ selectors:
+ - datatype == "nirs"
+ - suffix == "optodes"
+ - extension == ".tsv"
+ initial_columns:
+ - name__optodes
+ - type__optodes
+ - x__optodes
+ - y__optodes
+ - z__optodes
+ columns:
+ name__optodes: required
+ type__optodes: required
+ x__optodes: required
+ y__optodes: required
+ z__optodes: required
+ template_x:
+ level: optional
+ level_addendum: required if `x` is `n/a`
+ template_y:
+ level: optional
+ level_addendum: required if `y` is `n/a`
+ template_z:
+ level: optional
+ level_addendum: required if `z` is `n/a`
+ description__optode: optional
+ detector_type: optional
+ source__optodes: optional
+ additional_columns: allowed_if_defined
diff --git a/bep32v01/ressources/schema/rules/tabular_data/perf.yaml b/bep32v01/ressources/schema/rules/tabular_data/perf.yaml
new file mode 100644
index 00000000..a56f5df7
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/perf.yaml
@@ -0,0 +1,8 @@
+---
+ASLContext:
+ selectors:
+ - datatype == "perf"
+ - suffix == "aslcontext"
+ columns:
+ volume_type: required
+ additional_columns: not_allowed
diff --git a/bep32v01/ressources/schema/rules/tabular_data/pet.yaml b/bep32v01/ressources/schema/rules/tabular_data/pet.yaml
new file mode 100644
index 00000000..8410ee84
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/pet.yaml
@@ -0,0 +1,60 @@
+---
+Blood:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - extension == ".tsv"
+ columns:
+ time: required
+ plasma_radioactivity:
+ level: optional
+ level_addendum: required if `PlasmaAvail` is `true`
+ metabolite_parent_fraction:
+ level: optional
+ level_addendum: required if `MetaboliteAvail` is `true`
+ metabolite_polar_fraction:
+ level: optional
+ level_addendum: recommended if `MetaboliteAvail` is `true`
+ hplc_recovery_fractions:
+ level: optional
+ level_addendum: required if `MetaboliteRecoveryCorrectionApplied` is `true`
+ whole_blood_radioactivity:
+ level: optional
+ level_addendum: required if `WholeBloodAvail` is `true`
+
+BloodPlasma:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - extension == ".tsv"
+ - sidecar.PlasmaAvail == true
+ columns:
+ plasma_radioactivity: required
+
+BloodMetabolite:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - extension == ".tsv"
+ - sidecar.MetaboliteAvail == true
+ columns:
+ metabolite_parent_fraction: required
+ metabolite_polar_fraction: recommended
+
+BloodMetaboliteCorrection:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - extension == ".tsv"
+ - sidecar.MetaboliteRecoveryCorrectionApplied == true
+ columns:
+ hplc_recovery_fractions: required
+
+BloodWholeBlood:
+ selectors:
+ - datatype == "pet"
+ - suffix == "blood"
+ - extension == ".tsv"
+ - sidecar.WholeBloodAvail == true
+ columns:
+ whole_blood_radioactivity: required
diff --git a/bep32v01/ressources/schema/rules/tabular_data/physio.yaml b/bep32v01/ressources/schema/rules/tabular_data/physio.yaml
new file mode 100644
index 00000000..272c4b7c
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/physio.yaml
@@ -0,0 +1,9 @@
+---
+PhysioColumns:
+ selectors:
+ - suffix == "physio"
+ columns:
+ cardiac: optional
+ respiratory: optional
+ trigger: optional
+ additional_columns: allowed
diff --git a/bep32v01/ressources/schema/rules/tabular_data/task.yaml b/bep32v01/ressources/schema/rules/tabular_data/task.yaml
new file mode 100644
index 00000000..0ca01afe
--- /dev/null
+++ b/bep32v01/ressources/schema/rules/tabular_data/task.yaml
@@ -0,0 +1,21 @@
+---
+TaskEvents:
+ selectors:
+ - '"task" in entities'
+ - suffix == "events"
+ columns:
+ onset: required
+ duration: required
+ trial_type: optional
+ response_time: optional
+ HED: optional
+ stim_file: optional
+ channel:
+ level: optional
+ description_addendum: |
+ Note that this column only applies to data types where
+ channels are specified, such as EEG, iEEG, MEG or NIRS.
+ additional_columns: allowed
+ initial_columns:
+ - onset
+ - duration
diff --git a/bep32v01/tests/__init__.py b/bep32v01/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/elab_bridge/Datastructures.py b/elab_bridge/Datastructures.py
new file mode 100644
index 00000000..89372908
--- /dev/null
+++ b/elab_bridge/Datastructures.py
@@ -0,0 +1,29 @@
+import os
+import os
+
+
+def creat_repository_by_experiments(root_to_save, data_type='micr', sub_id=None, sess_id=None):
+ subject_dir = os.path.join(root_to_save, str(sub_id))
+ session_dir = os.path.join(subject_dir, str(sess_id))
+
+ if not os.path.exists(subject_dir):
+ os.makedirs(subject_dir)
+
+ if not os.path.exists(session_dir):
+ os.makedirs(session_dir)
+
+ if not os.path.exists(os.path.join(session_dir, data_type)):
+ os.makedirs(os.path.join(session_dir, data_type))
+
+
+def main():
+ root_directory = "."
+ subject_id = "sujet1"
+ session_id = "session1"
+ data_type = "type_de_donnees"
+
+ creat_repository_by_experiments(root_directory, data_type, subject_id, session_id)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/elab_bridge/Extractor.py b/elab_bridge/Extractor.py
new file mode 100644
index 00000000..c4d4fe36
--- /dev/null
+++ b/elab_bridge/Extractor.py
@@ -0,0 +1,373 @@
+import json
+
+import argparse
+
+import logging
+
+# Configure logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def loadfile(jsonfile):
+ try:
+ with open(jsonfile, 'r') as f:
+ data = json.load(f)
+ # tranforme to int all id an dgroupe id in the json file
+ for group in data['elabftw']['extra_fields_groups']:
+ group['id'] = int(group['id'])
+ for field in data['extra_fields'].values():
+ field['group_id'] = int(field['group_id'])
+
+ return data
+ except json.JSONDecodeError as e:
+ raise ValueError(f"Error decoding JSON: {e}")
+ except FileNotFoundError:
+ raise ValueError(f"File not found: {jsonfile}")
+
+
+def savefile(jsonfile, data):
+ with open(jsonfile, "w") as f:
+ json.dump(data, f, indent=4)
+
+
+def extract_groupfield_detail(jsonfile, id, new_id=None):
+ """
+ Extract details of groupfield from a JSON file.
+
+ :param jsonfile: The JSON file path.
+ :param id: The groupfield id to match.
+ :param new_id: The new id to replace for matching fields.
+ :return: groupfield name and all child fields from the group as a list of dictionaries.
+ """
+ list_group_field = []
+ group_name = ""
+
+ # Open and load the JSON data
+ with open(jsonfile, 'r') as f:
+ try:
+ data = json.load(f)
+ except json.JSONDecodeError as e:
+ raise ValueError(f"Error decoding JSON: {e}")
+
+ # Extract the group name by matching the id
+ if 'elabftw' in data and 'extra_fields_groups' in data['elabftw']:
+ for group in data['elabftw']['extra_fields_groups']:
+ if int(group.get('id')) == id:
+ group_name = group.get('name', '') # Ensure name exists
+ break
+ else:
+ raise KeyError("Expected keys 'elabftw' and 'extra_fields_groups' not found in JSON")
+
+ # Check if 'extra_fields' exists and is a dictionary
+ extra_fields = data.get('extra_fields', {})
+
+ if isinstance(extra_fields, dict):
+ for k, v in extra_fields.items():
+ if v.get('group_id') == str(id) or v.get('group_id') == id:
+ v['group_id'] = new_id
+ list_group_field.append({k: v})
+
+ return group_name, list_group_field
+
+
+def construct_extracted_json(jsonfile, id, new_id, json_output=None):
+ """
+ Construct a new JSON file with the same layout but only the extracted information.
+
+ :param jsonfile: The original JSON file path.
+ :param id: The groupfield id to match.
+ :param new_id: The new id to replace for matching fields.
+ :param json_output: The path to save the new JSON structure.
+ :return: A dictionary with the new JSON structure.
+ """
+ group_name, list_group_field = extract_groupfield_detail(jsonfile, id, new_id)
+
+ new_json_structure = {
+ 'elabftw': {
+ 'extra_fields_groups': [
+ {
+ 'id': new_id,
+ 'name': group_name
+ }
+ ]
+ },
+ 'extra_fields': {field_id: details for field in list_group_field for field_id, details in
+ field.items()}
+ }
+
+ if json_output is not None:
+ savefile(json_output, new_json_structure)
+
+ return new_json_structure
+
+
+def add_a_groupfield(jsonfile, indice, groupfield_dict_list, group_name, output_jsonfile=None):
+ """
+ Add a new groupfield to the JSON file.
+
+ :param jsonfile: The JSON file path.
+ :param indice: The ID for the new groupfield.
+ :param groupfield_dict_list: A list of dictionaries representing the fields to add.
+ :param group_name: The name of the new groupfield.
+ :param output_jsonfile: The path to save the updated JSON file.
+ :return: The updated JSON data.
+ """
+
+ data = loadfile(jsonfile)
+
+ # Increment IDs of existing groups if they are greater than or equal to the new index
+ for group in data['elabftw']['extra_fields_groups']:
+ if group['id'] >= indice:
+ group['id'] += 1
+
+ # Add the new group
+ data['elabftw']['extra_fields_groups'].append({'id': indice, 'name': group_name})
+ data['elabftw']['extra_fields_groups'] = sorted(data['elabftw']['extra_fields_groups'],
+ key=lambda x: x['id'])
+
+ # Update the group_id in existing extra fields
+ extra_fields = data.get('extra_fields', {})
+ for k, v in extra_fields.items():
+ group_id = int(v.get('group_id', 0))
+ if group_id >= indice:
+ v['group_id'] = group_id + 1
+
+ # Add the new fields to the extra fields
+ for a_dict in groupfield_dict_list:
+ for field_name, field_data in a_dict.items():
+ field_data['group_id'] = indice # Assign the new group ID as an integer
+ extra_fields[field_name] = field_data
+
+ data['extra_fields'] = extra_fields
+
+ if output_jsonfile is not None:
+ with open(output_jsonfile, 'w') as f_out:
+ json.dump(data, f_out, indent=4)
+
+ return data
+
+
+def complete_groupfield_in_jsonfile(jsonfile, groupfield_name, groupfield_detail_list,
+ json_completed=None):
+ """
+ Complete the 'extra_fields' section of a JSON file with new fields based on a groupfield name.
+
+ :param jsonfile: The JSON file path.
+ :param groupfield_name: The name of the groupfield.
+ :param groupfield_detail_list: A list of dictionaries representing the new fields to add.
+ :param json_completed: The path to save the updated JSON file.
+ :return: The updated JSON data.
+ """
+ is_completed = False
+ new_id = None
+
+ data = loadfile(jsonfile)
+
+ for group in data['elabftw']['extra_fields_groups']:
+ if groupfield_name == group['name']:
+ is_completed = True
+ new_id = group['id']
+ break
+
+ if is_completed and new_id:
+ extra_fields = data['extra_fields']
+
+ for a_dict in groupfield_detail_list:
+ for k, v in a_dict.items():
+ v['group_id'] = new_id
+ extra_fields[k] = v
+
+ data['extra_fields'] = extra_fields
+
+ if json_completed is not None:
+ with open(json_completed, 'w') as f_out:
+ json.dump(data, f_out, indent=4)
+
+ return data
+
+ else:
+ raise ValueError(f"Groupfield name '{groupfield_name}' not found in the JSON file.")
+
+
+def complete_jsonfile1_with_jsonfile2_groupefield(jsonfiletocompleted, jsonfiletoextract, indice,
+ new_indice, json_completed=None):
+ """
+ Extract a groupfield from one JSON file and add it to another JSON file.
+
+ :param jsonfiletocompleted: The JSON file to be completed.
+ :param jsonfiletoextract: The JSON file to extract the groupfield from.
+ :param indice: The groupfield ID in the source JSON file.
+ :param new_indice: The new groupfield ID for the target JSON file.
+ :param json_completed: The path to save the completed JSON file.
+ :return: The updated JSON data.
+ """
+ group_name, list_group_field = extract_groupfield_detail(jsonfiletoextract, indice, new_indice)
+ if json_completed is None:
+ json_completed = jsonfiletocompleted
+ return add_a_groupfield(jsonfiletocompleted, new_indice, list_group_field, group_name,
+ output_jsonfile=json_completed)
+
+
+def orderjsonfile(jsonfile, list_group_field_name, output_jsonfile=None):
+
+ """
+ Orders fields within a JSON file by specified group field names.
+ Parameters
+ ----------
+ jsonfile
+ list_group_field_name
+ output_jsonfile
+
+ Returns
+ ------- the updated JSON data.
+
+ """
+
+ try:
+ # Loading the JSON file
+ Data = loadfile(jsonfile)
+ if output_jsonfile is None:
+ output_jsonfile = jsonfile
+
+ # Ensure required keys are present
+ if 'elabftw' not in Data or 'extra_fields_groups' not in Data['elabftw']:
+ raise KeyError("Missing 'extra_fields_groups' in JSON data.")
+
+ list_group_field = [group['name'] for group in Data['elabftw']['extra_fields_groups']]
+ logger.debug(f"List of group fields: {list_group_field}")
+
+ # Validate group names
+ missing_groups = [group_name for group_name in list_group_field_name if
+ group_name not in list_group_field]
+ if missing_groups:
+ raise ValueError(f"Missing groups in data: {missing_groups}")
+
+ # Create mapping for group IDs
+ Dict_group_field_map = {}
+ for group in Data['elabftw']['extra_fields_groups']:
+ if group['name'] in list_group_field_name:
+ Dict_group_field_map[group['id']] = list_group_field_name.index(group['name']) + 1
+ logger.debug(f"Group field map: {Dict_group_field_map}")
+
+ # Reorganize group fields
+ for group in Data['elabftw']['extra_fields_groups']:
+ if group['id'] in Dict_group_field_map:
+ group['id'] = Dict_group_field_map[group['id']]
+ Data['elabftw']['extra_fields_groups'] = sorted(Data['elabftw']['extra_fields_groups'],
+ key=lambda x: x['id'])
+ logger.debug(f"Reorganized group fields: {Data['elabftw']['extra_fields_groups']}")
+
+ # Reorganize fields
+ for field in Data.get('extra_fields', {}).values():
+ if field['group_id'] in Dict_group_field_map:
+ field['group_id'] = Dict_group_field_map[field['group_id']]
+ logger.debug(f"Reorganized fields: {Data.get('extra_fields')}")
+
+ # Save the updated JSON
+ savefile(output_jsonfile, Data)
+ logger.info(f"Updated JSON saved to {output_jsonfile}")
+ return Data
+
+ except AssertionError as e:
+ logger.error(f"AssertionError: {str(e)}")
+ except KeyError as e:
+ logger.error(f"KeyError: {str(e)}")
+ except ValueError as e:
+ logger.error(f"ValueError: {str(e)}")
+ except Exception as e:
+ logger.error(f"An unexpected error occurred: {str(e)}")
+ return None
+
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser(
+ description=(
+ "This script provides tools to manipulate JSON files, including:\n"
+ "- Extracting specific fields from a JSON file and creating a new structured JSON.\n"
+ "- Merging two JSON files based on group field IDs: Extracting a group field from one "
+ "JSON file and appending it to another.\n"
+ "- Ordering fields within a JSON file by specified group field names."
+ ),
+ epilog=(
+ "Examples of usage:\n"
+ " Extract fields:\n"
+ "python Extractor.py extract --jsonfile_extract input.json --id 1 --new_id 2 "
+ "--json_output output.json\n\n"
+
+ " Merge JSON files:\n"
+ "python Extractor.py merge --jsonfiletocompleted file1.json --jsonfiletoextract "
+ "file2.json --id 3 --new_id 4 --json_completed merged.json\n\n"
+ " Order JSON fields:\n"
+ "python Extractor.py order --jsonfile input.json --list_group_field_name field1 "
+ "field2 --output_jsonfile ordered.json\n\n"
+ "Options:\n"
+ " extract Extracts fields from a JSON file and saves the output.\n"
+ " merge Complete a JSON file by adding a group field from another JSON file.\n"
+ " order Orders fields in a JSON file by the specified group field names."
+ ),
+ formatter_class=argparse.RawDescriptionHelpFormatter
+ )
+ parser.add_argument(
+ "operation",
+ choices=["extract", "merge", "order"],
+ help="Specify the operation to perform: 'extract' to extract fields or 'merge' to combine "
+ "files.",
+ )
+
+ # Arguments for extracting
+ parser.add_argument("--jsonfile_extract", '-e', help="The JSON file path for extraction.", type=str)
+
+ parser.add_argument("--id", help="The groupfield ID to match.", type=int)
+ parser.add_argument("--new_id", help="The new ID to replace for matching fields.", type=int)
+ parser.add_argument("--json_output", '-u', help="The path to save the new JSON structure.", type=str,
+ default=None)
+
+ # Arguments for merging
+ parser.add_argument("--jsonfiletocompleted", '-c', help="The JSON file to be completed.", type=str)
+ parser.add_argument("--jsonfiletoextract", '-x', help="The JSON file to extract the "
+ "groupfield from.",
+ type=str)
+ parser.add_argument("--json_completed", '-C', help="The path to save the completed JSON file.",
+ type=str, default=None)
+
+ # Arguments for ordering
+ parser.add_argument("--jsonfile", '-j', help="The JSON file path for ordering.", type=str)
+ parser.add_argument("--list_group_field_name", '-l', help="The list of group field names to "
+ "order.",
+ type=str, nargs='+')
+ parser.add_argument("--output_jsonfile", '-o', help="The path to save the ordered JSON file.",
+ type=str, default=None)
+
+ args = parser.parse_args()
+
+ if args.operation == "extract":
+ if not all([args.jsonfile_extract, args.id, args.new_id, args.json_output]):
+ print("Error: Missing arguments for the 'extract' operation.")
+ else:
+ construct_extracted_json(args.jsonfile_extract
+ , args.id, args.new_id, args.json_output)
+ print(f"Extraction completed and saved to {args.json_output}.")
+
+ elif args.operation == "merge":
+ if not all(
+ [args.jsonfiletocompleted, args.jsonfiletoextract, args.id, args.new_id,
+ args.json_completed]
+ ):
+ print("Error: Missing arguments for the 'merge' operation.")
+ else:
+ complete_jsonfile1_with_jsonfile2_groupefield(
+ args.jsonfiletocompleted,
+ args.jsonfiletoextract,
+ args.id,
+ args.new_id,
+ args.json_completed,
+ )
+ print(f"Merging completed and saved to {args.json_completed}.")
+ elif args.operation == "order":
+ if not all([args.jsonfile, args.list_group_field_name]):
+ print("Error: Missing arguments for the 'order' operation.")
+ else:
+ orderjsonfile(args.jsonfile, args.list_group_field_name, args.output_jsonfile)
+ print(f"Ordering completed and saved to {args.jsonfile}.")
diff --git a/elab_bridge/Merge.py b/elab_bridge/Merge.py
new file mode 100644
index 00000000..bffb7466
--- /dev/null
+++ b/elab_bridge/Merge.py
@@ -0,0 +1,182 @@
+import json
+import os
+import argparse
+from typing import List, Tuple, Dict, Any
+from tqdm import tqdm # For progress indication
+import logging
+
+# Configure logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+
+def safe_load_json(filepath: str) -> Dict[str, Any]:
+ """
+ Safely load a JSON file, handling potential errors.
+ Args:
+ filepath (str): Path to the JSON file.
+ Returns:
+ Dict[str, Any]: Parsed JSON data.
+ Raises:
+ ValueError: If the file is not valid JSON or cannot be read.
+ """
+ try:
+ with open(filepath, 'r') as f:
+ return json.load(f)
+ except json.JSONDecodeError:
+ raise ValueError(f"Invalid JSON format in file: {filepath}")
+ except FileNotFoundError:
+ raise ValueError(f"File not found: {filepath}")
+
+
+def get_a_jsonfile_structure(jsonfile: str) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]:
+ """
+ Extract structure from a JSON file, focusing on 'extra_fields_groups' and 'extra_fields'.
+ Args:
+ jsonfile (str): Path to the JSON file.
+ Returns:
+ Tuple[List[Dict[str, Any]], Dict[str, Any]]: Groups and fields.
+ """
+ data = safe_load_json(jsonfile)
+
+ # Ensure every 'id' in 'extra_fields_groups' is an int
+ for group in data['elabftw']['extra_fields_groups']:
+ group['id'] = int(group['id'])
+
+ # Ensure every 'group_id' in 'extra_fields' is an int
+ for field in data['extra_fields'].values():
+ field['group_id'] = int(field['group_id'])
+ # check if all id are int
+ assert all(isinstance(group['id'], int) for group in data['elabftw']['extra_fields_groups'])
+ # check if all group_id are int
+ assert all(isinstance(field['group_id'], int) for field in data['extra_fields'].values())
+ return data['elabftw']['extra_fields_groups'], data['extra_fields']
+
+
+def get_indices(extra_fields_groups: List[Dict[str, Any]]) -> int:
+ """
+ Get the next available index for 'id' fields.
+ Args:
+ extra_fields_groups (List[Dict[str, Any]]): List of groups.
+ Returns:
+ int: Next index.
+ """
+ return max(group['id'] for group in extra_fields_groups) + 1 if extra_fields_groups else 1
+
+
+def replace_id(
+ extra_fields_groups: List[Dict[str, Any]],
+ extrat_fields: Dict[str, Dict[str, Any]],
+ indice: int
+) -> Tuple[List[Dict[str, Any]], Dict[str, Dict[str, Any]]]:
+ """
+ Replace IDs in groups and fields to ensure uniqueness.
+ Args:
+ extra_fields_groups (list): List of groups.
+ extrat_fields (dict): Fields mapping.
+ indice (int): Starting index.
+ Returns:
+ Tuple[List[Dict[str, Any]], Dict[str, Dict[str, Any]]]: Updated groups and fields.
+ """
+ # Sort 'extra_fields_groups' by 'id' to ensure consistent order
+ extra_fields_groups_sorted = sorted(extra_fields_groups, key=lambda group: group['id'])
+
+ # Sort 'extrat_fields' by 'group_id' to ensure fields match the sorted groups
+ extrat_fields_sorted = {k: v for k, v in
+ sorted(extrat_fields.items(), key=lambda item: item[1]['group_id'])}
+
+ matched_indices = {}
+ for group in extra_fields_groups_sorted:
+ old_id = group['id']
+ group['id'] = indice
+ matched_indices[old_id] = indice
+ indice += 1
+
+ for field in extrat_fields_sorted.values():
+ if 'group_id' in field and field['group_id'] in matched_indices:
+ field['group_id'] = matched_indices[field['group_id']]
+
+ return extra_fields_groups_sorted, extrat_fields_sorted
+
+
+def merge_jsonfiles(jsonfile_list_sorted: List[str], json_output: str, dry_run: bool = False,
+ compact: bool = False):
+ """
+ Merge multiple JSON files into one.
+ Args:
+ jsonfile_list_sorted (List[str]): List of JSON files to merge.
+ json_output (str): Output file path.
+ dry_run (bool): If True, preview changes without saving.
+ compact (bool): If True, save output in compact format.
+ """
+ base_data = safe_load_json(jsonfile_list_sorted[0])
+ main_extra_fields_groups = base_data['elabftw']['extra_fields_groups']
+ main_extrat_fields = base_data['extra_fields']
+ indice = get_indices(main_extra_fields_groups)
+
+ for jsonfile in tqdm(jsonfile_list_sorted[1:], desc="Merging JSON files"):
+ extra_fields_groups, extrat_fields = get_a_jsonfile_structure(jsonfile)
+ updated_groups, updated_fields = replace_id(extra_fields_groups, extrat_fields, indice)
+ main_extra_fields_groups.extend(updated_groups)
+ main_extrat_fields.update(updated_fields)
+ indice = max(group['id'] for group in main_extra_fields_groups) + 1
+
+ base_data['elabftw']['extra_fields_groups'] = main_extra_fields_groups
+ base_data['extra_fields'] = main_extrat_fields
+
+ if dry_run:
+ logger.info("Dry run mode enabled. Changes not saved.")
+ logger.info(json.dumps(base_data, indent=4 if not compact else None))
+ else:
+ with open(json_output, 'w') as f:
+ json.dump(base_data, f, indent=None if compact else 4)
+ logger.info(f"Output written to {json_output}")
+
+
+def main():
+ # Argument parser initialization
+ parser = argparse.ArgumentParser(
+ description=(
+ "This script merges multiple JSON files into a single output file. "
+ "Provide a list of JSON files and the name of the output file."
+ ),
+ epilog=(
+ "Examples:\n"
+ " python Merge.py file1.json file2.json output.json\n"
+ " python Merge.py file1.json file2.json output.json --dry-run\n"
+ " python Merge.py file1.json file2.json output.json --overwrite\n\n"
+ "Options:\n"
+ " --dry-run Preview the result without saving.\n"
+ " --compact Save the output JSON in a compact format (without extra spaces).\n"
+ " --overwrite Overwrite the output file if it already exists."
+ ),
+ formatter_class=argparse.RawDescriptionHelpFormatter
+ )
+ parser.add_argument("--sorted_list_input_files", "-s", nargs="+", help="List of JSON files to "
+ "merge", type=str,
+ required=True)
+ parser.add_argument("--output", "-o", help="Name of the output JSON file", type=str,
+ required=True)
+ parser.add_argument("--dry-run", "-d", action="store_true", help="Preview changes without "
+ "saving")
+ parser.add_argument("--compact", "-c", action="store_true", help="Save output JSON in "
+ "compact format")
+ parser.add_argument("--overwrite", "-ov", action="store_true",
+ help="Overwrite the output file if it exists")
+
+ args = parser.parse_args()
+ list_of_files = [file for file in args.sorted_list_input_files if file.endswith('.json')]
+ if not list_of_files:
+ raise ValueError("No valid JSON files found in the input list.")
+
+ output_file = args.output if args.output.endswith('.json') else args.output + '.json'
+
+ if not args.overwrite and os.path.exists(output_file):
+ raise FileExistsError(
+ f"Output file {output_file} already exists. Use --overwrite to overwrite.")
+
+ merge_jsonfiles(list_of_files, output_file, dry_run=args.dry_run, compact=args.compact)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/elab_bridge/Test_export_bids.py b/elab_bridge/Test_export_bids.py
new file mode 100644
index 00000000..126e8c0a
--- /dev/null
+++ b/elab_bridge/Test_export_bids.py
@@ -0,0 +1,24 @@
+from pathlib import Path
+import elab_bridge
+import json
+from elab_bridge import server_interface
+
+from diglab_utils.test_utils import (test_directory, initialize_test_dir)
+
+project_dir = test_directory / 'test files_elab' / 'TestProject'
+SERVER_CONFIG_YAML = ('/home/pourtoi/PycharmProjects/DigLabTools/elab_bridge/tests/testfiles_elab/TestProject/project'
+ '.json')
+
+
+def main():
+ save_to = '/home/pourtoi/Bureau/Nouveau dossier/BEP/Test/fichier.csv'
+
+ df = elab_bridge.server_interface.download_experiment(save_to, SERVER_CONFIG_YAML, 247, format='csv')
+ print(df)
+ output_file = '/home/pourtoi/Bureau/Nouveau dossier/BEP/Test/json_output.json'
+ with open(output_file, 'w') as output_file:
+ json.dump(df, output_file, indent=4)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/elab_bridge/template_parts/test_templates/ Merged_output.json b/elab_bridge/template_parts/test_templates/ Merged_output.json
new file mode 100644
index 00000000..59c5b852
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ Merged_output.json
@@ -0,0 +1,519 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "ProjectBIDSMetadata"
+ },
+ {
+ "id": 2,
+ "name": "ParticipantBIDSMetadata"
+ },
+ {
+ "id": 3,
+ "name": "SessionBIDSMetadata"
+ },
+ {
+ "id": 3,
+ "name": "Run "
+ },
+ {
+ "id": 4,
+ "name": "EyeTrackingBIDSMETADATA"
+ }
+ ]
+ },
+ "extra_fields": {
+ "age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 5,
+ "description": "GDPR !!!. In years or months. Ex: '42 or 0.4'"
+ },
+ "sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "GDPR"
+ },
+ "group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'"
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "The weight of the subject [in grams]",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 1,
+ "description": "List of individuals who contributed to the creation/curation of the dataset."
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3
+ },
+ "Modality": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "extracellular microelectrode signals",
+ "intracellular microelectrode signals",
+ "EEG",
+ "EMG",
+ "ECog",
+ "optical imaging",
+ "behaviour",
+ "stimulation (specify below)"
+ ],
+ "group_id": 2,
+ "position": "5",
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper)."
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "description": "subject number or monkey name or etc"
+ },
+ "handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR"
+ },
+ "session_id": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: '01 or predrug or 20231206'"
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The interpretation of the dataset. For backwards compatibility, the default value is \"raw\". Must be one of: \"raw\", \"derivative\"."
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "Used to specify provenance of the dataset."
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to map a given from a BIDS URI of the form bids:"
+ },
+ "Subject GUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2
+ },
+ "Experimenter 1": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 7,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 2": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 8,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 3": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 9,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experiment name": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "En fran\u00e7ais: nom de la manip incluant X sujets / Experiment name including around X subjects"
+ },
+ "Session duration": {
+ "type": "number",
+ "value": "91",
+ "group_id": 3,
+ "position": "3",
+ "description": "The duration of the session [in minutes]",
+ "blank_value_on_duplicate": true
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'"
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "defaut format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 0,
+ "description": "The official ethical protocol id "
+ },
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 1,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "Run comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 144,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "description": "Description of the task"
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "description": "Add comments if needed"
+ },
+ "StartTime": {
+ "type": "number",
+ "unit": "seconds",
+ "units": [
+ "seconds"
+ ],
+ "value": "",
+ "group_id": 4,
+ "position": 2,
+ "description": "Start time in seconds",
+ "blank_value_on_duplicate": false
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "Run Number": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 4,
+ "position": 4,
+ "description": "One repetition of a experimental task. defined numerically"
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 4,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 4,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 4,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 4,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 4,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter"
+ ],
+ "value": "",
+ "group_id": 4,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 4,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 4,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 4,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 4,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/ MergedeEPPP.json b/elab_bridge/template_parts/test_templates/ MergedeEPPP.json
new file mode 100644
index 00000000..740a533d
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ MergedeEPPP.json
@@ -0,0 +1,683 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Project_BIDS_Metadata"
+ },
+ {
+ "id": 2,
+ "name": "Subject_BIDS_Metadata"
+ },
+ {
+ "id": 3,
+ "name": "Recording_BIDS_Metadata"
+ },
+ {
+ "id": 4,
+ "name": "MicroEphys_BIDS_Metadata"
+ },
+ {
+ "id": 5,
+ "name": "EyeTracking_BIDS_METADATA"
+ },
+ {
+ "id": 6,
+ "name": "VisuoMotorLaminar_Specifique_Metadata"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months",
+ "days"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "in years, month or days",
+ "blank_value_on_duplicate": false
+ },
+ "Sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "",
+ "blank_value_on_duplicate": false
+ },
+ "Group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'",
+ "blank_value_on_duplicate": false
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "kg",
+ "g"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "List of individuals who contributed to the creation of the project.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "Add comments if needed"
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6,
+ "blank_value_on_duplicate": false
+ },
+ "SessionId": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: 01, predrug , 20231206 , 20231206S01",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper).",
+ "blank_value_on_duplicate": false
+ },
+ "Handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR",
+ "blank_value_on_duplicate": false
+ },
+ "Modalities": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "MRI",
+ "MEG",
+ "EEG",
+ "iEEG",
+ "Physio (cardiac, respiration, etc.)",
+ "Behaviour",
+ "Genetic descriptor",
+ "PET",
+ "Microscopy",
+ "NIRS",
+ "Motion",
+ "MRS",
+ "Microelectode Electrophysiology",
+ "Video",
+ "EyeTracking"
+ ],
+ "group_id": 2,
+ "position": 5,
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "description": "subject number or monkey name or etc",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The interpretation of the dataset. Must be one of: 'raw', 'derivative'.",
+ "blank_value_on_duplicate": false
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to specify provenance of the dataset.",
+ "blank_value_on_duplicate": false
+ },
+ "ProjectName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 0,
+ "description": "Experiment name including around X subjects",
+ "blank_value_on_duplicate": false
+ },
+ "SessionDate": {
+ "type": "date",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "SubjectGUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Used to map a given from a BIDS URI of the form bids:",
+ "blank_value_on_duplicate": false
+ },
+ "SessionComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "default format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 1,
+ "description": "The official ethical protocol id",
+ "blank_value_on_duplicate": false
+ },
+ "ProbIDList": {
+ "type": "text",
+ "value": "[p023, p021]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "HemisphereList": {
+ "type": "text",
+ "value": "[left, right]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "BrainRegionList": {
+ "type": "text",
+ "value": "[motor cortex , visual cortex]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "CoordinateSystemFile": {
+ "type": "text",
+ "value": "BIDS_coordsystem.json",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ProbesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_probes.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ChannelsDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_channels.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ElectrodesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_electrodes.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "Comment on the MicroephysBidsMetadata": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "StartTime": {
+ "type": "number",
+ "unit": "seconds",
+ "units": [
+ "seconds"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 2,
+ "description": "Start time in seconds",
+ "blank_value_on_duplicate": false
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "Run Number": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": "One repetition of a experimental task. defined numerically"
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 5,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 5,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 5,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ },
+ "Duration": {
+ "type": "text",
+ "value": "",
+ "group_id": 6,
+ "position": 3,
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "select",
+ "value": "DMSBlocked",
+ "options": [
+ "DMSBlocked",
+ "DMSRandom",
+ "DMS",
+ "Reward schedule",
+ "Movie watching",
+ "Groove",
+ "RestingState"
+ ],
+ "group_id": 6,
+ "position": 0,
+ "blank_value_on_duplicate": false
+ },
+ "Stop Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "Start Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ " RewardType": {
+ "type": "radio",
+ "value": "liquid",
+ "options": [
+ "liquid",
+ "solid"
+ ],
+ "group_id": 6,
+ "position": 5,
+ "blank_value_on_duplicate": false
+ },
+ "Special Event": {
+ "type": "radio",
+ "value": "yes",
+ "options": [
+ "yes",
+ "no"
+ ],
+ "group_id": 6,
+ "position": 10,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 1": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 7,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 2": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 8,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 3": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 9,
+ "blank_value_on_duplicate": false
+ },
+ "RewardQuantity": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "g",
+ "ml"
+ ],
+ "value": "",
+ "group_id": 6,
+ "position": 6
+ },
+ " Witch Color First": {
+ "type": "radio",
+ "value": "pink",
+ "options": [
+ "pink",
+ "blue",
+ "none"
+ ],
+ "group_id": 6,
+ "position": 4,
+ "blank_value_on_duplicate": false
+ },
+ "Special Event Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "CommentSpecialEvent": {
+ "type": "text",
+ "value": "Martin",
+ "group_id": 6,
+ "position": 12,
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/ eyeform.json b/elab_bridge/template_parts/test_templates/ eyeform.json
new file mode 100644
index 00000000..85fcb071
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ eyeform.json
@@ -0,0 +1,523 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Project_BIDS_Metadata"
+ },
+ {
+ "id": 2,
+ "name": "Subject_BIDS_Metadata"
+ },
+ {
+ "id": 3,
+ "name": "Recording_BIDS_Metadata"
+ },
+ {
+ "id": 4,
+ "name": "Run "
+ },
+ {
+ "id": 5,
+ "name": "EyeTracking_BIDS_METADATA"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months",
+ "days"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "in years, month or days",
+ "blank_value_on_duplicate": false
+ },
+ "Sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "",
+ "blank_value_on_duplicate": false
+ },
+ "Group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'",
+ "blank_value_on_duplicate": false
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "kg",
+ "g"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "List of individuals who contributed to the creation of the project.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "Add comments if needed"
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6,
+ "blank_value_on_duplicate": false
+ },
+ "SessionId": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: 01, predrug , 20231206 , 20231206S01",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper).",
+ "blank_value_on_duplicate": false
+ },
+ "Handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR",
+ "blank_value_on_duplicate": false
+ },
+ "Modalities": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "MRI",
+ "MEG",
+ "EEG",
+ "iEEG",
+ "Physio (cardiac, respiration, etc.)",
+ "Behaviour",
+ "Genetic descriptor",
+ "PET",
+ "Microscopy",
+ "NIRS",
+ "Motion",
+ "MRS",
+ "Microelectode Electrophysiology",
+ "Video",
+ "EyeTracking"
+ ],
+ "group_id": 2,
+ "position": 5,
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "description": "subject number or monkey name or etc",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The interpretation of the dataset. Must be one of: 'raw', 'derivative'.",
+ "blank_value_on_duplicate": false
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to specify provenance of the dataset.",
+ "blank_value_on_duplicate": false
+ },
+ "ProjectName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 0,
+ "description": "Experiment name including around X subjects",
+ "blank_value_on_duplicate": false
+ },
+ "SessionDate": {
+ "type": "date",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "SubjectGUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Used to map a given from a BIDS URI of the form bids:",
+ "blank_value_on_duplicate": false
+ },
+ "SessionComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "default format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 1,
+ "description": "The official ethical protocol id",
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 0,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "RunNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 2
+ },
+ "StartTime": {
+ "type": "text",
+ "value": "",
+ "group_id": 4
+ },
+ "RunComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 3,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 1,
+ "description": "Description of the task"
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "eyetrack",
+ "group_id": 5,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 5,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 5,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter",
+ "cm"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 5,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/ visuolaminar.json b/elab_bridge/template_parts/test_templates/ visuolaminar.json
new file mode 100644
index 00000000..f19eb247
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ visuolaminar.json
@@ -0,0 +1,681 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Project_BIDS_Metadata"
+ },
+ {
+ "id": 2,
+ "name": "Subject_BIDS_Metadata"
+ },
+ {
+ "id": 3,
+ "name": "Recording_BIDS_Metadata"
+ },
+ {
+ "id": 4,
+ "name": "MicroEphys_BIDS_Metadata"
+ },
+ {
+ "id": 5,
+ "name": "EyeTracking_BIDS_METADATA"
+ },
+ {
+ "id": 6,
+ "name": "VisuoMotorLaminar_Specifique_Metadata"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months",
+ "days"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "in years, month or days",
+ "blank_value_on_duplicate": false
+ },
+ "Sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "",
+ "blank_value_on_duplicate": false
+ },
+ "Group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'",
+ "blank_value_on_duplicate": false
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "kg",
+ "g"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "List of individuals who contributed to the creation of the project.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "Add comments if needed"
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6,
+ "blank_value_on_duplicate": false
+ },
+ "SessionId": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: 01, predrug , 20231206 , 20231206S01",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper).",
+ "blank_value_on_duplicate": false
+ },
+ "Handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR",
+ "blank_value_on_duplicate": false
+ },
+ "Modalities": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "MRI",
+ "MEG",
+ "EEG",
+ "iEEG",
+ "Physio (cardiac, respiration, etc.)",
+ "Behaviour",
+ "Genetic descriptor",
+ "PET",
+ "Microscopy",
+ "NIRS",
+ "Motion",
+ "MRS",
+ "Microelectode Electrophysiology",
+ "Video",
+ "EyeTracking"
+ ],
+ "group_id": 2,
+ "position": 5,
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "description": "subject number or monkey name or etc",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The interpretation of the dataset. Must be one of: 'raw', 'derivative'.",
+ "blank_value_on_duplicate": false
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to specify provenance of the dataset.",
+ "blank_value_on_duplicate": false
+ },
+ "ProjectName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 0,
+ "description": "Experiment name including around X subjects",
+ "blank_value_on_duplicate": false
+ },
+ "SessionDate": {
+ "type": "date",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "SubjectGUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Used to map a given from a BIDS URI of the form bids:",
+ "blank_value_on_duplicate": false
+ },
+ "SessionComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "default format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 1,
+ "description": "The official ethical protocol id",
+ "blank_value_on_duplicate": false
+ },
+ "ProbIDList": {
+ "type": "text",
+ "value": "[p023, p021]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "HemisphereList": {
+ "type": "text",
+ "value": "[left, right]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "BrainRegionList": {
+ "type": "text",
+ "value": "[motor cortex , visual cortex]",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "CoordinateSystemFile": {
+ "type": "text",
+ "value": "BIDS_coordsystem.json",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ProbesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_probes.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ChannelsDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_channels.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ElectrodesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_electrodes.tsv",
+ "group_id": 4,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "Comment on the MicroephysBidsMetadata": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "blank_value_on_duplicate": false
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "eyetrack",
+ "group_id": 5,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 5,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 5,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter",
+ "cm"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 5,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 5,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 5,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 5,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ },
+ "Accuracy": {
+ "type": "text",
+ "value": "",
+ "group_id": 6,
+ "position": 13
+ },
+ "Duration": {
+ "type": "text",
+ "value": "",
+ "group_id": 6,
+ "position": 3,
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "select",
+ "value": "DMSBlocked",
+ "options": [
+ "DMSBlocked",
+ "DMSRandom",
+ "DMS",
+ "Reward schedule",
+ "Movie watching",
+ "Groove",
+ "RestingState"
+ ],
+ "group_id": 6,
+ "position": 0,
+ "blank_value_on_duplicate": false
+ },
+ "Stop Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "Start Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ " RewardType": {
+ "type": "radio",
+ "value": "liquid",
+ "options": [
+ "liquid",
+ "solid"
+ ],
+ "group_id": 6,
+ "position": 4,
+ "blank_value_on_duplicate": false
+ },
+ "FailedTrial": {
+ "type": "text",
+ "value": "",
+ "group_id": 6,
+ "position": 12
+ },
+ "Special Event": {
+ "type": "radio",
+ "value": "no",
+ "options": [
+ "yes",
+ "no"
+ ],
+ "group_id": 6,
+ "position": 10,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 1": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 7,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 2": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 8,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 3": {
+ "type": "users",
+ "value": "",
+ "group_id": 6,
+ "position": 9,
+ "blank_value_on_duplicate": false
+ },
+ "RewardQuantity": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "g",
+ "ml"
+ ],
+ "value": "",
+ "group_id": 6,
+ "position": 6
+ },
+ "Successful Trial": {
+ "type": "text",
+ "value": "",
+ "group_id": 6,
+ "position": 11
+ },
+ " Witch Color First": {
+ "type": "radio",
+ "value": "pink",
+ "options": [
+ "pink",
+ "blue",
+ "none"
+ ],
+ "group_id": 6,
+ "position": 5,
+ "blank_value_on_duplicate": false
+ },
+ "Special Event Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 6,
+ "position": 13,
+ "blank_value_on_duplicate": false
+ },
+ "CommentSpecialEvent": {
+ "type": "text",
+ "value": "Martin",
+ "group_id": 6,
+ "position": 14,
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/Basic_Form.json b/elab_bridge/template_parts/test_templates/Basic_Form.json
new file mode 100644
index 00000000..e69de29b
diff --git a/elab_bridge/template_parts/test_templates/Basicf.json b/elab_bridge/template_parts/test_templates/Basicf.json
new file mode 100644
index 00000000..c9b93de5
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/Basicf.json
@@ -0,0 +1,221 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "GENERIC_BIDS_PROJECT"
+ },
+ {
+ "id": 2,
+ "name": "GENERIC_BIDS_PARTICIPANT"
+ },
+ {
+ "id": 3,
+ "name": "GENERIC_BIDS_SESSION"
+ }
+ ]
+ },
+ "extra_fields": {
+ "age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 5,
+ "description": "GDPR !!!. In years or months. Ex: '42 or 0.4'"
+ },
+ "sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "GDPR"
+ },
+ "group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'"
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "The weight of the subject [in grams]",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 1,
+ "description": "List of individuals who contributed to the creation/curation of the dataset."
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3
+ },
+ "Modality": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "extracellular microelectrode signals",
+ "intracellular microelectrode signals",
+ "EEG",
+ "EMG",
+ "ECog",
+ "optical imaging",
+ "behaviour",
+ "stimulation (specify below)"
+ ],
+ "group_id": 2,
+ "position": "5",
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper)."
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "description": "subject number or monkey name or etc"
+ },
+ "handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR"
+ },
+ "session_id": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: '01 or predrug or 20231206'"
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The interpretation of the dataset. For backwards compatibility, the default value is \"raw\". Must be one of: \"raw\", \"derivative\"."
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "Used to specify provenance of the dataset."
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to map a given from a BIDS URI of the form bids:"
+ },
+ "Subject GUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2
+ },
+ "Experimenter 1": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 7,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 2": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 8,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 3": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 9,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experiment name": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "En français: nom de la manip incluant X sujets / Experiment name including around X subjects"
+ },
+ "Session duration": {
+ "type": "number",
+ "value": "91",
+ "group_id": 3,
+ "position": "3",
+ "description": "The duration of the session [in minutes]",
+ "blank_value_on_duplicate": true
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'"
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "defaut format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 0,
+ "description": "The official ethical protocol id "
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/EEG_HARDWARE_info.json b/elab_bridge/template_parts/test_templates/EEG_HARDWARE_info.json
new file mode 100644
index 00000000..3cfc2b27
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/EEG_HARDWARE_info.json
@@ -0,0 +1,135 @@
+{
+ "elabftw": {
+ "display_main_text": true,
+ "extra_fields_groups": [
+ {
+ "id": 3,
+ "name": "Hardware"
+ },
+ {
+ "id": 2,
+ "name": "Session"
+ },
+ {
+ "id": 3,
+ "name": "Run "
+ }
+ ]
+ },
+ "extra_fields": {
+ "age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "GDPR !!!. In years or months. Ex: '42 or 0.4'"
+ },
+ "sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 1,
+ "position": 3,
+ "description": "GDPR"
+ },
+ "group": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'"
+ },
+ "EEG cap": {
+ "type": "items",
+ "value": "",
+ "group_id": 3,
+ "position": 9,
+ "description": "Type EEGcap and select the cap"
+ },
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 1,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "EEG system": {
+ "type": "items",
+ "group_id": 3,
+ "position": 10,
+ "description": "Type EEGsystem and select the system"
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 0,
+ "description": "subject number or monkey name"
+ },
+ "handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 1,
+ "position": 5,
+ "description": "GDPR"
+ },
+ "Run comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 100,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "Subject GUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 1
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "description": "Description of the task"
+ },
+ "EEG cap position": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 11,
+ "description": "Ex: 'CZ at 10cm from nasion'"
+ },
+ "Hardware comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 12,
+ "description": "Ex: 'Dysfunction of electrode #3, ...'"
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Ex: '53.5 or 55'"
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/Ephys1.json b/elab_bridge/template_parts/test_templates/Ephys1.json
new file mode 100644
index 00000000..7a2de038
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/Ephys1.json
@@ -0,0 +1,64 @@
+{
+ "elabftw": {
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "MicroEphys_BIDS_Metadata"
+ }
+ ]
+ },
+ "extra_fields": {
+ "ProbIDList": {
+ "type": "text",
+ "value": "[p023, p021]",
+ "group_id": 1,
+ "blank_value_on_duplicate": false
+ },
+ "HemisphereList": {
+ "type": "text",
+ "value": "[left, right]",
+ "group_id": 1,
+ "blank_value_on_duplicate": false
+ },
+ "BrainRegionList": {
+ "type": "text",
+ "value": "[motor cortex , visual cortex]",
+ "group_id": 1,
+ "blank_value_on_duplicate": false
+ },
+ "CoordinateSystemFile": {
+ "type": "text",
+ "value": "BIDS_coordsystem.json",
+ "group_id": 1,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ProbesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_probes.tsv",
+ "group_id": 1,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ChannelsDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_channels.tsv",
+ "group_id": 1,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "ElectrodesDescriptionFile": {
+ "type": "text",
+ "value": "BIDS_electrodes.tsv",
+ "group_id": 1,
+ "description": "file path",
+ "blank_value_on_duplicate": false
+ },
+ "Comment on the MicroephysBidsMetadata": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/RUNten.json b/elab_bridge/template_parts/test_templates/RUNten.json
new file mode 100644
index 00000000..8c8b2293
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/RUNten.json
@@ -0,0 +1 @@
+{"elabftw":{"display_main_text":true,"extra_fields_groups":[{"id":2,"name":"Run 1"},{"id":3,"name":"Run 2"},{"id":4,"name":"Run 3"},{"id":5,"name":"Run 4"},{"id":6,"name":"Run 5"},{"id":7,"name":"Run 6"},{"id":8,"name":"Run 7"},{"id":9,"name":"Run 8"},{"id":10,"name":"Run 9"},{"id":11,"name":"Run 10"}]},"extra_fields":{"TaskName_1":{"type":"text","value":"","group_id":2,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_2":{"type":"text","value":"","group_id":3,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_3":{"type":"text","value":"","group_id":4,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_4":{"type":"text","value":"","group_id":5,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_5":{"type":"text","value":"","group_id":6,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_6":{"type":"text","value":"","group_id":7,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_7":{"type":"text","value":"","group_id":8,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_8":{"type":"text","value":"","group_id":9,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"TaskName_9":{"type":"text","value":"","group_id":10,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"EventsSet_1":{"type":"text","value":"","group_id":2,"position":4,"description":"Details about the events associated with this set."},"EventsSet_2":{"type":"text","value":"","group_id":3,"position":4,"description":"Details about the events associated with this set."},"EventsSet_3":{"type":"text","value":"","group_id":4,"position":4,"description":"Details about the events associated with this set."},"EventsSet_4":{"type":"text","value":"","group_id":5,"position":4,"description":"Details about the events associated with this set."},"EventsSet_5":{"type":"text","value":"","group_id":6,"position":4,"description":"Details about the events associated with this set."},"EventsSet_6":{"type":"text","value":"","group_id":7,"position":4,"description":"Details about the events associated with this set."},"EventsSet_7":{"type":"text","value":"","group_id":8,"position":4,"description":"Details about the events associated with this set."},"EventsSet_8":{"type":"text","value":"","group_id":9,"position":4,"description":"Details about the events associated with this set."},"EventsSet_9":{"type":"text","value":"","group_id":10,"position":4,"description":"Details about the events associated with this set."},"RunNumber_1":{"type":"text","value":"","group_id":2,"position":0},"RunNumber_2":{"type":"text","value":"","group_id":3,"position":0},"RunNumber_3":{"type":"text","value":"","group_id":4,"position":0},"RunNumber_4":{"type":"text","value":"","group_id":5,"position":0},"RunNumber_5":{"type":"text","value":"","group_id":6,"position":0},"RunNumber_6":{"type":"text","value":"","group_id":7,"position":0},"RunNumber_7":{"type":"text","value":"","group_id":8,"position":0},"RunNumber_8":{"type":"text","value":"","group_id":9,"position":0},"RunNumber_9":{"type":"text","value":"","group_id":10,"position":0},"StartTime_1":{"type":"text","value":"","group_id":2,"position":5},"StartTime_2":{"type":"text","value":"","group_id":3,"position":5},"StartTime_3":{"type":"text","value":"","group_id":4,"position":5},"StartTime_4":{"type":"text","value":"","group_id":5,"position":5},"StartTime_5":{"type":"text","value":"","group_id":6,"position":5},"StartTime_6":{"type":"text","value":"","group_id":7,"position":5},"StartTime_7":{"type":"text","value":"","group_id":8,"position":5},"StartTime_8":{"type":"text","value":"","group_id":9,"position":5},"StartTime_9":{"type":"text","value":"","group_id":10,"position":5},"TaskName_10":{"type":"text","value":"","group_id":11,"position":1,"required":true,"description":"Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"},"EventsSet_10":{"type":"text","value":"","group_id":11,"position":4,"description":"Details about the events associated with this set."},"RunComment_1":{"type":"text","value":"","group_id":2,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_2":{"type":"text","value":"","group_id":3,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_3":{"type":"text","value":"","group_id":4,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_4":{"type":"text","value":"","group_id":5,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_5":{"type":"text","value":"","group_id":6,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_6":{"type":"text","value":"","group_id":7,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_7":{"type":"text","value":"","group_id":8,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_8":{"type":"text","value":"","group_id":9,"position":6,"description":"Comment about the subject behavior during the run."},"RunComment_9":{"type":"text","value":"","group_id":10,"position":3,"description":"Comment about the subject behavior during the run."},"RunNumber_10":{"type":"text","value":"","group_id":11,"position":0},"StartTime_10":{"type":"text","value":"","group_id":11},"Acquisition_1":{"type":"text","value":"","group_id":2,"position":3,"description":"Details about the acquisition process."},"Acquisition_2":{"type":"text","value":"","group_id":3,"position":3,"description":"Details about the acquisition process."},"Acquisition_3":{"type":"text","value":"","group_id":4,"position":3,"description":"Details about the acquisition process."},"Acquisition_4":{"type":"text","value":"","group_id":5,"position":3,"description":"Details about the acquisition process."},"Acquisition_5":{"type":"text","value":"","group_id":6,"position":3,"description":"Details about the acquisition process."},"Acquisition_6":{"type":"text","value":"","group_id":7,"position":3,"description":"Details about the acquisition process."},"Acquisition_7":{"type":"text","value":"","group_id":8,"position":3,"description":"Details about the acquisition process."},"Acquisition_8":{"type":"text","value":"","group_id":9,"position":3,"description":"Details about the acquisition process."},"Acquisition_9":{"type":"text","value":"","group_id":10,"position":3,"description":"Details about the acquisition process."},"RunComment_10":{"type":"text","value":"","group_id":11,"position":3,"description":"Comment about the subject behavior during the run."},"Acquisition_10":{"type":"text","value":"","group_id":11,"position":3,"description":"Details about the acquisition process."},"TaskDescription_1":{"type":"text","value":"","group_id":2,"position":2,"description":"Description of the task"},"TaskDescription_2":{"type":"text","value":"","group_id":3,"position":2,"description":"Description of the task"},"TaskDescription_3":{"type":"text","value":"","group_id":4,"position":2,"description":"Description of the task"},"TaskDescription_4":{"type":"text","value":"","group_id":5,"position":2,"description":"Description of the task"},"TaskDescription_5":{"type":"text","value":"","group_id":6,"position":1,"description":"Description of the task"},"TaskDescription_6":{"type":"text","value":"","group_id":7,"position":2,"description":"Description of the task"},"TaskDescription_7":{"type":"text","value":"","group_id":8,"position":2,"description":"Description of the task"},"TaskDescription_8":{"type":"text","value":"","group_id":9,"position":2,"description":"Description of the task"},"TaskDescription_9":{"type":"text","value":"","group_id":10,"position":2,"description":"Description of the task"},"TaskDescription_10":{"type":"text","value":"","group_id":11,"position":2,"description":"Description of the task"}}}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/Run.json b/elab_bridge/template_parts/test_templates/Run.json
new file mode 100644
index 00000000..f69f3a65
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/Run.json
@@ -0,0 +1,46 @@
+{
+ "elabftw": {
+ "display_main_text": true,
+ "extra_fields_groups": [
+ {
+ "id": 2,
+ "name": "Run "
+ }
+ ]
+ },
+ "extra_fields": {
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "RunNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2
+ },
+ "StartTime": {
+ "type": "text",
+ "value": "",
+ "group_id": 2
+ },
+ "RunComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "description": "Description of the task"
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/bas.json b/elab_bridge/template_parts/test_templates/bas.json
new file mode 100644
index 00000000..525003d7
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/bas.json
@@ -0,0 +1,147 @@
+{
+ "elabftw": {
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "VisuoMotorLaminar_Specifique_Metadata"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Accuracy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 13
+ },
+ "Duration": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "select",
+ "value": "DMSBlocked",
+ "options": [
+ "DMSBlocked",
+ "DMSRandom",
+ "DMS",
+ "Reward schedule",
+ "Movie watching",
+ "Groove",
+ "RestingState"
+ ],
+ "group_id": 1,
+ "position": 0,
+ "blank_value_on_duplicate": false
+ },
+ "Stop Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "Start Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 1,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ " RewardType": {
+ "type": "radio",
+ "value": "liquid",
+ "options": [
+ "liquid",
+ "solid"
+ ],
+ "group_id": 1,
+ "position": 4,
+ "blank_value_on_duplicate": false
+ },
+ "FailedTrial": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 12
+ },
+ "Special Event": {
+ "type": "radio",
+ "value": "no",
+ "options": [
+ "yes",
+ "no"
+ ],
+ "group_id": 1,
+ "position": 10,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 1": {
+ "type": "users",
+ "value": "",
+ "group_id": 1,
+ "position": 7,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 2": {
+ "type": "users",
+ "value": "",
+ "group_id": 1,
+ "position": 8,
+ "blank_value_on_duplicate": false
+ },
+ "Experimenter 3": {
+ "type": "users",
+ "value": "",
+ "group_id": 1,
+ "position": 9,
+ "blank_value_on_duplicate": false
+ },
+ "RewardQuantity": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "g",
+ "ml"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 6
+ },
+ "Successful Trial": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 11
+ },
+ " Witch Color First": {
+ "type": "radio",
+ "value": "pink",
+ "options": [
+ "pink",
+ "blue",
+ "none"
+ ],
+ "group_id": 1,
+ "position": 5,
+ "blank_value_on_duplicate": false
+ },
+ "Special Event Time": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 1,
+ "position": 13,
+ "blank_value_on_duplicate": false
+ },
+ "CommentSpecialEvent": {
+ "type": "text",
+ "value": "Martin",
+ "group_id": 1,
+ "position": 14,
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/basic1.json b/elab_bridge/template_parts/test_templates/basic1.json
new file mode 100644
index 00000000..a50b808c
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/basic1.json
@@ -0,0 +1,241 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Project_BIDS_Metadata"
+ },
+ {
+ "id": 2,
+ "name": "Subject_BIDS_Metadata"
+ },
+ {
+ "id": 3,
+ "name": "Recording_BIDS_Metadata"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months",
+ "days"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 4,
+ "description": "in years, month or days",
+ "blank_value_on_duplicate": false
+ },
+ "Sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 2,
+ "position": 7,
+ "description": "",
+ "blank_value_on_duplicate": false
+ },
+ "Group": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 9,
+ "description": "Experimental group. Ex: 'control, under 10 years, ...'",
+ "blank_value_on_duplicate": false
+ },
+ "Strain": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 3,
+ "description": "The strain of the subject",
+ "blank_value_on_duplicate": false
+ },
+ "Weight": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "kg",
+ "g"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 10,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "List of individuals who contributed to the creation of the project.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 12,
+ "blank_value_on_duplicate": false
+ },
+ "Species": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "BirthDate": {
+ "type": "datetime-local",
+ "value": "",
+ "group_id": 2,
+ "position": 6,
+ "blank_value_on_duplicate": false
+ },
+ "SessionId": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 0,
+ "required": true,
+ "description": "Ex: 01, predrug , 20231206 , 20231206S01",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper).",
+ "blank_value_on_duplicate": false
+ },
+ "Handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 2,
+ "position": 8,
+ "description": "GDPR",
+ "blank_value_on_duplicate": false
+ },
+ "Modalities": {
+ "type": "select",
+ "value": [
+ "intracellular microelectrode signals"
+ ],
+ "options": [
+ "MRI",
+ "MEG",
+ "EEG",
+ "iEEG",
+ "Physio (cardiac, respiration, etc.)",
+ "Behaviour",
+ "Genetic descriptor",
+ "PET",
+ "Microscopy",
+ "NIRS",
+ "Motion",
+ "MRS",
+ "Microelectode Electrophysiology",
+ "Video",
+ "EyeTracking"
+ ],
+ "group_id": 2,
+ "position": 5,
+ "description": "The modalities recorded",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": true
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "description": "subject number or monkey name or etc",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The interpretation of the dataset. Must be one of: 'raw', 'derivative'.",
+ "blank_value_on_duplicate": false
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Used to specify provenance of the dataset.",
+ "blank_value_on_duplicate": false
+ },
+ "ProjectName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 0,
+ "description": "Experiment name including around X subjects",
+ "blank_value_on_duplicate": false
+ },
+ "SessionDate": {
+ "type": "date",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "blank_value_on_duplicate": false
+ },
+ "SubjectGUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 1,
+ "blank_value_on_duplicate": false
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Used to map a given from a BIDS URI of the form bids:",
+ "blank_value_on_duplicate": false
+ },
+ "SessionComment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 2,
+ "position": 11,
+ "description": "Ex: '53.5 or 55'",
+ "blank_value_on_duplicate": false
+ },
+ "Ethical Protocol Identifier": {
+ "type": "text",
+ "value": "default format in '5X-16X-vX'",
+ "group_id": 1,
+ "position": 1,
+ "description": "The official ethical protocol id",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/ephys.json b/elab_bridge/template_parts/test_templates/ephys.json
new file mode 100644
index 00000000..bba961bb
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ephys.json
@@ -0,0 +1,261 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "EyeTracking_BIDS_METADATA"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "description": "Add comments if needed"
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "eyetrack",
+ "group_id": 1,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 1,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 1,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 1,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter",
+ "cm"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 1,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 1,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/ephys2.json b/elab_bridge/template_parts/test_templates/ephys2.json
new file mode 100644
index 00000000..c1879e99
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/ephys2.json
@@ -0,0 +1,260 @@
+{
+ "elabftw": {
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "EyeTracking_BIDS_METADATA"
+ }
+ ]
+ },
+ "extra_fields": {
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "Comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "description": "Add comments if needed"
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "eyetrack",
+ "group_id": 1,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 1,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 1,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 1,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter",
+ "cm"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 1,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 1,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 1,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/eye-spec.json b/elab_bridge/template_parts/test_templates/eye-spec.json
new file mode 100644
index 00000000..7b9c2d50
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/eye-spec.json
@@ -0,0 +1,53 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 8,
+ "name": "General EEG Infos"
+ },
+ {
+ "id": 10,
+ "name": "Default"
+ }
+ ]
+ },
+ "extra_fields": {
+ "EEGGround": {
+ "type": "text",
+ "value": "",
+ "group_id": 8,
+ "description": "Location of the ground electrode. Ex: 'placed on right mastoid (M2)'"
+ },
+ "default EEG": {
+ "type": "text",
+ "value": "",
+ "group_id": 10
+ },
+ "EEGReference": {
+ "type": "text",
+ "value": "",
+ "group_id": 8,
+ "required": true,
+ "description": "General description of the reference scheme used (when applicable) of location of the reference electrode in the raw recordings. \n Ex: 'N/A or Single electrode placed on FCz or Multiple references'"
+ },
+ "SoftwareFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 8,
+ "required": true,
+ "description": "Object of temporal software filters applied. Each key-value pair in the JSON object is a name of the filter and an object in which its parameters are defined as key-value pairs. \n Ex: '{\"Anti-aliasing filter\": {\"half-amplitude cutoff (Hz)\": 500, \"Roll-off\": \"6dB/Octave\"}} or N/A'"
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "Hz",
+ "units": [
+ "Hz"
+ ],
+ "value": "",
+ "group_id": 8,
+ "required": true,
+ "description": "Sampling frequency (in Hz) of all the data in the recording, regardless of their type. \n Ex: '2400' "
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/eye.json b/elab_bridge/template_parts/test_templates/eye.json
new file mode 100644
index 00000000..06857c57
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/eye.json
@@ -0,0 +1,434 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Participant"
+ },
+
+ {
+ "id": 3,
+ "name": "Run "
+ },
+ {
+ "id": 4,
+ "name": "General experiment infos"
+ },
+ {
+ "id": 14,
+ "name": "EYE TRACKING SPEC "
+ }
+ ]
+ },
+ "extra_fields": {
+ "age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "GDPR !!!. In years or months. Ex: '42 or 4.4'"
+ },
+ "sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 1,
+ "position": 3,
+ "description": "GDPR"
+ },
+ "group": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "Experimental group. Ex: 'control, under 14 years, ...'"
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 1,
+ "description": "List of individuals who contributed to the creation/curation of the dataset."
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 1,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "StartTime": {
+ "type": "number",
+ "unit": "seconds",
+ "units": [
+ "seconds"
+ ],
+ "value": "",
+ "group_id": 14,
+ "position": 2,
+ "description": "Start time in seconds",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper)."
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "Run Number": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 14,
+ "position": 4,
+ "description": "One repetition of a experimental task. defined numerically"
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "subject number or monkey name"
+ },
+ "handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 1,
+ "position": 5,
+ "description": "GDPR"
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "description": "The interpretation of the dataset. For backwards compatibility, the default value is \"raw\". Must be one of: \"raw\", \"derivative\"."
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "description": "Used to specify provenance of the dataset."
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 14,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Run comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 144,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "description": "Used to map a given from a BIDS URI of the form bids:"
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "Subject GUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 1
+ },
+ "Experimenter 1": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 2,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 2": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 3,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 3": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 4,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 14,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 14,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "Experiment name": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 4,
+ "description": "En français: nom de la manip incluant X sujets / Experiment name including around X subjects"
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 3,
+ "position": 2,
+ "description": "Description of the task"
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 14,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Ex: '53.5 or 55'"
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 14,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter"
+ ],
+ "value": "",
+ "group_id": 14,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 14,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 14,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 14,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 14,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 14,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/eye_out.json b/elab_bridge/template_parts/test_templates/eye_out.json
new file mode 100644
index 00000000..1dfd285e
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/eye_out.json
@@ -0,0 +1,461 @@
+{
+ "elabftw": {
+ "display_main_text": false,
+ "extra_fields_groups": [
+ {
+ "id": 1,
+ "name": "Participant"
+ },
+ {
+ "id": 2,
+ "name": "Session"
+ },
+ {
+ "id": 4,
+ "name": "Run "
+ },
+ {
+ "id": 5,
+ "name": "General experiment infos"
+ },
+ {
+ "id": 15,
+ "name": "EYE TRACKING SPEC "
+ }
+ ]
+ },
+ "extra_fields": {
+ "age": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "years",
+ "months"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 2,
+ "description": "GDPR !!!. In years or months. Ex: '42 or 4.4'"
+ },
+ "sex": {
+ "type": "radio",
+ "options": [
+ "F",
+ "M",
+ "Others"
+ ],
+ "group_id": 1,
+ "position": 3,
+ "description": "GDPR"
+ },
+ "group": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "Experimental group. Ex: 'control, under 14 years, ...'"
+ },
+ "Authors": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 1,
+ "description": "List of individuals who contributed to the creation/curation of the dataset."
+ },
+ "Columns": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 3,
+ "description": "Names of columns in file.",
+ "blank_value_on_duplicate": false
+ },
+ "TaskName": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 1,
+ "required": true,
+ "description": "Code name of the task (no space and only alphanumeric characters).\n Ex: 'rest or facesnback or headnodding'"
+ },
+ "StartTime": {
+ "type": "number",
+ "unit": "seconds",
+ "units": [
+ "seconds"
+ ],
+ "value": "",
+ "group_id": 15,
+ "position": 2,
+ "description": "Start time in seconds",
+ "blank_value_on_duplicate": false
+ },
+ "DatasetDOI": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "The Digital Object Identifier of the dataset (not the corresponding paper)."
+ },
+ "PhysioType": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 8,
+ "description": "Defines the specific type of physiological recording",
+ "blank_value_on_duplicate": false
+ },
+ "Run Number": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 15,
+ "position": 4,
+ "description": "One repetition of a experimental task. defined numerically"
+ },
+ "Subject ID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 4,
+ "description": "subject number or monkey name"
+ },
+ "handedness": {
+ "type": "radio",
+ "options": [
+ "left",
+ "right",
+ "ambidextrous"
+ ],
+ "group_id": 1,
+ "position": 5,
+ "description": "GDPR"
+ },
+ "DatasetType": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "The interpretation of the dataset. For backwards compatibility, the default value is \"raw\". Must be one of: \"raw\", \"derivative\"."
+ },
+ "GeneratedBy": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "Used to specify provenance of the dataset."
+ },
+ "RecordedEye": {
+ "type": "select",
+ "value": [
+ "left"
+ ],
+ "options": [
+ "left",
+ "right",
+ "cyclopean"
+ ],
+ "group_id": 15,
+ "position": 14,
+ "description": "Indicates the eye tracked",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "Run comment": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 144,
+ "description": "Comment about the subject behavior during the run."
+ },
+ "DatasetLinks": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "description": "Used to map a given from a BIDS URI of the form bids:"
+ },
+ "Manufacturer": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 5,
+ "description": "Manufacturer of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "Subject GUID": {
+ "type": "text",
+ "value": "",
+ "group_id": 1,
+ "position": 1
+ },
+ "Experimenter 1": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 2,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 2": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 3,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "Experimenter 3": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": " Ex: 'Odile De Ray'"
+ },
+ "PupilFitMethod": {
+ "type": "select",
+ "value": "centre-of-mass",
+ "options": [
+ "centre-of-mass",
+ "ellipse"
+ ],
+ "group_id": 15,
+ "position": 24,
+ "description": "The method employed for fitting the pupil",
+ "blank_value_on_duplicate": false
+ },
+ "RawDataFilters": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 25,
+ "description": "Filter settings applied to eye-movement raw data.",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationType": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 16,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationUnit": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 15,
+ "position": 17,
+ "description": "Unit of \"CalibrationPosition\". ",
+ "blank_value_on_duplicate": false
+ },
+ "Experiment name": {
+ "type": "text",
+ "value": "",
+ "group_id": 5,
+ "position": 4,
+ "description": "En fran\u00e7ais: nom de la manip incluant X sujets / Experiment name including around X subjects"
+ },
+ "TaskDescription": {
+ "type": "text",
+ "value": "",
+ "group_id": 4,
+ "position": 2,
+ "description": "Description of the task"
+ },
+ "CalibrationCount": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 15,
+ "position": 14,
+ "description": "The number of calibrations corresponding to this run.",
+ "blank_value_on_duplicate": false
+ },
+ "SoftwareVersions": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 7,
+ "description": "Manufacturer's designation of software version",
+ "blank_value_on_duplicate": false
+ },
+ "EyeCameraSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 18,
+ "description": "A field to store any settings that influence the resolution and quality of the eye imagery",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackingMethod": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 24,
+ "description": "Method used to track gaze or pupil position",
+ "blank_value_on_duplicate": false
+ },
+ "HeadCircumference": {
+ "type": "number",
+ "unit": "",
+ "units": [
+ "cm"
+ ],
+ "value": "",
+ "group_id": 1,
+ "position": 6,
+ "description": "Ex: '53.5 or 55'"
+ },
+ "SamplingFrequency": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 15,
+ "position": 1,
+ "description": "Sampling frequency (in Hz) of all the data in the recording",
+ "blank_value_on_duplicate": false
+ },
+ "DeviceSerialNumber": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 4,
+ "description": "The serial number of the equipment that produced the measurements",
+ "blank_value_on_duplicate": false
+ },
+ "EyeTrackerDistance": {
+ "type": "number",
+ "unit": "meter",
+ "units": [
+ "meter"
+ ],
+ "value": "",
+ "group_id": 15,
+ "position": 19,
+ "description": "Distance (in meters) between the eye-tracker and the participant eye(s).",
+ "blank_value_on_duplicate": false
+ },
+ "CalibrationPosition": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 15,
+ "description": "The type of the calibration procedure executed last",
+ "blank_value_on_duplicate": false
+ },
+ "GazeMappingSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 22,
+ "description": "Description of gaze-mapping settings. ",
+ "blank_value_on_duplicate": false
+ },
+ "ScreenAOIDefinition": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 26,
+ "description": "A description of the shape of the Screen AOIs and what coordinates are used.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateUnits": {
+ "type": "select",
+ "value": "pixel",
+ "options": [
+ "pixel",
+ "mm",
+ "cm"
+ ],
+ "group_id": 15,
+ "position": 11,
+ "blank_value_on_duplicate": false
+ },
+ "EnvironmentCoordinates": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 9,
+ "description": "Coordinates origin (or zero), for gaze-on-screen coordinates",
+ "blank_value_on_duplicate": false
+ },
+ "ManufacturersModelName": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 6,
+ "description": "Manufacturer's model name of the equipment that produced the measurements.",
+ "blank_value_on_duplicate": false
+ },
+ "SampleCoordinateSystem": {
+ "type": "select",
+ "value": "gaze-on-screen",
+ "options": [
+ "gaze-on-screen",
+ "eye-in-head",
+ "gaze-in-world"
+ ],
+ "group_id": 15,
+ "position": 12,
+ "description": "Coordinate system of the gaze position recordings",
+ "allow_multi_values": true,
+ "blank_value_on_duplicate": false
+ },
+ "AverageCalibrationError": {
+ "type": "number",
+ "unit": "",
+ "units": [],
+ "value": "",
+ "group_id": 15,
+ "position": 13,
+ "description": "Average calibration error in visual degree. ",
+ "blank_value_on_duplicate": false
+ },
+ "MaximalCalibrationError": {
+ "type": "number",
+ "unit": "degrees",
+ "units": [
+ "degrees"
+ ],
+ "value": "",
+ "group_id": 15,
+ "position": 23,
+ "description": "Maximal calibration error in degrees",
+ "blank_value_on_duplicate": false
+ },
+ "FeatureDetectionSettings": {
+ "type": "text",
+ "value": "",
+ "group_id": 15,
+ "position": 21,
+ "description": "Description of feature detection settings. For example, minimum/maximum pupil size.",
+ "blank_value_on_duplicate": false
+ },
+ "session_id": {
+ "type": "text",
+ "value": "",
+ "group_id": 2,
+ "position": 0,
+ "required": true,
+ "description": "Ex: '01 or predrug or 20231206'"
+ },
+ "Session date": {
+ "type": "date",
+ "value": "",
+ "group_id": 2,
+ "position": "2",
+ "description": "The date of the recording",
+ "blank_value_on_duplicate": true
+ },
+ "Session duration": {
+ "type": "number",
+ "value": "",
+ "group_id": 2,
+ "position": "3",
+ "description": "The duration of the session [in minutes]",
+ "blank_value_on_duplicate": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/elab_bridge/template_parts/test_templates/tms.json b/elab_bridge/template_parts/test_templates/tms.json
new file mode 100644
index 00000000..20f7ce93
--- /dev/null
+++ b/elab_bridge/template_parts/test_templates/tms.json
@@ -0,0 +1,56 @@
+{
+ "elabftw": {
+ "display_main_text": true,
+ "extra_fields_groups": [
+ {
+ "id": 18,
+ "name": "LaureProjectSPEC"
+ }
+ ]
+ },
+ "extra_fields": {
+ "MotorThreshold": {
+ "type": "text",
+ "value": "",
+ "description": "Resting motor threshold",
+ "group_id": 18,
+ "position": 0
+ },
+ "intensityFEF": {
+ "type": "text",
+ "value": "",
+ "description": "TMS intensity for FEF stimulation (110% motor threshold)",
+ "group_id": 18,
+ "position": 1
+ },
+ "intensitySham": {
+ "type": "text",
+ "value": "",
+ "description": "TMS intensity for Sham stimulation (130% motor threshold)",
+ "group_id": 18,
+ "position": 2
+ },
+ "MRISubNumber": {
+ "type": "text",
+ "value": "",
+ "description": "Subject number for MRI data",
+ "group_id": 18,
+ "position": 3
+ },
+ "RobotTargets": {
+ "type": "text",
+ "value": "",
+ "description": "Corresponding anatomical targets for robot targets",
+ "group_id": 18,
+ "position": 4
+ },
+ "UseRobot": {
+ "type": "select",
+ "value": "Yes",
+ "options": ["Yes", "No", "Tried but did not work"],
+ "group_id": 18,
+ "description": "Did you use the robot for this session?",
+ "position": 5
+ }
+ }
+}
diff --git a/elab_bridge/tests/test_Merge.py b/elab_bridge/tests/test_Merge.py
new file mode 100644
index 00000000..da3b2e6d
--- /dev/null
+++ b/elab_bridge/tests/test_Merge.py
@@ -0,0 +1,116 @@
+import unittest
+import tempfile
+import os
+import json
+from elab_bridge.Merge import (
+ safe_load_json,
+ get_a_jsonfile_structure,
+ get_indices,
+ replace_id,
+ merge_jsonfiles
+)
+
+
+class TestJSONMerge(unittest.TestCase):
+ def setUp(self):
+ """Set up temporary JSON files for testing."""
+ self.temp_files = []
+ self.sample_json1 = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 1, "name": "Group 1"},
+ {"id": 2, "name": "Group 2"}
+ ]
+ },
+ "extra_fields": {
+ "field_1": {"group_id": 1, "value": "Test 1"},
+ "field_2": {"group_id": 2, "value": "Test 2"}
+ }
+ }
+ self.sample_json2 = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 4, "name": "New group"},
+ {"id": 5, "name": "unwanted group"}
+ ]
+ },
+ "extra_fields": {
+ "field_4": {"group_id": 4, "value": "New TEST"},
+ "field_5": {"group_id": 5, "value": "unwanted"}
+ }
+ }
+ self.temp_files.append(self._create_temp_file(self.sample_json1))
+ self.temp_files.append(self._create_temp_file(self.sample_json2))
+
+ def tearDown(self):
+ """Clean up temporary files."""
+ for temp_file in self.temp_files:
+ os.unlink(temp_file)
+
+ def _create_temp_file(self, data):
+ """Helper function to create a temporary file with JSON content."""
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".json")
+ with open(temp_file.name, 'w') as f:
+ json.dump(data, f)
+ return temp_file.name
+
+ def test_safe_load_json(self):
+ """Test safe loading of JSON files."""
+ data = safe_load_json(self.temp_files[0])
+ self.assertEqual(data, self.sample_json1)
+
+ def test_get_a_jsonfile_structure(self):
+ """Test extracting structure from a JSON file."""
+ groups, fields = get_a_jsonfile_structure(self.temp_files[0])
+ print(groups)
+ print(fields)
+
+ self.assertEqual(groups, [{"id": 1, "name": "Group 1"}, {"id": 2, "name": "Group 2"}])
+ self.assertEqual(fields, {
+ "field_1": {"group_id": 1, "value": "Test 1"},
+ "field_2": {"group_id": 2, "value": "Test 2"}
+ })
+
+ def test_get_indices(self):
+ """Test finding the next available index."""
+ groups = [{"id": 1}, {"id": 2}]
+ self.assertEqual(get_indices(groups), 3)
+ self.assertEqual(get_indices([]), 1)
+
+ def test_replace_id(self):
+ """Test replacing IDs in groups and fields."""
+ groups = [{"id": 1, "name": "Group 1"}]
+ fields = {"field_1": {"group_id": 1, "value": "Value 1"}}
+ new_groups, new_fields = replace_id(groups, fields, 10)
+ expected_groups = [{"id": 10, "name": "Group 1"}]
+ expected_fields = {"field_1": {"group_id": 10, "value": "Value 1"}}
+ self.assertEqual(new_groups, expected_groups)
+ self.assertEqual(new_fields, expected_fields)
+
+ def test_merge_jsonfiles(self):
+ """Test merging multiple JSON files into one."""
+ json_output = tempfile.NamedTemporaryFile(delete=False, suffix=".json").name
+ merge_jsonfiles(self.temp_files, json_output)
+ with open(json_output, 'r') as f:
+ merged_data = json.load(f)
+ expected_data = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 1, "name": "Group 1"},
+ {"id": 2, "name": "Group 2"},
+ {"id": 3, "name": "New group"},
+ {"id": 4, "name": "unwanted group"}
+ ]
+ },
+ "extra_fields": {
+ "field_1": {"group_id": 1, "value": "Test 1"},
+ "field_2": {"group_id": 2, "value": "Test 2"},
+ "field_4": {"group_id": 3, "value": "New TEST"},
+ "field_5": {"group_id": 4, "value": "unwanted"}
+ }
+ }
+ self.assertEqual(merged_data, expected_data)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/elab_bridge/tests/test_extractor.py b/elab_bridge/tests/test_extractor.py
new file mode 100644
index 00000000..84e7392f
--- /dev/null
+++ b/elab_bridge/tests/test_extractor.py
@@ -0,0 +1,239 @@
+import unittest
+import json
+import os
+from tempfile import NamedTemporaryFile
+from elab_bridge.Extractor import (
+ loadfile,
+ savefile,
+ extract_groupfield_detail,
+ construct_extracted_json,
+ add_a_groupfield,
+ complete_groupfield_in_jsonfile,
+ complete_jsonfile1_with_jsonfile2_groupefield,
+ orderjsonfile,
+)
+
+
+class TestJsonOperations(unittest.TestCase):
+
+ def setUp(self):
+ """Setup temporary JSON files for testing."""
+ self.temp_file = NamedTemporaryFile(delete=False, mode='w+', suffix='.json')
+ self.sample_json = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 1, "name": "Group 1"},
+ {"id": 2, "name": "Group 2"}
+ ]
+ },
+ "extra_fields": {
+ "field_1": {"group_id": 1, "value": "Test 1"},
+ "field_2": {"group_id": 2, "value": "Test 2"}
+ }
+ }
+ json.dump(self.sample_json, self.temp_file)
+ self.temp_file.close()
+
+ def tearDown(self):
+ """Clean up temporary files."""
+ os.unlink(self.temp_file.name)
+
+ def test_loadfile(self):
+ """Test loading a valid JSON file."""
+ data = loadfile(self.temp_file.name)
+ self.assertEqual(data, self.sample_json)
+
+ def test_loadfile_invalid(self):
+ """Test loading an invalid JSON file."""
+ with open(self.temp_file.name, 'w') as f:
+ f.write("{invalid_json")
+ with self.assertRaises(ValueError):
+ loadfile(self.temp_file.name)
+
+ def test_savefile(self):
+ """Test saving data to a JSON file."""
+ test_data = {"test": "data"}
+ savefile(self.temp_file.name, test_data)
+ with open(self.temp_file.name, 'r') as f:
+ loaded_data = json.load(f)
+ self.assertEqual(loaded_data, test_data)
+
+ def test_extract_groupfield_detail(self):
+ """Test extracting groupfield details."""
+ group_name, fields = extract_groupfield_detail(self.temp_file.name, 1)
+ self.assertEqual(group_name, "Group 1")
+ self.assertEqual(fields, [{"field_1": {"group_id": None, "value": "Test 1"}}])
+
+ def test_construct_extracted_json(self):
+ """Test constructing extracted JSON."""
+ output_file = NamedTemporaryFile(delete=False, mode='w+', suffix='.json')
+ result = construct_extracted_json(self.temp_file.name, 1, 10, output_file.name)
+ print(result, "resultssss")
+ self.assertEqual(
+ result["elabftw"]["extra_fields_groups"],
+ [{"id": 10, "name": "Group 1"}]
+ )
+ os.unlink(output_file.name)
+
+ def test_orderjsonfile(self):
+ """Test ordering JSON file."""
+ # Define ordered group names
+ ordered_groups = ["Group 2", "Group 1"]
+
+ # Call the function with valid inputs
+ ordered_data = orderjsonfile(self.temp_file.name, ordered_groups)
+ print(ordered_data, "ordered_data")
+ # Assert ordered_data is not None
+ self.assertIsNotNone(ordered_data, "ordered_data is None")
+
+ # Assert 'elabftw' exists in the result
+ self.assertIn("elabftw", ordered_data, "'elabftw' key is missing in ordered_data")
+
+ # Assert 'extra_fields_groups' exists and is a list
+ self.assertIn("extra_fields_groups", ordered_data["elabftw"],
+ "'extra_fields_groups' key is missing in ordered_data['elabftw']")
+ self.assertIsInstance(ordered_data["elabftw"]["extra_fields_groups"], list,
+ "'extra_fields_groups' is not a list")
+
+ # Check that all groups are ordered correctly
+ for i, group_name in enumerate(ordered_groups):
+ self.assertEqual(ordered_data["elabftw"]["extra_fields_groups"][i]["name"], group_name,
+ f"Group {i} is not ordered correctly")
+
+ # Additional debug print (optional)
+ print(
+ f"Ordered data groups: {[group['name'] for group in ordered_data['elabftw']['extra_fields_groups']]}")
+
+ def test_add_a_groupfield(self):
+ """Test adding groupfields at various indices."""
+ # Define new groupfields
+ new_field1 = [{"field_3": {"group_id": 2, "value": "Test 3"}}]
+ groupe_name1 = "new group 1"
+
+ new_field2 = [{"field_4": {"group_id": 5, "value": "Test 4"}}]
+ groupe_name2 = "middle group"
+
+ new_field3 = [{"field_5": {"group_id": 10, "value": "Test 5"}}]
+ groupe_name3 = "final group"
+
+ # Add a groupfield at index 1
+ result1 = add_a_groupfield(self.temp_file.name, 1, new_field1, groupe_name1)
+
+ # Add another groupfield in the middle (index 5)
+ result2 = add_a_groupfield(self.temp_file.name, 5, new_field2, groupe_name2)
+
+ # Add another groupfield at the final index (index 10)
+ result3 = add_a_groupfield(self.temp_file.name, 10, new_field3, groupe_name3)
+
+ # Assertions for the first group
+ self.assertIn("elabftw", result1, "'elabftw' key missing in result")
+ self.assertIn("extra_fields_groups", result1["elabftw"],
+ "'extra_fields_groups' key missing")
+ self.assertTrue(
+ any(group['id'] == 1 and group['name'] == groupe_name1 for group in
+ result1["elabftw"]["extra_fields_groups"]),
+ "New groupfield 1 not added"
+ )
+ self.assertIn("field_3", result1["extra_fields"], "'field_3' missing in extra_fields")
+ self.assertEqual(result1["extra_fields"]["field_3"]["group_id"], 1,
+ "Incorrect group_id for field_3")
+
+ # Assertions for the middle group
+ self.assertTrue(
+ any(group['id'] == 5 and group['name'] == groupe_name2 for group in
+ result2["elabftw"]["extra_fields_groups"]),
+ "Middle groupfield not added"
+ )
+ self.assertIn("field_4", result2["extra_fields"], "'field_4' missing in extra_fields")
+ self.assertEqual(result2["extra_fields"]["field_4"]["group_id"], 5,
+ "Incorrect group_id for field_4")
+
+ # Assertions for the final group
+ self.assertTrue(
+ any(group['id'] == 10 and group['name'] == groupe_name3 for group in
+ result3["elabftw"]["extra_fields_groups"]),
+ "Final groupfield not added"
+ )
+ self.assertIn("field_5", result3["extra_fields"], "'field_5' missing in extra_fields")
+ self.assertEqual(result3["extra_fields"]["field_5"]["group_id"], 10,
+ "Incorrect group_id for field_5")
+
+ def test_complete_jsonfile1_with_jsonfile2_groupefield(self):
+ """Test combining two JSON files by extracting and adding group fields.
+ This test does not mock other functions; instead, it tests the function as a whole.
+ It qualifies as an integration test, verifying the interaction between all components.
+ """
+
+ # Define the source JSON file (to be completed)
+ sample_json = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 1, "name": "Group 1"},
+ {"id": 2, "name": "Group 2"}
+ ]
+ },
+ "extra_fields": {
+ "field_1": {"group_id": 1, "value": "Test 1"},
+ "field_2": {"group_id": 2, "value": "Test 2"}
+ }
+ }
+
+ # Define the JSON file to extract data from
+ sample_json2 = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 4, "name": "New group"},
+ {"id": 5, "name": "unwanted group"}
+ ]
+ },
+ "extra_fields": {
+ "field_4": {"group_id": 4, "value": "New TEST"},
+ "field_5": {"group_id": 5, "value": "unwanted"}
+ }
+ }
+
+ # Create temporary files for testing
+ jsonfiletocompleted = NamedTemporaryFile(delete=False, mode='w+', suffix='.json')
+ json.dump(sample_json, jsonfiletocompleted)
+ jsonfiletocompleted.close()
+
+ jsonfiletoextract = NamedTemporaryFile(delete=False, mode='w+', suffix='.json')
+ json.dump(sample_json2, jsonfiletoextract)
+ jsonfiletoextract.close()
+
+ # Define parameters for the function
+ indice = 4
+ new_indice = 1
+
+ # Call the function under test
+ json_completed = complete_jsonfile1_with_jsonfile2_groupefield(
+ jsonfiletocompleted.name, jsonfiletoextract.name, indice, new_indice
+ )
+
+ # Define the expected result
+ expected_json = {
+ "elabftw": {
+ "extra_fields_groups": [
+ {"id": 1, "name": "New group"},
+ {"id": 2, "name": "Group 1"},
+ {"id": 3, "name": "Group 2"}
+ ]
+ },
+ "extra_fields": {
+ "field_4": {"group_id": 1, "value": "New TEST"},
+ "field_1": {"group_id": 2, "value": "Test 1"},
+ "field_2": {"group_id": 3, "value": "Test 2"}
+ }
+ }
+
+ # Validate the output
+ self.assertEqual(json_completed, expected_json,
+ "The completed JSON does not match the expected structure.")
+
+ # Clean up temporary files
+ os.unlink(jsonfiletocompleted.name)
+ os.unlink(jsonfiletoextract.name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/requirements.txt b/requirements.txt
index 89cba9d6..c323a527 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,8 @@
-pandas
-pytest
+pandas~=2.2.0
+pytest~=7.4.4
gitpython
pycap>=2.0.0
-elabapi_python
\ No newline at end of file
+elabapi_python
+PyYAML~=6.0.1
+setuptools~=68.2.0
+numpy~=1.26.3
\ No newline at end of file