diff --git a/.idea/DigLabTools.iml b/.idea/DigLabTools.iml index 57c2c965..ba3d9f56 100644 --- a/.idea/DigLabTools.iml +++ b/.idea/DigLabTools.iml @@ -4,7 +4,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index 0ab07188..3a0b99de 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 33616f73..ff388e61 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,7 +4,9 @@ - + + + @@ -41,29 +44,53 @@ - { + "keyToString": { + "Python tests.pytest for test_Merge.TestJSONMerge.executor": "Run", + "Python tests.pytest for test_Merge.TestJSONMerge.test_get_a_jsonfile_structure.executor": "Run", + "Python tests.pytest for test_Merge.TestJSONMerge.test_get_indices.executor": "Run", + "Python tests.pytest for test_Merge.TestJSONMerge.test_merge_jsonfiles.executor": "Run", + "Python tests.pytest for test_Merge.TestJSONMerge.test_replace_id.executor": "Run", + "Python tests.pytest for test_Merge.TestJSONMerge.test_safe_load_json.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.test_add_a_groupfield.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.test_complete_jsonfile1_with_jsonfile2_groupefield.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.test_construct_extracted_json.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.test_orderjsonfile.executor": "Run", + "Python tests.pytest for test_extractor.TestJsonOperations.test_orderjsonfile.test_add_a_groupfield.executor": "Run", + "Python tests.pytest for test_extractor.test_complete_jsonfile1_with_jsonfile2_groupefield.executor": "Run", + "Python tests.pytest in test_extractor.py.executor": "Run", + "Python.BidsDatatype.executor": "Run", + "Python.Createdirectory.executor": "Run", + "Python.Createfile.executor": "Run", + "Python.Extractor.executor": "Run", + "Python.Generator.executor": "Run", + "Python.Modality.executor": "Run", + "Python.Test_export_bids.executor": "Run", + "Python.launch.executor": "Run", + "Python.lunch.executor": "Run", + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "git-widget-placeholder": "cleanerRemote", + "last_opened_file_path": "/home/INT/idrissou.f/PycharmProjects/DigLabTools/elab_bridge/template_parts/test_templates", + "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" } -}]]> - - +} + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - - - + + + + + - @@ -194,6 +321,22 @@ + + + + + + + + + + + + + + + + - @@ -229,19 +468,53 @@ - + + + + + file://$PROJECT_DIR$/elab_bridge/server_interface.py + + + - - + - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bep32v01/BidsDatatype.py b/bep32v01/BidsDatatype.py deleted file mode 100644 index 900cea5a..00000000 --- a/bep32v01/BidsDatatype.py +++ /dev/null @@ -1,54 +0,0 @@ -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 deleted file mode 100644 index f61f77cd..00000000 --- a/bep32v01/BidsDirectoryStructure.py +++ /dev/null @@ -1,144 +0,0 @@ -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 deleted file mode 100644 index 447dff9d..00000000 --- a/bep32v01/BidsEmptyRepositoryGenerator.py +++ /dev/null @@ -1,42 +0,0 @@ -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 deleted file mode 100644 index bce8329d..00000000 --- a/bep32v01/BidsEntity.py +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index 4a071415..00000000 --- a/bep32v01/BidsFilestructure.py +++ /dev/null @@ -1,148 +0,0 @@ -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 deleted file mode 100644 index 6a2019ea..00000000 --- a/bep32v01/BidsModality.py +++ /dev/null @@ -1,31 +0,0 @@ -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 deleted file mode 100644 index 4a2f1044..00000000 --- a/bep32v01/Createdirectory.py +++ /dev/null @@ -1,90 +0,0 @@ -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 deleted file mode 100644 index a8f10d60..00000000 --- a/bep32v01/Createfile.py +++ /dev/null @@ -1,137 +0,0 @@ -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 deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/CITATION.cff b/bep32v01/Essaie/CITATION.cff deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/LICENSE b/bep32v01/Essaie/LICENSE deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/README b/bep32v01/Essaie/README deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/README.md b/bep32v01/Essaie/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/README.rst b/bep32v01/Essaie/README.rst deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/README.txt b/bep32v01/Essaie/README.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/dataset_description.json b/bep32v01/Essaie/dataset_description.json deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/fichier.csv b/bep32v01/Essaie/fichier.csv deleted file mode 100644 index 25de6e16..00000000 --- a/bep32v01/Essaie/fichier.csv +++ /dev/null @@ -1,2 +0,0 @@ -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 deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/participants.json b/bep32v01/Essaie/participants.json deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/participants.tsv b/bep32v01/Essaie/participants.tsv deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/samples.json b/bep32v01/Essaie/samples.json deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/Essaie/samples.tsv b/bep32v01/Essaie/samples.tsv deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/__init__.py b/bep32v01/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/bep32v01/helper.py b/bep32v01/helper.py deleted file mode 100644 index 16d0f850..00000000 --- a/bep32v01/helper.py +++ /dev/null @@ -1,110 +0,0 @@ -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 deleted file mode 100644 index 83630806..00000000 --- a/bep32v01/launch.py +++ /dev/null @@ -1,34 +0,0 @@ -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 deleted file mode 100644 index e94858f7..00000000 --- a/bep32v01/ressources/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml b/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da..00000000 --- a/bep32v01/ressources/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/misc.xml b/bep32v01/ressources/.idea/misc.xml deleted file mode 100644 index 6eeaaf25..00000000 --- a/bep32v01/ressources/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/modules.xml b/bep32v01/ressources/.idea/modules.xml deleted file mode 100644 index 8efbbeb2..00000000 --- a/bep32v01/ressources/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/ressources.iml b/bep32v01/ressources/.idea/ressources.iml deleted file mode 100644 index d0876a78..00000000 --- a/bep32v01/ressources/.idea/ressources.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/vcs.xml b/bep32v01/ressources/.idea/vcs.xml deleted file mode 100644 index b2bdec2d..00000000 --- a/bep32v01/ressources/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/bep32v01/ressources/.idea/workspace.xml b/bep32v01/ressources/.idea/workspace.xml deleted file mode 100644 index 258be40d..00000000 --- a/bep32v01/ressources/.idea/workspace.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - "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 - - - - - - \ No newline at end of file diff --git a/bep32v01/ressources/schema/BIDS_VERSION b/bep32v01/ressources/schema/BIDS_VERSION deleted file mode 100644 index a01185b4..00000000 --- a/bep32v01/ressources/schema/BIDS_VERSION +++ /dev/null @@ -1 +0,0 @@ -1.10.0-dev diff --git a/bep32v01/ressources/schema/README.md b/bep32v01/ressources/schema/README.md deleted file mode 100644 index d8013145..00000000 --- a/bep32v01/ressources/schema/README.md +++ /dev/null @@ -1,1025 +0,0 @@ -# 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-