Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch mapping to openMINDS Python classes #9

Merged
merged 15 commits into from
Jun 21, 2024
122 changes: 98 additions & 24 deletions bids2openminds/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from openminds import IRI

from .utility import table_filter, pd_table_value, file_hash, file_storage_size, detect_nifti_version
from .mapping import bids2openminds_instance
from . import mapping


def create_openminds_person(full_name):
Expand Down Expand Up @@ -92,32 +92,66 @@ def create_behavioral_protocol(layout, collection):
return behavioral_protocols, behavioral_protocols_dict


def techniques_openminds(suffix):
possible_types = ["Technique", "AnalysisTechnique", "StimulationApproach",
"StimulationTechnique"]

if suffix in mapping.MAP_2_TECHNIQUES:
items_openminds = mapping.MAP_2_TECHNIQUES[suffix]
else:
return []

if items_openminds is None:
return []

openminds_techniques_list = []
for item_openminds in items_openminds:
for possible_type in possible_types:
openminds_type = getattr(controlled_terms, possible_type)
try:
openminds_obj = openminds_type.by_name(item_openminds)
break
except KeyError:
pass
openminds_techniques_list.append(openminds_obj)
return openminds_techniques_list


def create_techniques(layout_df):
suffixs = layout_df["suffix"].unique().tolist()
techniques = []
not_techniques_index = ["description", "participants", "events"]
for suffix in suffixs:
# excluding the None and non thechnique indexes
if not (pd.isna(suffix) or (suffix in not_techniques_index)):
openminds_techniques_cache = bids2openminds_instance(
suffix, "MAP_2_TECHNIQUES")
# Excluding the suffixs that are not in the library or flagged as non technique suffixes
if not pd.isna(openminds_techniques_cache):
techniques.extend(openminds_techniques_cache)
else:
warn(
f"The {suffix} suffix is currently considered an auxiliary file for already existing techniques or a non technique file.")
if not (pd.isnull(suffix) or (suffix in not_techniques_index)):
openminds_techniques_cache = techniques_openminds(suffix)
techniques.extend(openminds_techniques_cache)

return techniques or None
techniques_set = set(techniques)
techniques_list = list(techniques_set)
return techniques_list or None


def approaches_openminds(datatype):

if datatype in mapping.MAP_2_EXPERIMENTAL_APPROACHES:
items_openminds = mapping.MAP_2_EXPERIMENTAL_APPROACHES[datatype]

approches_list = []

for item in items_openminds:
approches_list.append(
controlled_terms.ExperimentalApproach.by_name(item))

return approches_list


def create_approaches(layout_df):
datatypes = layout_df["datatype"].unique().tolist()
approaches = set([])
for datatype in datatypes:
if not (pd.isna(datatype)):
approaches.update(bids2openminds_instance(
datatype, "MAP_2_EXPERIMENTAL_APPROACHES"))
if not (pd.isnull(datatype)):
approaches.update(approaches_openminds(datatype))

return list(approaches) or None

Expand Down Expand Up @@ -227,6 +261,52 @@ def create_dataset(dataset_description, dataset_version, collection):
return dataset


def spices_openminds(data_subject: pd.DataFrame):
bids_species = pd_table_value(data_subject, "species")
if bids_species is None:
# In BIDS the default species is homo sapiens.
return controlled_terms.Species.homo_sapiens
if bids_species in mapping.MAP_2_SPECIES:
openminds_species = mapping.MAP_2_SPECIES[bids_species]
return controlled_terms.Species.by_name(openminds_species[0])
else:
try:
openminds_species = controlled_terms.Species.by_name(bids_species)
warn(
f"You have specified {bids_species} as species, we have autodetected {openminds_species.name}, please verify it.")
return openminds_species
except KeyError:
warn(
f"You have specified {bids_species} we currently don't support this species.")
return None


def handedness_openminds(data_subject: pd.DataFrame):
bids_handedness = pd_table_value(data_subject, "handedness")
if bids_handedness is None:
return None
if bids_handedness in mapping.MAP_2_HANDEDNESS:
openminds_handedness = mapping.MAP_2_HANDEDNESS[bids_handedness]
return controlled_terms.Handedness.by_name(openminds_handedness[0])
else:
warn(
f"You have specified {bids_handedness} which is not a allowed value for handedness defined by BIDS standard.")
return None


def sex_openminds(data_subject: pd.DataFrame):
bids_sex = pd_table_value(data_subject, "sex")
if bids_sex is None:
return None
if bids_sex in mapping.MAP_2_BIOLOGICALSEX:
bids_sex = mapping.MAP_2_BIOLOGICALSEX[bids_sex]
return controlled_terms.BiologicalSex.by_name(bids_sex[0])
else:
warn(
f"You have specified {bids_sex} which is not a allowed value for handedness defined by BIDS standard.")
return None


def create_subjects(subject_id, layout_df, layout, collection):

sessions = layout.get_sessions()
Expand Down Expand Up @@ -280,8 +360,6 @@ def create_subjects(subject_id, layout_df, layout, collection):
# Select the tsv file of the table
participants_path_tsv = pd_table_value(table_filter(
participants_paths, ".tsv", "extension"), "path")
participants_path_json = pd_table_value(table_filter(
participants_paths, ".json", "extension"), "path")

participants_table = pd.read_csv(participants_path_tsv, sep="\t", header=0)
for subject in subject_id:
Expand All @@ -293,8 +371,7 @@ def create_subjects(subject_id, layout_df, layout, collection):
if not sessions:
state = omcore.SubjectState(
age=create_openminds_age(data_subject),
handedness=bids2openminds_instance(pd_table_value(
data_subject, "handedness"), "MAP_2_HANDEDNESS", is_list=False),
handedness=handedness_openminds(data_subject),
internal_identifier=f"Studied state {subject_name}".strip(),
lookup_label=f"Studied state {subject_name}".strip()
)
Expand All @@ -306,8 +383,7 @@ def create_subjects(subject_id, layout_df, layout, collection):
if not (table_filter(table_filter(layout_df, session, "session"), subject, "subject").empty):
state = omcore.SubjectState(
age=create_openminds_age(data_subject),
handedness=bids2openminds_instance(pd_table_value(
data_subject, "handedness"), "MAP_2_HANDEDNESS", is_list=False),
handedness=handedness_openminds(data_subject),
internal_identifier=f"Studied state {subject_name} {session}".strip(
),
lookup_label=f"Studied state {subject_name} {session}".strip(
Expand All @@ -318,13 +394,11 @@ def create_subjects(subject_id, layout_df, layout, collection):
state_cache.append(state)
subject_state_dict[f"{subject}"] = state_cache_dict
subject_cache = omcore.Subject(
biological_sex=bids2openminds_instance(pd_table_value(
data_subject, "sex"), "MAP_2_SEX", is_list=False),
biological_sex=sex_openminds(data_subject),
lookup_label=f"{subject_name}",
internal_identifier=f"{subject_name}",
# TODO species should default to homo sapiens
species=bids2openminds_instance(pd_table_value(
data_subject, "species"), "MAP_2_SPECIES", is_list=False),
species=spices_openminds(data_subject),
studied_states=state_cache
)
subjects_dict[f"{subject}"] = subject_cache
Expand Down
Loading