diff --git a/tools/cobidas/convert_csv_to_schema.py b/tools/cobidas/convert_csv_to_schema.py new file mode 100644 index 000000000..8f4e78cde --- /dev/null +++ b/tools/cobidas/convert_csv_to_schema.py @@ -0,0 +1,57 @@ +import os +from create_schema import create_schema + +schema_to_create = ["neurovault", "pet", "mri", "eyetracker"] + +# ----------------------------------------------------------------------------- +# PARAMETERS +# ----------------------------------------------------------------------------- +# modify the following lines to match your needs + +# OUTPUT_DIR ---------------------------------------- +# where the files will be written on your machine: the local repository +# corresponding to the remote where of the reproschema will be hosted + + +OUTPUT_DIR = "/home/remi/github/cobidas_chckls" +# OUTPUT_DIR = "/home/remi/github/cobidas-PET" +# OUTPUT_DIR = "/home/remi/github/cobidas" +# OUTPUT_DIR = "/home/remi/github/cobidas-eyetracker" + +# REMOTE_REPO ---------------------------------------- +# Placeholder to insert in all instances of the remote repo that will host the +# schema representation +# Most likely you just need to replace Remi-Gau in the following line by your +# github username + +REMOTE_REPO = "https://raw.githubusercontent.com/Remi-Gau/cobidas_chckls/" +# REMOTE_REPO = "https://raw.githubusercontent.com/Remi-Gau/cobidas-PET/" +# REMOTE_REPO = "https://raw.githubusercontent.com/ohbm/cobidas/" +# REMOTE_REPO = "https://raw.githubusercontent.com/Remi-Gau/cobidas-eyetracker/" + +# ----------------------------------------------------------------------------- +# RUN +# ----------------------------------------------------------------------------- + +for schema in schema_to_create: + + protocol = create_schema(schema, OUTPUT_DIR) + + print( + "\n\n" + + "---------------------------------------------------------------" + + "\nYou can view this protocol here:\n" + + "https://www.repronim.org/reproschema-ui/#/?url=" + + os.path.join( + REMOTE_REPO, "master", "protocols", protocol.dir, protocol.get_filename() + ) + + "\n" + + "--------------------------------------------------------------" + + "\n" + + "https://www.repronim.org/reproschema-ui/#/?url=url-to-protocol-schema" + + "\n" + + "https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schema" + + "\n" + + "--------------------------------------------------------------" + + "\n\n", + ) diff --git a/tools/cobidas/create_schema.py b/tools/cobidas/create_schema.py new file mode 100644 index 000000000..a73684021 --- /dev/null +++ b/tools/cobidas/create_schema.py @@ -0,0 +1,144 @@ +import os +import json + + +def create_schema(schema_to_create, OUTPUT_DIR): + """ + This takes the content of the a csv file and turns it into a + reproschema protocol. + This loops through the items of the csv and creates a new reproschema + activity with every new checklist "section" it encouters: this new activity + will be added to the protocol. + Every new item encountered is added to the current activity. + """ + + import csv + from reproschema_protocol import ReproschemaProtocol + from item import get_item_info + + # ----------------------------------------------------------------------------- + # START + # ----------------------------------------------------------------------------- + + input_file, csv_info = return_protocol_details(schema_to_create) + + protocol_name = schema_to_create + protocol = ReproschemaProtocol() + protocol.set_defaults(protocol_name) + + # create output directories + if not os.path.exists(os.path.join(OUTPUT_DIR, "protocols", protocol.dir)): + os.makedirs(os.path.join(OUTPUT_DIR, "protocols", protocol.dir)) + + # to check if we got to a new section while looping through items + this_section = "" + activity = [] + + with open(input_file, "r") as csvfile: + PROTOCOL_METADATA = csv.reader(csvfile) + for row in PROTOCOL_METADATA: + + item_info = get_item_info(row, csv_info) + + if item_info["name"] != []: + + protocol, activity, this_section = create_update_activity( + row, + csv_info, + protocol, + activity, + item_info, + this_section, + OUTPUT_DIR, + ) + + create_new_item( + item_info, activity, row, csv_info, OUTPUT_DIR, + ) + + protocol.sort() + + protocol.write(os.path.join(OUTPUT_DIR, "protocols", protocol.dir)) + + return protocol + + +def return_protocol_details(schema_to_create): + + source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") + csv_dir = os.path.join("inputs", "csv") + + input_file = os.path.join( + source_dir, csv_dir, "cobidas_" + schema_to_create + ".csv" + ) + data_dictionnary_file = os.path.join( + source_dir, csv_dir, "cobidas_" + schema_to_create + ".json" + ) + + with open(data_dictionnary_file) as f: + csv_info = json.load(f) + + return input_file, csv_info + + +def create_update_activity( + row, csv_info, protocol, activity, item_info, this_section, OUTPUT_DIR +): + + from reproschema_activity import ReproschemaActivity + + # ------------------------------------------------------------------- + # detect if this is a new section if so it will create a new activity + # ------------------------------------------------------------------- + if row[csv_info["section"]["col"]] != this_section: + + # update section name + this_section = row[csv_info["section"]["col"]] + section = this_section.replace(" ", "_") + + activity = ReproschemaActivity() + + activity_name = protocol.get_name() + "_" + section + activity.set_defaults(activity_name) + + pref_label = row[csv_info["act_pref_label"]["col"]] + activity.set_pref_label(pref_label) + + URI = "../../activities/" + activity.get_name() + "/" + activity.get_filename() + activity.set_URI(URI) + + # create dir for this section + if not os.path.exists( + os.path.join(OUTPUT_DIR, "activities", activity.get_name()) + ): + os.makedirs(os.path.join(OUTPUT_DIR, "activities", activity.get_name())) + os.makedirs( + os.path.join(OUTPUT_DIR, "activities", activity.get_name(), "items") + ) + + protocol.append_activity(activity) + + print(activity.get_filename()) + + activity.update_activity(item_info) + + activity.sort() + + activity.write(os.path.join(OUTPUT_DIR, "activities", activity.get_name())) + + return protocol, activity, this_section + + +def create_new_item(item_info, activity, row, csv_info, OUTPUT_DIR): + + from item import define_new_item + + print(" " + item_info["name"]) + print(" " + item_info["question"]) + print(" " + item_info["resp_type"]) + + item = define_new_item(item_info) + + item.sort() + + item.write(os.path.join(OUTPUT_DIR, "activities", activity.get_name(), "items")) diff --git a/tools/cobidas/item.py b/tools/cobidas/item.py new file mode 100644 index 000000000..8ccf93c5e --- /dev/null +++ b/tools/cobidas/item.py @@ -0,0 +1,191 @@ +def get_item_info(row, csv_info): + + item_name = [] + + item_col = csv_info["item"]["col"] + item_col_name = csv_info["item"]["name"] + + # we want to skip the header and only include items with 1 in the include column (if it exists) + incl_col = csv_info["include"]["col"] + if row[item_col] == item_col_name or (incl_col != [] and row[incl_col] != "1"): + + print(" skipping item") + + return {"name": item_name} + + item_name = row[item_col].replace("\n", "") + + question_col = csv_info["question"]["col"] + question = row[question_col].replace("\n", "") + + resp_type_col = csv_info["resp_type"]["col"] + response_type = row[resp_type_col] + + choice_col = csv_info["choice"]["col"] + response_choices = row[choice_col].split(" | ") + + preamble = csv_info["preamble"]["col"] + + visibility = get_visibility(row, csv_info) + + mandatory = get_mandatory(row, csv_info) + + return { + "name": item_name, + "question": question, + "resp_type": response_type, + "choices": response_choices, + "visibility": visibility, + "preamble": preamble, + "mandatory": mandatory, + } + + +def get_visibility(row, csv_info): + + visibility = True + + if row[csv_info["vis"]["col"]] != "1": + + visibility = row[csv_info["vis"]["col"]] + + # vis_conditions = row[choice_col].split(',') + # + # for i, cdt in enumerate(vis_conditions): + # + # visibility['choices'].append({ + # 'schema:name': opt, + # 'schema:value': i, + # '@type': 'schema:option' + # }) + + return visibility + + +def get_mandatory(row, csv_info): + + mandatory = False + + if row[csv_info["mandatory"]["col"]] == "1": + + mandatory = True + + return mandatory + + +def define_new_item(item_info): + """ + define jsonld for this item + """ + + from reproschema_item import ReproschemaItem + + item = ReproschemaItem() + + item.set_defaults(item_info["name"]) + + item.set_question(item_info["question"]) + + item = define_response_choices(item, item_info["resp_type"], item_info["choices"]) + + return item + + +def define_response_choices(item, response_type, response_choices): + + # in case we have one of the basic response type + # with no response choice involved + item.set_basic_response_type(response_type) + + if response_type == "radio": + response_options = list_responses_options(response_choices) + item.set_input_type_as_radio(response_options) + + # if we have a dropdown menu + # TODO: change to select item to have a REAL dropdown as soon as radio item + # offer the possibility to have an "Other" choice that opens a text box + elif response_type == "dropdown": + response_options = list_responses_options(response_choices) + item.set_input_type_as_radio(response_options) + + elif response_type == "slider": + # response_options = slider_response(response_choices, min_label, max_label) + # item.set_input_type_as_slider(response_options) + item.set_input_type_as_slider() + + if ( + response_type == "boolean" + or response_type == "mri_software" + or response_type == "interpolation" + or response_type == "cost_function" + or response_type == "multiple_comparison" + ): + + value_constraint = response_type + + if "_" in response_type: + """ + if response_type is "test_name" in the spreadsheet then the + corresponding response option value constraints file is + testNameValueConstraints, so we need to do some string magic + """ + + response_type = response_type.split("_") + + # This does not cover the cases where the string has more than + # 2 elements separated by "_" + value_constraint = ( + response_type[0] + response_type[1][0].upper() + response_type[1][1:] + ) + + response_options = "../../../response_options/" + response_options += value_constraint + response_options += "ValueConstraints" + + item.set_input_type_as_radio(response_options) + + return item + + +def list_responses_options(response_choices): + + response_options = {"choices": []} + + for i, opt in enumerate(response_choices): + + response_options["choices"].append({"name": opt, "value": i, "@type": "option"}) + + response_options["choices"].append( + {"name": "Other", "value": len(response_choices), "@type": "option"} + ) + + response_options["minValue"] = 0 + response_options["maxValue"] = len(response_choices) + + return response_options + + +def slider_response(response_choices, min_label, max_label): + + import numpy + + # min = int(response_choices[0]) + # max = int(response_choices[1]) + # steps = int(response_choices[2]) + 1 if len(response_choices) == 3 else 11 + min = 1 + max = 11 + steps = 11 + response_options = { + "valueType": "xsd:integer", + "minValue": min, + "maxValue": max, + "choices": [], + } + + for i in numpy.linspace(min, max, steps): + response_options["choices"].append({"value": int(i), "@type": "option"}) + + response_options["choices"][0]["name"] = min_label + response_options["choices"][-1]["name"] = max_label + + return response_options diff --git a/tools/cobidas/reproschema_activity.py b/tools/cobidas/reproschema_activity.py new file mode 100644 index 000000000..52770c643 --- /dev/null +++ b/tools/cobidas/reproschema_activity.py @@ -0,0 +1,70 @@ +from reproschema_schema import ReproschemaSchema + + +class ReproschemaActivity(ReproschemaSchema): + """ + class to deal with reproschema activities + """ + + def __init__(self): + super().__init__() + self.schema["@type"] = "reproschema:Activity" + self.schema["ui"] = {"shuffle": [], "order": [], "addProperties": []} + + def set_ui_shuffle(self, shuffle=False): + self.schema["ui"]["shuffle"] = shuffle + + def set_URI(self, URI): + self.URI = URI + + def get_URI(self): + return self.URI + + # TODO + # preamble + # compute + # citation + # image + + def set_defaults(self, name): + self._ReproschemaSchema__set_defaults(name) # this looks wrong + self.set_ui_shuffle(False) + + def update_activity(self, item_info): + + # TODO + # - remove the hard coding on visibility and valueRequired + + # update the content of the activity schema with new item + + item_info["URI"] = "items/" + item_info["name"] + + append_to_activity = { + "variableName": item_info["name"], + "isAbout": item_info["URI"], + "isVis": item_info["visibility"], + "valueRequired": False, + } + + self.schema["ui"]["order"].append(item_info["URI"]) + self.schema["ui"]["addProperties"].append(append_to_activity) + + def sort(self): + schema_order = [ + "@context", + "@type", + "@id", + "prefLabel", + "description", + "schemaVersion", + "version", + "ui", + ] + self.sort_schema(schema_order) + + ui_order = [ + "shuffle", + "order", + "addProperties", + ] + self.sort_ui(ui_order) diff --git a/tools/cobidas/reproschema_item.py b/tools/cobidas/reproschema_item.py new file mode 100644 index 000000000..47cc2ca29 --- /dev/null +++ b/tools/cobidas/reproschema_item.py @@ -0,0 +1,157 @@ +from reproschema_schema import ReproschemaSchema + + +class ReproschemaItem(ReproschemaSchema): + """ + class to deal with reproschema activities + """ + + def __init__(self): + super().__init__() + self.schema["@type"] = "reproschema:Field" + self.schema["ui"] = {"inputType": []} + self.schema["question"] = {} + self.schema["responseOptions"] = {} + # default input type is "char" + self.set_input_type_as_char() + + def set_URI(self, URI): + self.URI = URI + + # TODO + # image + # readonlyValue + + def set_defaults(self, name): + self._ReproschemaSchema__set_defaults(name) # this looks wrong + self.schema_file = name + self.schema["@id"] = name + self.set_input_type_as_char() + + def set_question(self, question, lang="en"): + self.schema["question"][lang] = question + + def set_input_type(self, input_type): + self.schema["ui"]["inputType"] = input_type + + def set_response_options(self, response_options): + self.schema["responseOptions"] = response_options + + """ + + input types with different response choices + + """ + + def set_input_type_as_radio(self, response_options): + self.set_input_type("radio") + self.set_response_options(response_options) + + def set_input_type_as_select(self, response_options): + self.set_input_type("select") + self.set_response_options(response_options) + + def set_input_type_as_slider(self): + self.set_input_type_as_char() # until the slide item of the ui is fixed + # self.set_input_type("slider") + # self.set_response_options({"valueType": "xsd:string"}) + + def set_input_type_as_language(self): + + URL = "https://raw.githubusercontent.com/ReproNim/reproschema/" + + self.set_input_type("selectLanguage") + + response_options = { + "valueType": "xsd:string", + "multipleChoice": True, + "choices": URL + "master/resources/languages.json", + } + self.set_response_options(response_options) + + """ + + input types with no response choice + + """ + + def set_input_type_as_char(self): + self.set_input_type("text") + self.set_response_options({"valueType": "xsd:string"}) + + def set_input_type_as_int(self): + self.set_input_type("number") + self.set_response_options({"valueType": "xsd:integer"}) + + def set_input_type_as_float(self): + self.set_input_type("float") + self.set_response_options({"valueType": "xsd:float"}) + + def set_input_type_as_time_range(self): + self.set_input_type("timeRange") + self.set_response_options({"valueType": "datetime"}) + + def set_input_type_as_date(self): + self.set_input_type("date") + self.set_response_options({"valueType": "xsd:date"}) + + """ + + input types with no response choice but with some parameters + + """ + + def set_input_type_as_multitext(self, max_length=300): + self.set_input_type("text") + self.set_response_options({"valueType": "xsd:string", "maxLength": max_length}) + + # TODO + # email: EmailInput/EmailInput.vue + # audioCheck: AudioCheck/AudioCheck.vue + # audioRecord: WebAudioRecord/Audio.vue + # audioPassageRecord: WebAudioRecord/Audio.vue + # audioImageRecord: WebAudioRecord/Audio.vue + # audioRecordNumberTask: WebAudioRecord/Audio.vue + # audioAutoRecord: AudioCheckRecord/AudioCheckRecord.vue + # year: YearInput/YearInput.vue + # selectCountry: SelectInput/SelectInput.vue + # selectState: SelectInput/SelectInput.vue + # documentUpload: DocumentUpload/DocumentUpload.vue + # save: SaveData/SaveData.vue + # static: Static/Static.vue + # StaticReadOnly: Static/Static.vue + + def set_basic_response_type(self, response_type): + + # default (also valid for "char" input type) + self.set_input_type_as_char() + + if response_type == "int": + self.set_input_type_as_int() + + elif response_type == "float": + self.set_input_type_as_float() + + elif response_type == "date": + self.set_input_type_as_date() + + elif response_type == "time range": + self.set_input_type_as_time_range() + + elif response_type == "language": + self.set_input_type_as_language() + + def sort(self): + schema_order = [ + "@context", + "@type", + "@id", + "prefLabel", + "description", + "schemaVersion", + "version", + "ui", + "question", + "responseOptions", + ] + self.sort_schema(schema_order) diff --git a/tools/cobidas/reproschema_protocol.py b/tools/cobidas/reproschema_protocol.py new file mode 100644 index 000000000..74da789e3 --- /dev/null +++ b/tools/cobidas/reproschema_protocol.py @@ -0,0 +1,83 @@ +from reproschema_schema import ReproschemaSchema + + +class ReproschemaProtocol(ReproschemaSchema): + """ + class to deal with reproschema protocols + """ + + def __init__(self): + super().__init__() + self.schema["@type"] = "reproschema:Protocol" + self.schema["ui"] = { + "allow": [], + "shuffle": [], + "order": [], + "addProperties": [], + } + + def set_landing_page(self, landing_page_url, lang="en"): + self.schema["landingPage"] = {"@id": landing_page_url, "@language": lang} + + # TODO + # def add_landing_page(self, landing_page_url, lang="en"): + # preamble + # compute + + def set_image(self, image_url): + self.schema["image"] = image_url + + def set_ui_allow(self): + self.schema["ui"]["allow"] = [ + "reproschema:AutoAdvance", + "reproschema:AllowExport", + ] + + def set_ui_shuffle(self, shuffle=False): + self.schema["ui"]["shuffle"] = shuffle + + def set_defaults(self, name): + self._ReproschemaSchema__set_defaults(name) # this looks wrong + self.set_landing_page("../../README-en.md") + self.set_ui_allow() + self.set_ui_shuffle(False) + + def append_activity(self, activity): + + # TODO + # - remove the hard coding on visibility and valueRequired + + # update the content of the protocol with this new activity + append_to_protocol = { + "variableName": activity.get_name(), + "isAbout": activity.get_URI(), + "prefLabel": {"en": activity.schema["prefLabel"]}, + "isVis": True, + "valueRequired": False, + } + + self.schema["ui"]["order"].append(activity.URI) + self.schema["ui"]["addProperties"].append(append_to_protocol) + + def sort(self): + schema_order = [ + "@context", + "@type", + "@id", + "prefLabel", + "description", + "schemaVersion", + "version", + "landingPage", + "ui", + ] + self.sort_schema(schema_order) + + ui_order = [ + "allow", + "shuffle", + "order", + "addProperties", + ] + self.sort_ui(ui_order) + diff --git a/tools/cobidas/reproschema_schema.py b/tools/cobidas/reproschema_schema.py new file mode 100644 index 000000000..b554b2683 --- /dev/null +++ b/tools/cobidas/reproschema_schema.py @@ -0,0 +1,58 @@ +class ReproschemaSchema: + """ + class to deal with reproschema schemas + """ + + def __init__(self): + + URL = "https://raw.githubusercontent.com/ReproNim/reproschema/" + VERSION = "1.0.0-rc1" + + self.schema = { + "@context": URL + VERSION + "/contexts/generic", + "schemaVersion": VERSION, + "version": "0.0.1", + } + + def set_filename(self, name): + self.schema_file = name + "_schema" + self.schema["@id"] = name + "_schema" + + def get_name(self): + return self.schema_file.replace("_schema", "") + + def get_filename(self): + return self.schema_file + + def set_pref_label(self, pref_label): + self.schema["prefLabel"] = pref_label + + def set_description(self, description): + self.schema["description"] = description + + def set_directory(self, output_directory): + self.dir = output_directory + + def __set_defaults(self, name): + self.set_filename(name) + self.set_directory(name) + self.set_pref_label(name.replace("_", " ")) + self.set_description(name.replace("_", " ")) + + def sort_schema(self, schema_order): + + reordered_dict = {k: self.schema[k] for k in schema_order} + self.schema = reordered_dict + + def sort_ui(self, ui_order): + + reordered_dict = {k: self.schema["ui"][k] for k in ui_order} + self.schema["ui"] = reordered_dict + + def write(self, output_dir): + import os + import json + + with open(os.path.join(output_dir, self.schema_file), "w",) as ff: + json.dump(self.schema, ff, sort_keys=False, indent=4) + diff --git a/tools/create_neurovault_schema.py b/tools/create_neurovault_schema.py deleted file mode 100644 index 8484237a5..000000000 --- a/tools/create_neurovault_schema.py +++ /dev/null @@ -1,278 +0,0 @@ -# this script takes the content of the metadata csv file from neurvovault and turns -# it into a Repronim compliant schema - -# tested with python 3.7 - -import json -import os -import csv - -# where the metadata from neurovault are described. Can be downloaded from here:v -# https://github.com/NeuroVault/NeuroVault/blob/master/scripts/metadata_neurovault.csv -input_file = '/home/remi/github/COBIDAS_chckls/xlsx/metadata_neurovault.csv' - -# where the files will be written (the local repo of the schema-standardization) -output_dir = '/home/remi/github/schema-standardization' - -# placeholder to insert in all instances of the remote repo -remote_repo = 'https://raw.githubusercontent.com/Remi-Gau/schema-standardization/' - -# to which branch of schema-standardization the ui will be pointed to -branch_name = 'neurovault' - - -# activity set names -activity_set_schema_filename = 'cobidas_schema.jsonld' -activity_set_context_filename = 'cobidas_context.jsonld' -activity_set_folder_name = 'cobidas' - - -# version -version = '0.0.1' - -# make output directories -if not os.path.exists(os.path.join(output_dir, 'activity-sets', activity_set_folder_name)): - os.makedirs(os.path.join(output_dir, 'activity-sets', activity_set_folder_name)) - - - -# define the activity set neurovault_schema.jsonld -nv_set_schema_json = { - '@context': [ remote_repo + branch_name + '/contexts/generic.jsonld', - remote_repo + branch_name + '/activity-sets/' + activity_set_folder_name + '/' + activity_set_context_filename - ], - '@type': remote_repo + branch_name + '/schemas/ActivitySet.jsonld', - '@id': 'cobidas_schema', - 'skos:prefLabel': 'neurovault as a COBIDAS POC', - 'skos:altLabel': 'neurovault_COBIDAS_POC', - 'schema:description': 'neurovault as a COBIDAS checklist proof of concept', - 'schema:schemaVersion': version, - 'schema:version': version, - 'variableMap': [], - 'ui': { - 'order': [], - 'shuffle': False, - 'activity_display_name': {}, - 'visibility': {} - } -} - -# define the activity set neurovault_context.jsonld -nv_set_context_json = { - '@context': { - '@version': 1.1, - 'activity_path': remote_repo + branch_name + '/activities/', - } -} - - -Section = '' -# loop through rows of the csv file and create corresponding jsonld for each item -with open(input_file, 'r') as csvfile: - nv_metadata = csv.reader(csvfile) - for row in nv_metadata: - - # to skip the header - if row[2]!='Item': - - # detect if this is a new section if so it will create a new activity - if row[1]!=Section: - - # update section name - Section=row[1] - - # where the items of this section will be stored - activity_folder_name = 'Neurovault_' + Section - - # names of this section schema and its corresponding jsonld files - activity_schema_name = 'Neurovault_' + Section + '_schema' - - activity_schema_filename = activity_schema_name + '.jsonld' - - activity_context_filename = 'Neurovault_' + Section + '_context.jsonld' - - - print(activity_schema_name) - - # create dir for this section - if not os.path.exists(os.path.join(output_dir, 'activities', activity_folder_name)): - os.makedirs(os.path.join(output_dir, 'activities', activity_folder_name)) - - if not os.path.exists(os.path.join(output_dir, 'activities', activity_folder_name, 'items')): - os.makedirs(os.path.join(output_dir, 'activities', activity_folder_name, 'items')) - - - # define the base json content for the activity: neurovault_schema.jsonld neurovault_context.jsonld - nv_context_json = { - '@context': { - '@version': 1.1, - 'item_path': remote_repo + branch_name + '/activities/' + activity_folder_name + '/items/', - } - } - - nv_schema_json = { - '@context': [ remote_repo + branch_name + '/contexts/generic.jsonld', - remote_repo + branch_name + '/activities/' + activity_folder_name + '/' + activity_context_filename - ], - '@type': remote_repo + branch_name + '/schemas/Activity.jsonld', - '@id': activity_schema_name, - 'skos:prefLabel': 'COBIDAS design checklist', - 'skos:altLabel': 'cobidas_design_schema', - 'schema:description': 'COBIDAS design checklist schema', - 'schema:schemaVersion': version, - 'schema:version': version, - 'preamble': 'How did you design/analyse your study?', - 'ui': { - 'order': [], - 'shuffle': False - } - } - - # update the json content of the activity set schema and context wrt this new activity - nv_set_schema_json['variableMap'].append( - {'variableName': activity_schema_name,'isAbout': activity_schema_name} - ) - - nv_set_schema_json['ui']['order'].append(activity_schema_name) - nv_set_schema_json['ui']['visibility'][activity_schema_name] = True - nv_set_schema_json['ui']['activity_display_name'][activity_schema_name] = 'Neurovault - ' + Section - - nv_set_context_json['@context'][activity_schema_name] = { - '@id': 'activity_path:' + activity_folder_name + '/' + activity_schema_filename, - '@type': '@id' - } - - print(' ' + row[2]) - - - # update the json content of the activity schema and context wrt this new item - nv_schema_json['ui']['order'].append(row[2]) - - nv_context_json['@context'][row[2]] = { - '@id': 'item_path:'+row[2]+'.jsonld', - '@type': '@id' - } - - # save activity jsonld with every new item - with open(os.path.join(output_dir, 'activities', activity_folder_name, activity_schema_filename), 'w') as ff: - json.dump(nv_schema_json, ff, sort_keys=False, indent=4) - - with open(os.path.join(output_dir, 'activities', activity_folder_name, activity_context_filename), 'w') as ff: - json.dump(nv_context_json, ff, sort_keys=False, indent=4) - - - # define jsonld for this item - item_json = { - '@context': [ remote_repo + branch_name + '/contexts/generic.jsonld', - remote_repo + branch_name + '/activities/' + activity_folder_name + '/' + activity_context_filename - ], - '@type': remote_repo + branch_name + '/schemas/Field.jsonld', - '@id': row[2], - 'skos:prefLabel': row[2], - 'skos:altLabel': row[2], - 'schema:description': row[2], - 'schema:schemaVersion': version, - 'schema:version': version, - 'question': row[3], - } - - # now we define the answers for this item - if row[4]=='Boolean': - - item_json['ui'] = { - 'inputType': 'radio' - } - item_json['responseOptions'] = { - '@type': 'xsd:anyURI', - 'multipleChoice': False, - 'schema:minValue': 0, - 'schema:maxValue': 1, - 'choices': [ - { - '@type': 'schema:Boolean', - 'schema:name': 'no', - 'schema:value': 0, - }, - { - '@type': 'schema:Boolean', - 'schema:name': 'yes', - 'schema:value': 1, - } - ] - } - - # if we have multiple choices - elif row[4][0]=='[': - - # we get all the possible options and add them to the possible responses - options = row[4][1:-2].replace("'", "").split(',') - - item_json['ui'] = { - 'inputType': 'radio' - } - - item_json['responseOptions'] = { - '@type': 'xsd:anyURI', - 'multipleChoice': False, - 'schema:minValue': 0, - 'schema:maxValue': len(options)-1, - 'choices': [] - } - - for i, opt in enumerate(options): - - item_json['responseOptions']['choices'].append({ - 'schema:name': {'en': opt}, - 'schema:value': i, - }) - - - # response is some integer - elif row[4]=='int': - item_json['ui'] = { - 'inputType': 'text' - } - item_json['responseOptions'] = { - 'type': 'xsd:int', - } - - - # response is some integer - elif row[4]=='float': - item_json['ui'] = { - 'inputType': 'text' - } - item_json['responseOptions'] = { - 'type': 'xsd:float', - } - - - # input requires some typed answer - elif row[4]=='char': - item_json['ui'] = { - 'inputType': 'text' - } - item_json['responseOptions'] = { - 'type': 'xsd:string' - } - - else: - item_json['ui'] = { - 'inputType': 'text' - } - item_json['responseOptions'] = { - 'type': 'xsd:string' - } - - - # write item jsonld - with open(os.path.join(output_dir, 'activities', activity_folder_name, 'items', row[2] + '.jsonld'), 'w') as ff: - json.dump(item_json, ff, sort_keys=False, indent=4) - - -# write activity set jsonld -with open(os.path.join(output_dir, 'activity-sets', activity_set_folder_name, activity_set_schema_filename), 'w') as ff: - json.dump(nv_set_schema_json, ff, sort_keys=False, indent=4) - -with open(os.path.join(output_dir, 'activity-sets', activity_set_folder_name, activity_set_context_filename), 'w') as ff: - json.dump(nv_set_context_json, ff, sort_keys=False, indent=4)