Skip to content
Snippets Groups Projects
Commit 789dfe8a authored by Toumji Abdallah's avatar Toumji Abdallah
Browse files

FormHandler.py tests

parent b80d06c3
No related branches found
No related tags found
No related merge requests found
Showing with 247 additions and 130 deletions
......@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Python 2.7 (pythonProject)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pythonProject)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (pythonProject) (3)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
......@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (pythonProject)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.12 (pythonProject) (3)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -463,6 +463,10 @@ class Application(tk.Frame):
command=self.actual_project_state)
self.show_project_button.pack()
open_project_button = tk.Button(self.integrate_sidecar_frame, text='Open project',
command=lambda: os.startfile(self.project_directory))
open_project_button.pack()
def integrate_sidecar_file(self):
""" This method is used to integrate a sidecar to the new BIDS project.
......@@ -722,7 +726,7 @@ class Application(tk.Frame):
:return: list
A list containing the optimal emplacements of the sidecar
"""
emplacement = self.get_entities(experiments_files)
emplacement = Tools.get_entities(experiments_files, self.project_directory)
path_list = []
no_shared = False
......@@ -776,37 +780,6 @@ class Application(tk.Frame):
concerned_files[0].split('.')[-1]) + path + sidecar_type)
return path_list
def get_entities(self, experiments_files):
""" This method is used to get the entities of the experiments.
The entities of the experiments are found.
:param: list
A list of the experiments files paths.
:return: dict
A dict containing the entities of the experiments in the form {subject : {session : {entity : entity_value}, ...}, ...}.
Where the third level is the file, the second level is the session and the first level is the subject.
"""
entities = {}
for experiment in experiments_files:
directory = experiment.split(self.project_directory)[1].split('/')
sub = ''
ses = ''
for info in directory[:-1]:
if 'sub-' in info:
sub = info
if sub not in entities:
entities[sub] = {}
elif 'ses-' in info:
ses = info
if ses not in entities[sub]:
entities[sub][ses] = []
if ses == '':
ses = 'ses-1'
if ses not in entities[sub]:
entities[sub][ses] = []
entities[sub][ses].append(experiment)
return entities
def place_created_sidecar(self):
""" This method is used to place the created sidecar to the new BIDS project.
......
......@@ -184,7 +184,7 @@ class Form:
self.import_data_md(path)
def import_data_json(self, path):
with open(os.path.join(path, self.form[0]), 'r') as file:
with open(path, 'r') as file:
data = json.load(file)
for entry in self.entries:
if entry.get_name() in data:
......@@ -192,7 +192,7 @@ class Form:
self.notify()
def import_data_md(self, path):
with open(os.path.join(path, self.form[0]), 'r') as file:
with open(path, 'r') as file:
data = file.read()
self.entries[0].insert(tk.END, data)
self.notify()
......
......@@ -4,13 +4,13 @@
"requirement level" : "required",
"multiple" : false,
"description" : "Name of the dataset",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"BIDSVersion" : {
"requirement level" : "required",
"multiple" : false,
"description" : "The version of the BIDS standard that was used",
"valid condition": "len(value) > 0 ; float(value) > 0"
"valid condition": "len(str(value)) > 0 ; float(value) > 0"
},
"HEDVersion" : {
"requirement level": "recommended",
......@@ -22,7 +22,7 @@
"requirement level": "optional",
"multiple": true,
"description": "Used to map a given <dataset-name> from a BIDS URI of the form bids:<dataset-name>:path/within/dataset to a local or remote location. The <dataset-name>: \"\" (an empty string) is a reserved keyword that MUST NOT be a key in DatasetLinks (example: bids::path/within/dataset).",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"DatasetType" : {
"requirement level" : "recommended",
......@@ -34,49 +34,49 @@
"requirement level" : "recommended",
"multiple" : false,
"description" : "The license for the dataset. The use of license name abbreviations is RECOMMENDED for specifying a license (see Licenses). The corresponding full license text MAY be specified in an additional LICENSE file.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"Authors" : {
"requirement level" : "recommended",
"multiple" : true,
"description" : "List of individuals who contributed to the creation/curation of the dataset.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"Acknowledgements" : {
"requirement level" : "optional",
"multiple" : false,
"description" : "Text acknowledging contributions of individuals or institutions other than those listed in Authors or Funding.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"HowToAcknowledge" : {
"requirement level" : "optional",
"multiple" : false,
"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.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"Funding" : {
"requirement level" : "optional",
"multiple" : true,
"description" : "List of sources of funding (grant numbers).",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"EthicsApprovals" : {
"requirement level" : "optional",
"multiple" : true,
"description" : "List of ethics committee approvals of the research protocols and/or protocol identifiers.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"ReferencesAndLinks" : {
"requirement level" : "optional",
"multiple" : true,
"description" : "List of references to publications that contain information on the dataset. A reference may be textual or a URI.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"DatasetDOI" : {
"requirement level" : "optional",
"multiple" : false,
"description" : "The Digital Object Identifier of the dataset (not the corresponding paper). DOIs SHOULD be expressed as a valid URI; bare DOIs such as 10.0.2.3/dfjj.10 are DEPRECATED.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"GeneratedBy" : {
"requirement level" : "optional",
......@@ -87,31 +87,31 @@
"requirement level" : "required",
"multiple" : false,
"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.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"Version" : {
"requirement level" : "recommended",
"multiple" : false,
"description" : "Version of the pipeline.",
"valid condition": "len(value) > 0 ; float(value) > 0"
"valid condition": "len(str(value)) > 0 ; float(value) > 0"
},
"Description" : {
"requirement level" : "optional",
"multiple" : false,
"description" : "Plain-text description of the pipeline or process that generated the outputs. RECOMMENDED if Name is \"Manual\".",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"CodeURL" : {
"requirement level" : "optional",
"multiple" : false,
"description" : "URL where the code used to generate the dataset may be found.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
},
"Container" : {
"requirement level": "optional",
"multiple": false,
"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 with string values.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
}
}
},
......@@ -119,7 +119,7 @@
"requirement level" : "optional",
"multiple" : true,
"description" : "Used to specify the locations and relevant attributes of all source datasets. Valid keys in each object include \"URL\", \"DOI\" (see URI), and \"Version\" with string values.",
"valid condition": "len(value) > 0"
"valid condition": "len(str(value)) > 0"
}
},
"participants.tsv" : {
......@@ -131,12 +131,12 @@
"age" : {
"requirement level": "recommended",
"description": "Age of the participant at time of testing",
"valid condition": "len(value) > 0 ; float(value) > 0 ; float(value) < 120"
"valid condition": "len(str(value)) > 0 ; float(value) > 0 ; float(value) < 120"
},
"handedness" : {
"requirement level": "recommended",
"description": "Handedness of the participant",
"valid condition": "value in ['R', 'L', 'A']"
"valid condition": "value in ['R', 'L', 'A', 'r', 'l', 'a']"
}
},
"participants.json" : {
......
This diff is collapsed.
......@@ -16,6 +16,38 @@ import os
from re import search
def get_entities(experiments_files, project_directory):
""" This method is used to get the entities of the experiments.
The entities of the experiments are found.
:param: list
A list of the experiments files paths.
:return: dict
A dict containing the entities of the experiments in the form {subject : {session : {entity : entity_value}, ...}, ...}.
Where the third level is the file, the second level is the session and the first level is the subject.
"""
entities = {}
for experiment in experiments_files:
directory = experiment.split(project_directory)[1].split('/')
sub = ''
ses = ''
for info in directory[:-1]:
if 'sub-' in info:
sub = info
if sub not in entities:
entities[sub] = {}
elif 'ses-' in info:
ses = info
if ses not in entities[sub]:
entities[sub][ses] = []
if ses == '':
ses = 'ses-1'
if ses not in entities[sub]:
entities[sub][ses] = []
entities[sub][ses].append(experiment)
return entities
def get_entities_single_file(file):
""" This method is used to get the entities of a file.
......
import os
import unittest
from BIDSHandler.CreationTool.FormHandler import FormHandler
import tkinter as tk
import pandas as pd
class FormHandlerTestCase(unittest.TestCase):
def setUp(self):
self.frame = tk.Toplevel()
necessary_forms = ["dataset_description.json", "participants.tsv"]
# Initialize a FormHandler instance here
# You might need to adjust this to match your actual setup
self.form_handler = FormHandler(self.frame, necessary_forms, '../CreationTool/res/Requirements.json')
def test_show_forms(self):
# Test that the form at index 0 is shown
self.form_handler.show_forms(0)
self.assertTrue(self.form_handler.form_frame_list[0].frame.grid_info())
# Test that the form at index 1 is not shown
self.assertFalse(self.form_handler.form_frame_list[1].frame.grid_info())
def test_is_valid_mandatory(self):
# This test open a notification window, so it is not suitable for automated testing
# To Do: Find a way to test this without opening a window
path = os.path.join(os.path.dirname(__file__), "res", "test_dataset_description.json")
index = 0
self.assertFalse(
self.form_handler.form_frame_list[index].is_valid_mandatory()
)
self.form_handler.import_data(index, path)
self.assertTrue(
self.form_handler.form_frame_list[index].is_valid_mandatory()
)
path = os.path.join(os.path.dirname(__file__), "res", "test_participants.tsv")
false_path = os.path.join(os.path.dirname(__file__), "res", "test_false_participants.tsv")
index = 1
# Actually a tsv is considered valid if it is empty, this might be subject to change in the future
self.assertTrue(
self.form_handler.form_frame_list[index].is_valid_mandatory()
)
self.form_handler.import_data(index, false_path)
self.assertFalse(
self.form_handler.form_frame_list[index].is_valid_mandatory()
)
self.form_handler.import_data(index, path)
self.assertTrue(
self.form_handler.form_frame_list[index].is_valid_mandatory()
)
def test_import_data(self):
path = os.path.join(os.path.dirname(__file__), "res", "test_participants.tsv")
index = 1
self.form_handler.import_data(index, path)
expected_df = pd.read_csv(path, sep="\t")
self.assertTrue(expected_df.equals(self.form_handler.form_frame_list[index].table.model.df))
def test_save_forms(self):
path = os.path.join(os.path.dirname(__file__), "res", "test_participants.tsv")
result_path = os.path.join(os.path.dirname(__file__), "res", "results")
result_file_path = os.path.join(result_path, "participants.tsv")
index = 1
self.form_handler.import_data(index, path)
self.form_handler.save_forms(1, result_path)
expected_df = pd.read_csv(path, sep="\t")
result_df = pd.read_csv(result_file_path, sep="\t")
self.assertTrue(expected_df.equals(result_df))
if __name__ == '__main__':
unittest.main()
participant_id age handedness
sub-01 18 r
sub-02 18 l
sub-03 25 l
name type units low_cutoff high_cutoff description sampling_frequency status status_description
FPz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
Fz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
F1 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
F2 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
FCz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
FC1 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
FC2 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
Cz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
C1 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
C2 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
CPz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
CP1 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
CP2 EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
Pz EEG V 0.0 256.0 ElectroEncephaloGram 512.0 good n/a
Aux1 GSR S 0.0 256.0 Galvanic skin response (electrodermal activity, EDA) 512.0 good n/a
{"Name": "bonjour", "BIDSVersion": "1.0", "HEDVersion": ["1.0","5.4.2"]}
\ No newline at end of file
participant_id age handedness
sub-01 18 r
sub-02 16
sub-03 25 l
participant_id age handedness
sub-01 18 r
sub-02 18 l
sub-03 25 l
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment