From 3059d287260165f252787740918e9792107c3080 Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Mon, 28 Oct 2024 18:16:56 +0100 Subject: [PATCH 1/7] WIP --- .../converters/aibl_to_bids/utils/clinical.py | 181 +++++++++++++----- .../aibl_to_bids/test_aibl_utils.py | 35 ++-- 2 files changed, 152 insertions(+), 64 deletions(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index 61540925e..c5b91aee9 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -1,6 +1,8 @@ +from ast import Index from pathlib import Path from typing import List, Optional, Union +import numpy as np import pandas as pd __all__ = [ @@ -148,8 +150,73 @@ def _load_specifications( return pd.read_csv(specifications, sep="\t") +def _mapping_unknown(input_value: Union[int, str]) -> str: + # todo :test + # todo : what happens if str -4 ? + if input_value == -4: + return "n/a" + else: + return input_value + + +def _mapping_diagnosis(diagnosis: int) -> str: + # todo : what happens if str ? + if diagnosis == 1: + return "CN" + elif diagnosis == 2: + return "MCI" + elif diagnosis == 3: + return "AD" + else: + return "n/a" + + +def _extract_metadata_df( + input_df: pd.DataFrame, source_id: int, bids_metadata: str, source_metadata: str +) -> pd.DataFrame: + # todo :test + from clinica.iotools.converter_utils import viscode_to_session + + extract = input_df.loc[(input_df["RID"] == source_id), ["VISCODE", source_metadata]] + extract.rename(columns={source_metadata: bids_metadata}, inplace=True) + extract = extract.assign( + session_id=extract.VISCODE.apply(lambda x: viscode_to_session(x)) + ) + extract.drop(labels="VISCODE", inplace=True, axis=1) + extract.set_index("session_id", inplace=True, drop=True) + + return extract + + +def _compute_age_at_exam(birth_date: str, exam_date: str) -> float: + """Compute the ages of the patient at each exam date. + + Parameters + ---------- + birth_date : str + Date of birth of patient ("/%Y" format) + + exam_date : str + Exam date ("%m/%d/%Y" format) + + Return + ------ + float + Age of the patient at exam date. + """ + # todo : test + # todo (LATER) : what happens if wrong format ? + + from datetime import datetime + + date_of_birth = datetime.strptime(birth_date, "/%Y") + exam_date = datetime.strptime(exam_date, "%m/%d/%Y") + + return exam_date.year - date_of_birth.year + + def create_sessions_tsv_file( - input_path: Path, + bids_dir: Path, clinical_data_dir: Path, clinical_specifications_folder: Path, ) -> None: @@ -157,8 +224,8 @@ def create_sessions_tsv_file( Parameters ---------- - input_path : Path - The path to the input folder (BIDS directory). + bids_dir : Path + The path to the BIDS directory. clinical_data_dir : Path The path to the directory to the clinical data files. @@ -168,42 +235,66 @@ def create_sessions_tsv_file( """ import glob - from clinica.iotools.bids_utils import StudyName, bids_id_factory + from clinica.iotools.bids_utils import ( + StudyName, + bids_id_factory, + get_bids_sess_list, + get_bids_subjs_list, + ) + from clinica.iotools.converter_utils import viscode_to_session + study = StudyName.AIBL.value specifications = _load_specifications( clinical_specifications_folder, "sessions.tsv" - ) - sessions_fields = specifications[StudyName.AIBL.value] - field_location = specifications[f"{StudyName.AIBL.value} location"] - sessions_fields_bids = specifications["BIDS CLINICA"] - fields_dataset = [] - fields_bids = [] + )[["BIDS CLINICA", f"{study} location", study]].dropna() + + for bids_id in get_bids_subjs_list(bids_dir): + rid = int(bids_id_factory(study)(bids_id).to_original_study_id()) + test = ( + pd.DataFrame({"session_id": get_bids_sess_list(bids_dir / bids_id)}) + .set_index("session_id", drop=False) + .sort_index() + ) - for i in range(0, len(sessions_fields)): - if not pd.isnull(sessions_fields[i]): - fields_bids.append(sessions_fields_bids[i]) - fields_dataset.append(sessions_fields[i]) + for _, row in specifications.iterrows(): + df = pd.read_csv( + glob.glob(str(clinical_data_dir / row[f"{study} location"]))[0], + dtype={"text": str}, + ) + extract = _extract_metadata_df( + input_df=df, + source_id=rid, + bids_metadata=row["BIDS CLINICA"], + source_metadata=row[study], + ) + test = pd.concat([test, extract], axis=1) - files_to_read: List[str] = [] - sessions_fields_to_read: List[str] = [] - for i in range(0, len(sessions_fields)): - # If the i-th field is available - if not pd.isnull(sessions_fields[i]): - # Load the file - file_to_read_path = clinical_data_dir / field_location[i] - files_to_read.append(glob.glob(str(file_to_read_path))[0]) - sessions_fields_to_read.append(sessions_fields[i]) + test = test.map(lambda x: _mapping_unknown(x)) + test["diagnosis"] = test.diagnosis.apply(lambda x: _mapping_diagnosis(x)) + + test["age"] = test["age"].fillna(method="ffill") + for i, row in test.iterrows(): + test.loc[i, "age"] = _compute_age_at_exam(row.age, row.examination_date) + # todo : anyway to do this with a apply sthg ? - rids = pd.read_csv(files_to_read[0], dtype={"text": str}, low_memory=False).RID - unique_rids = list(set(rids)) + # todo : handle exam date + # todo : put back months from ses id ? + + files_to_read = [ + glob.glob(str(clinical_data_dir / loc))[0] + for loc in specifications[f"{study} location"] + ] + sessions_fields_to_read = specifications[study].tolist() + unique_rids = [ + int(bids_id_factory(study)(bids_id).to_original_study_id()) + for bids_id in get_bids_subjs_list(bids_dir) + ] for rid in unique_rids: for file in files_to_read: df = pd.read_csv(file, dtype={"text": str}) - if len(df.columns) == 1: - df = pd.read_csv(file, sep=";", low_memory=False) - - visit_code = df.loc[(df["RID"] == rid), "VISCODE"] - + visit_code = df.loc[ + (df["RID"] == rid), "VISCODE" + ] # todo :how to get it out of the loop ? for field in sessions_fields_to_read: if field in list(df.columns.values) and field == "MMSCORE": mm_score = df.loc[(df["RID"] == rid), field] @@ -217,10 +308,7 @@ def create_sessions_tsv_file( elif field in list(df.columns.values) and field == "DXCURREN": dx_curren = df.loc[(df["RID"] == rid), field] - dx_curren[dx_curren == -4] = "n/a" - dx_curren[dx_curren == 1] = "CN" - dx_curren[dx_curren == 2] = "MCI" - dx_curren[dx_curren == 3] = "AD" + dx_curren = dx_curren.apply(lambda x: _mapping_diagnosis(x)) elif field in list(df.columns.values) and field == "EXAMDATE": exam_date = df.loc[(df["RID"] == rid), field] @@ -239,12 +327,9 @@ def create_sessions_tsv_file( else: age = "n/a" - visit_code[visit_code == "bl"] = "M000" - visit_code = visit_code.str.upper() - sessions = pd.DataFrame( { - "months": visit_code.str[1:], + "session_id": [viscode_to_session(code) for code in visit_code], "age": age, "MMS": mm_score, "cdr_global": cd_global, @@ -252,23 +337,17 @@ def create_sessions_tsv_file( "examination_date": exam_dates, } ) - # todo (LATER) : pretty sure there exists a function that converts viscode to session - sessions = sessions.assign( - session_id=lambda df: df.months.apply(lambda x: f"ses-M{int(x):03d}") - ) cols = sessions.columns.tolist() sessions = sessions[cols[-1:] + cols[:-1]] bids_id = bids_id_factory(StudyName.AIBL).from_original_study_id(str(rid)) - bids_paths = input_path / bids_id - if bids_paths.exists(): - sessions.to_csv( - input_path / bids_id / f"{bids_id}_sessions.tsv", - sep="\t", - index=False, - encoding="utf8", - ) + sessions.to_csv( + bids_dir / bids_id / f"{bids_id}_sessions.tsv", + sep="\t", + index=False, + encoding="utf8", + ) def _clean_exam_dates( @@ -422,7 +501,7 @@ def _compute_ages_at_each_exam( # rq : what is the use of being so precise ? we are comparing a year with a full date.. that's false anyway # we could give ages in years (int, >=0) and just subtract the years - # todo (LATER) : what happens if wrong format ? or exam < birth for some reason ? + # todo (LATER) : what happens if wrong format ? return ages diff --git a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py index d95b278c3..6c7b17e0a 100644 --- a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py +++ b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py @@ -3,6 +3,25 @@ import numpy as np import pandas as pd import pytest +from pandas.testing import assert_frame_equal + + +@pytest.mark.parametrize( + "diagnosis, expected", + [ + (-4, "n/a"), + (1, "CN"), + (2, "MCI"), + (3, "AD"), + (0, "n/a"), + ], +) +def test_mapping_diagnosis(diagnosis, expected): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _mapping_diagnosis, + ) + + assert _mapping_diagnosis(diagnosis) == expected @pytest.mark.parametrize( @@ -36,14 +55,6 @@ def test_compute_exam_date_from_baseline_raiseValue(): _compute_exam_date_from_baseline("foo", [], []) -def test_find_exam_date_in_other_csv_files(): - pass - - -def test_clean_exam_dates(): - pass - - def test_load_specifications_success(tmp_path): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( _load_specifications, @@ -227,7 +238,7 @@ def test_create_sessions_tsv(tmp_path): bids_path = build_bids_dir(tmp_path) create_sessions_tsv_file( - input_path=bids_path, + bids_dir=bids_path, clinical_data_dir=build_clinical_data(tmp_path), clinical_specifications_folder=build_sessions_spec(tmp_path), ) @@ -243,7 +254,6 @@ def test_create_sessions_tsv(tmp_path): expected_sub100 = pd.DataFrame( { "session_id": ["ses-M000", "ses-M012"], - "months": [0, 12], "age": [np.nan, np.nan], "MMS": [30, 29], "cdr_global": [0.0, 0.0], @@ -255,7 +265,6 @@ def test_create_sessions_tsv(tmp_path): expected_sub1 = pd.DataFrame( { "session_id": ["ses-M000"], - "months": [0], "age": [100], "MMS": [np.nan], "cdr_global": [np.nan], @@ -264,5 +273,5 @@ def test_create_sessions_tsv(tmp_path): } ) - assert expected_sub1.equals(result_sub1) - assert expected_sub100.equals(result_sub100) + assert_frame_equal(result_sub1, expected_sub1, check_like=True) + assert_frame_equal(result_sub100, expected_sub100, check_like=True) From 8fb0e6ff06b81a597e6f9b7fb2cc4fb146b00073 Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Tue, 29 Oct 2024 18:08:00 +0100 Subject: [PATCH 2/7] WIP - major changes --- .../converters/aibl_to_bids/utils/clinical.py | 253 ++++-------------- .../aibl_to_bids/test_aibl_utils.py | 33 +-- 2 files changed, 63 insertions(+), 223 deletions(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index c5b91aee9..77e1138df 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -11,6 +11,8 @@ "create_sessions_tsv_file", ] +from sqlalchemy.sql.operators import from_ + def create_participants_tsv_file( input_path: Path, @@ -150,17 +152,8 @@ def _load_specifications( return pd.read_csv(specifications, sep="\t") -def _mapping_unknown(input_value: Union[int, str]) -> str: - # todo :test - # todo : what happens if str -4 ? - if input_value == -4: - return "n/a" - else: - return input_value - - def _mapping_diagnosis(diagnosis: int) -> str: - # todo : what happens if str ? + # todo : what if str(1) ? if diagnosis == 1: return "CN" elif diagnosis == 2: @@ -188,7 +181,9 @@ def _extract_metadata_df( return extract -def _compute_age_at_exam(birth_date: str, exam_date: str) -> float: +def _compute_age_at_exam( + birth_date: Union[float, str], exam_date: Union[float, str] +) -> float: """Compute the ages of the patient at each exam date. Parameters @@ -205,14 +200,14 @@ def _compute_age_at_exam(birth_date: str, exam_date: str) -> float: Age of the patient at exam date. """ # todo : test - # todo (LATER) : what happens if wrong format ? - from datetime import datetime - date_of_birth = datetime.strptime(birth_date, "/%Y") - exam_date = datetime.strptime(exam_date, "%m/%d/%Y") - - return exam_date.year - date_of_birth.year + if not isinstance(birth_date, float) and not isinstance(exam_date, float): + date_of_birth = datetime.strptime(birth_date, "/%Y") + exam_date = datetime.strptime(exam_date, "%m/%d/%Y") + return exam_date.year - date_of_birth.year + else: + return np.nan def create_sessions_tsv_file( @@ -241,7 +236,6 @@ def create_sessions_tsv_file( get_bids_sess_list, get_bids_subjs_list, ) - from clinica.iotools.converter_utils import viscode_to_session study = StudyName.AIBL.value specifications = _load_specifications( @@ -250,11 +244,9 @@ def create_sessions_tsv_file( for bids_id in get_bids_subjs_list(bids_dir): rid = int(bids_id_factory(study)(bids_id).to_original_study_id()) - test = ( - pd.DataFrame({"session_id": get_bids_sess_list(bids_dir / bids_id)}) - .set_index("session_id", drop=False) - .sort_index() - ) + test = pd.DataFrame( + {"session_id": get_bids_sess_list(bids_dir / bids_id)} + ).set_index("session_id", drop=False) for _, row in specifications.iterrows(): df = pd.read_csv( @@ -269,80 +261,23 @@ def create_sessions_tsv_file( ) test = pd.concat([test, extract], axis=1) - test = test.map(lambda x: _mapping_unknown(x)) + test.sort_index(inplace=True) + # -4 are considered missing values in AIBL + test.replace([-4, "-4"], np.nan, inplace=True) test["diagnosis"] = test.diagnosis.apply(lambda x: _mapping_diagnosis(x)) - test["age"] = test["age"].fillna(method="ffill") - for i, row in test.iterrows(): - test.loc[i, "age"] = _compute_age_at_exam(row.age, row.examination_date) - # todo : anyway to do this with a apply sthg ? - - # todo : handle exam date - # todo : put back months from ses id ? - - files_to_read = [ - glob.glob(str(clinical_data_dir / loc))[0] - for loc in specifications[f"{study} location"] - ] - sessions_fields_to_read = specifications[study].tolist() - unique_rids = [ - int(bids_id_factory(study)(bids_id).to_original_study_id()) - for bids_id in get_bids_subjs_list(bids_dir) - ] - for rid in unique_rids: - for file in files_to_read: - df = pd.read_csv(file, dtype={"text": str}) - visit_code = df.loc[ - (df["RID"] == rid), "VISCODE" - ] # todo :how to get it out of the loop ? - for field in sessions_fields_to_read: - if field in list(df.columns.values) and field == "MMSCORE": - mm_score = df.loc[(df["RID"] == rid), field] - mm_score[mm_score == -4] = "n/a" - - elif field in list(df.columns.values) and field == "CDGLOBAL": - cd_global = df.loc[(df["RID"] == rid), field] - cd_global[ - cd_global == -4 - ] = "n/a" # todo (LATER) : do that mapping later, same for other fields - - elif field in list(df.columns.values) and field == "DXCURREN": - dx_curren = df.loc[(df["RID"] == rid), field] - dx_curren = dx_curren.apply(lambda x: _mapping_diagnosis(x)) - - elif field in list(df.columns.values) and field == "EXAMDATE": - exam_date = df.loc[(df["RID"] == rid), field] - - elif field in list(df.columns.values) and field == "PTDOB": - patient_date_of_birth = df.loc[(df["RID"] == rid), field] - - exam_dates = _clean_exam_dates( - rid, exam_date.to_list(), visit_code.to_list(), clinical_data_dir + # todo : handle exam date, see function below + # in general age metadata is present only for baseline session + test["age"] = test["age"].ffill() + test["age"] = test.apply( + lambda row: _compute_age_at_exam(row.age, row.examination_date), axis=1 ) - - if not patient_date_of_birth.empty: - age = _compute_ages_at_each_exam( - patient_date_of_birth.values[0], exam_dates - ) - else: - age = "n/a" - - sessions = pd.DataFrame( - { - "session_id": [viscode_to_session(code) for code in visit_code], - "age": age, - "MMS": mm_score, - "cdr_global": cd_global, - "diagnosis": dx_curren, - "examination_date": exam_dates, - } - ) - cols = sessions.columns.tolist() - sessions = sessions[cols[-1:] + cols[:-1]] + # in case there is a session in clinical data that was not actually converted + test.dropna(subset=["session_id"], inplace=True) + test.fillna("n/a", inplace=True) bids_id = bids_id_factory(StudyName.AIBL).from_original_study_id(str(rid)) - - sessions.to_csv( + test.to_csv( bids_dir / bids_id / f"{bids_id}_sessions.tsv", sep="\t", index=False, @@ -350,54 +285,32 @@ def create_sessions_tsv_file( ) -def _clean_exam_dates( - rid: int, - exam_dates: List[Union[str, int]], - visit_codes: List[str], - clinical_data_dir: Path, -) -> List[Union[str, int]]: - """Clean the exam dates when necessary by trying to compute them from other sources. - - Parameters - ---------- - rid : int - Patient study/source id - exam_dates : List - Ex : ['10/12/2007', '05/29/2009', '10/25/2010', -4] - visit_codes : List - Ex : ['bl', 'm18', 'm36', 'm54'] - clinical_data_dir : Path +def _find_exam_dates( + df: pd.DataFrame, session_id: str, rid: int, clinical_data_dir: Path +) -> str: + # todo :test - Returns - ------- - List of cleaned exam dates + # todo : finish from csv + # todo : finish interaction between 2 - """ + from_csv = _find_exam_date_in_other_csv_files(rid, session_id, clinical_data_dir) - from clinica.utils.stream import cprint - - exam_dates_cleaned: List[str] = [] - for visit_code, exam_date in zip(visit_codes, exam_dates): - if exam_date == "-4": - exam_date = _find_exam_date_in_other_csv_files( - rid, visit_code, clinical_data_dir - ) or _compute_exam_date_from_baseline(visit_code, exam_dates, visit_codes) - if not exam_date: - cprint( - f"No EXAMDATE for subject %{rid}, at session {visit_code}", - lvl="debug", - ) - exam_date = "-4" - exam_dates_cleaned.append(exam_date) + try: + baseline_date = df.loc["ses-M000"]["examination_date"] + except KeyError: + from_baseline = None + else: + from_baseline = _compute_exam_date_from_baseline(session_id, baseline_date) - return exam_dates_cleaned + date = from_csv or from_baseline + return from_baseline def _find_exam_date_in_other_csv_files( rid: int, visit_code: str, clinical_data_dir: Path ) -> Optional[str]: """Try to find an alternative exam date by searching in other CSV files.""" - # todo (LATER) : refactor and test depending on _get_csv_files + # todo (LATER) : refactor to use session_id for csv_file in _get_csv_files(clinical_data_dir): if "aibl_flutemeta" in csv_file: csv_data = pd.read_csv( @@ -431,81 +344,29 @@ def _get_csv_files(clinical_data_dir: Path) -> List[str]: def _compute_exam_date_from_baseline( - visit_code: str, exam_dates: List[Union[str, int]], visit_codes: List[str] + session_id: str, + baseline_date: str, ) -> Optional[str]: - """Try to find an alternative exam date by computing the number of months from the visit code. - - Parameters - ---------- - visit_code : Visit code of the current analysed session - exam_dates : List of all the exam_dates for one subject (ex : ['01/01/2000', -4]) - visit_codes : List of all the visit codes for one subject (ex : ['bl', 'm12'] - - Returns - ------- - Either None or the calculated date (str) - """ - # todo (LATER) : this function could use a refactor though, - # for the same output you could just use the visitcode and the date at baseline (no need to use the lists) - # assuming you know it. There it returns none if its baseline ? why not the baseline date ? - import re from datetime import datetime from dateutil.relativedelta import relativedelta - if visit_code != "bl": - try: - months = int(re.match(r"m(\d*)", visit_code).group(1)) - except AttributeError: - raise ValueError( - f"Unexpected visit code {visit_code}. Should be in format mX :" - "Ex: m0, m6, m12, m048..." - ) - baseline_index = visit_codes.index("bl") - baseline_date = datetime.strptime(exam_dates[baseline_index], "%m/%d/%Y") - exam_date = baseline_date + relativedelta(months=+months) - return exam_date.strftime("%m/%d/%Y") + if session_id != "ses-M000": + if not bool(np.isnan(baseline_date)): + try: + months = int(re.match(r"ses-M(\d*)", session_id).group(1)) + except AttributeError: + raise ValueError( + f"Unexpected visit code {session_id}. Should be in format ses-MX :" + "Ex: ses-M000, ses-M006, ses-M012..." + ) + baseline_date = datetime.strptime(baseline_date, "%m/%d/%Y") + exam_date = baseline_date + relativedelta(months=+months) + return exam_date.strftime("%m/%d/%Y") return None -def _compute_ages_at_each_exam( - patient_date_of_birth: str, exam_dates: List[str] -) -> List[float]: - """Compute the ages of the patient at each exam date. - - Parameters - ---------- - patient_date_of_birth : str - Date of birth of patient ("/%Y" format) - - exam_dates : list of str - List of exam dates ("%m/%d/%Y" format) - - Return - ------ - list of float - The ages of the patient at each exam date. - """ - from datetime import datetime - - ages: List[float] = [] - date_of_birth = datetime.strptime(patient_date_of_birth, "/%Y") - - for exam_date in exam_dates: - exam_date = datetime.strptime(exam_date, "%m/%d/%Y") - delta = exam_date.year - date_of_birth.year - ages.append(delta) - - # todo (NOW) : - # rq : what is the use of being so precise ? we are comparing a year with a full date.. that's false anyway - # we could give ages in years (int, >=0) and just subtract the years - - # todo (LATER) : what happens if wrong format ? - - return ages - - def create_scans_tsv_file( input_path: Path, clinical_data_dir: Path, diff --git a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py index 6c7b17e0a..958a8a42f 100644 --- a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py +++ b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py @@ -25,21 +25,19 @@ def test_mapping_diagnosis(diagnosis, expected): @pytest.mark.parametrize( - "visit, visit_list, date_list, expected", + "session_id, baseline_date, expected", [ - ("bl", ["bl", "m10"], ["01/01/2000", -4], None), - ("m10", ["bl", "m10"], ["01/01/2000", -4], "11/01/2000"), - ("m0006", ["bl"], ["01/01/2000"], "07/01/2000"), + ("ses-M000", "foo", None), + ("ses-M010", "01/01/2000", "11/01/2000"), + ("ses-M010", np.nan, None), ], ) -def test_compute_exam_date_from_baseline_success( - visit, date_list, visit_list, expected -): +def test_compute_exam_date_from_baseline_success(session_id, baseline_date, expected): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( _compute_exam_date_from_baseline, ) - assert _compute_exam_date_from_baseline(visit, date_list, visit_list) == expected + assert _compute_exam_date_from_baseline(session_id, baseline_date) == expected def test_compute_exam_date_from_baseline_raiseValue(): @@ -120,25 +118,6 @@ def test_get_first_file_matching_pattern_error(tmp_path, pattern, msg): _get_first_file_matching_pattern(tmp_path, pattern) -@pytest.mark.parametrize( - "birth_date, exam_date, age", - [ - ( - "/2000", - ["01/02/2000", "02/01/2000", "01/01/2001", "07/06/2003"], - [0, 0, 1, 3], - ), - ("/2001", ["12/30/2003"], [2]), - ], -) -def test_compute_age(birth_date, exam_date, age): - from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( - _compute_ages_at_each_exam, - ) - - assert _compute_ages_at_each_exam(birth_date, exam_date) == age - - def build_sessions_spec(tmp_path: Path) -> Path: spec = pd.DataFrame( { From 96ccb417f8d354fb7f43c21451acd6188d0d610e Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Wed, 30 Oct 2024 17:31:49 +0100 Subject: [PATCH 3/7] End of proposition --- .../converters/aibl_to_bids/utils/clinical.py | 145 ++++-------- .../aibl_to_bids/test_aibl_utils.py | 214 ++++++++++++++---- 2 files changed, 216 insertions(+), 143 deletions(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index 77e1138df..919c4b77a 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -1,6 +1,5 @@ -from ast import Index from pathlib import Path -from typing import List, Optional, Union +from typing import Optional, Tuple import numpy as np import pandas as pd @@ -11,8 +10,6 @@ "create_sessions_tsv_file", ] -from sqlalchemy.sql.operators import from_ - def create_participants_tsv_file( input_path: Path, @@ -153,7 +150,6 @@ def _load_specifications( def _mapping_diagnosis(diagnosis: int) -> str: - # todo : what if str(1) ? if diagnosis == 1: return "CN" elif diagnosis == 2: @@ -167,7 +163,6 @@ def _mapping_diagnosis(diagnosis: int) -> str: def _extract_metadata_df( input_df: pd.DataFrame, source_id: int, bids_metadata: str, source_metadata: str ) -> pd.DataFrame: - # todo :test from clinica.iotools.converter_utils import viscode_to_session extract = input_df.loc[(input_df["RID"] == source_id), ["VISCODE", source_metadata]] @@ -182,32 +177,15 @@ def _extract_metadata_df( def _compute_age_at_exam( - birth_date: Union[float, str], exam_date: Union[float, str] -) -> float: - """Compute the ages of the patient at each exam date. - - Parameters - ---------- - birth_date : str - Date of birth of patient ("/%Y" format) - - exam_date : str - Exam date ("%m/%d/%Y" format) - - Return - ------ - float - Age of the patient at exam date. - """ - # todo : test + birth_date: Optional[str], exam_date: Optional[str] +) -> Optional[float]: from datetime import datetime - if not isinstance(birth_date, float) and not isinstance(exam_date, float): + if birth_date and exam_date: date_of_birth = datetime.strptime(birth_date, "/%Y") exam_date = datetime.strptime(exam_date, "%m/%d/%Y") return exam_date.year - date_of_birth.year - else: - return np.nan + return None def create_sessions_tsv_file( @@ -228,6 +206,7 @@ def create_sessions_tsv_file( clinical_specifications_folder : Path The path to the folder containing the clinical specification files. """ + # todo :rename test import glob from clinica.iotools.bids_utils import ( @@ -263,15 +242,21 @@ def create_sessions_tsv_file( test.sort_index(inplace=True) # -4 are considered missing values in AIBL - test.replace([-4, "-4"], np.nan, inplace=True) + test.replace([-4, "-4", np.nan], None, inplace=True) test["diagnosis"] = test.diagnosis.apply(lambda x: _mapping_diagnosis(x)) + test["examination_date"] = test.apply( + lambda x: _complete_examination_dates( + rid, x.session_id, x.examination_date, clinical_data_dir + ), + axis=1, + ) - # todo : handle exam date, see function below # in general age metadata is present only for baseline session test["age"] = test["age"].ffill() test["age"] = test.apply( - lambda row: _compute_age_at_exam(row.age, row.examination_date), axis=1 + lambda x: _compute_age_at_exam(x.age, x.examination_date), axis=1 ) + # in case there is a session in clinical data that was not actually converted test.dropna(subset=["session_id"], inplace=True) test.fillna("n/a", inplace=True) @@ -285,86 +270,56 @@ def create_sessions_tsv_file( ) -def _find_exam_dates( - df: pd.DataFrame, session_id: str, rid: int, clinical_data_dir: Path -) -> str: - # todo :test - - # todo : finish from csv - # todo : finish interaction between 2 - - from_csv = _find_exam_date_in_other_csv_files(rid, session_id, clinical_data_dir) - - try: - baseline_date = df.loc["ses-M000"]["examination_date"] - except KeyError: - from_baseline = None - else: - from_baseline = _compute_exam_date_from_baseline(session_id, baseline_date) - - date = from_csv or from_baseline - return from_baseline +def _complete_examination_dates( + rid: int, + session_id: Optional[str], + examination_date: Optional[str], + clinical_data_dir: Path, +) -> Optional[str]: + if examination_date: + return examination_date + if session_id: + return _find_exam_date_in_other_csv_files(rid, session_id, clinical_data_dir) + return None def _find_exam_date_in_other_csv_files( - rid: int, visit_code: str, clinical_data_dir: Path + rid: int, session_id: str, clinical_data_dir: Path ) -> Optional[str]: """Try to find an alternative exam date by searching in other CSV files.""" - # todo (LATER) : refactor to use session_id - for csv_file in _get_csv_files(clinical_data_dir): - if "aibl_flutemeta" in csv_file: - csv_data = pd.read_csv( - csv_file, low_memory=False, usecols=list(range(0, 36)) - ) - else: - csv_data = pd.read_csv(csv_file, low_memory=False) - exam_date = csv_data[(csv_data.RID == rid) & (csv_data.VISCODE == visit_code)] + from clinica.iotools.converter_utils import viscode_to_session + + for csv in _get_csv_paths(clinical_data_dir): + csv_data = pd.read_csv(csv, low_memory=False) + csv_data["SESSION"] = csv_data.VISCODE.apply(lambda x: viscode_to_session(x)) + exam_date = csv_data[(csv_data.RID == rid) & (csv_data.SESSION == session_id)] if not exam_date.empty and exam_date.iloc[0].EXAMDATE != "-4": return exam_date.iloc[0].EXAMDATE return None -def _get_csv_files(clinical_data_dir: Path) -> List[str]: +def _get_csv_paths(clinical_data_dir: Path) -> Tuple[str]: """Return a list of paths to CSV files in which an alternative exam date could be found.""" import glob - # todo (LATER) : would be better to use a function similar to load_clinical_csv from ADNI - # bc there it does not check for existence and can return anything - - return [ - glob.glob(str(clinical_data_dir / pattern))[0] - for pattern in ( - "aibl_mri3meta_*.csv", - "aibl_mrimeta_*.csv", - "aibl_cdr_*.csv", - "aibl_flutemeta_*.csv", - "aibl_mmse_*.csv", - "aibl_pibmeta_*.csv", - ) - ] + pattern_list = ( + "aibl_mri3meta_*.csv", + "aibl_mrimeta_*.csv", + "aibl_cdr_*.csv", + "aibl_flutemeta_*.csv", + "aibl_mmse_*.csv", + "aibl_pibmeta_*.csv", + ) -def _compute_exam_date_from_baseline( - session_id: str, - baseline_date: str, -) -> Optional[str]: - import re - from datetime import datetime + paths_list = () - from dateutil.relativedelta import relativedelta - - if session_id != "ses-M000": - if not bool(np.isnan(baseline_date)): - try: - months = int(re.match(r"ses-M(\d*)", session_id).group(1)) - except AttributeError: - raise ValueError( - f"Unexpected visit code {session_id}. Should be in format ses-MX :" - "Ex: ses-M000, ses-M006, ses-M012..." - ) - baseline_date = datetime.strptime(baseline_date, "%m/%d/%Y") - exam_date = baseline_date + relativedelta(months=+months) - return exam_date.strftime("%m/%d/%Y") - return None + for pattern in pattern_list: + try: + path = glob.glob(str(clinical_data_dir / pattern))[0] + paths_list += (path,) + except IndexError: + pass + return paths_list def create_scans_tsv_file( diff --git a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py index 958a8a42f..6e8277ad1 100644 --- a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py +++ b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py @@ -1,3 +1,4 @@ +from distutils.command.build import build from pathlib import Path import numpy as np @@ -6,6 +7,18 @@ from pandas.testing import assert_frame_equal +@pytest.mark.parametrize( + "birth_date, exam_date, expected", + [(None, "foo", None), ("foo", None, None), ("/2000", "01/01/2012", 12)], +) +def test_compute_age_at_exam(birth_date, exam_date, expected): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _compute_age_at_exam, + ) + + assert _compute_age_at_exam(birth_date, exam_date) == expected + + @pytest.mark.parametrize( "diagnosis, expected", [ @@ -14,6 +27,7 @@ (2, "MCI"), (3, "AD"), (0, "n/a"), + (None, "n/a"), ], ) def test_mapping_diagnosis(diagnosis, expected): @@ -24,35 +38,6 @@ def test_mapping_diagnosis(diagnosis, expected): assert _mapping_diagnosis(diagnosis) == expected -@pytest.mark.parametrize( - "session_id, baseline_date, expected", - [ - ("ses-M000", "foo", None), - ("ses-M010", "01/01/2000", "11/01/2000"), - ("ses-M010", np.nan, None), - ], -) -def test_compute_exam_date_from_baseline_success(session_id, baseline_date, expected): - from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( - _compute_exam_date_from_baseline, - ) - - assert _compute_exam_date_from_baseline(session_id, baseline_date) == expected - - -def test_compute_exam_date_from_baseline_raiseValue(): - from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( - _compute_exam_date_from_baseline, - ) - - with pytest.raises( - ValueError, - match=f"Unexpected visit code foo. Should be in format mX :" - "Ex: m0, m6, m12, m048...", - ): - _compute_exam_date_from_baseline("foo", [], []) - - def test_load_specifications_success(tmp_path): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( _load_specifications, @@ -148,6 +133,8 @@ def build_bids_dir(tmp_path: Path) -> Path: (bids_dir / "sub-AIBL1" / "ses-M000").mkdir(parents=True) (bids_dir / "sub-AIBL100" / "ses-M000").mkdir(parents=True) (bids_dir / "sub-AIBL100" / "ses-M012").mkdir(parents=True) + (bids_dir / "sub-AIBL109" / "ses-M000").mkdir(parents=True) + (bids_dir / "sub-AIBL109" / "ses-M006").mkdir(parents=True) return bids_dir @@ -157,14 +144,16 @@ def build_clinical_data(tmp_path: Path) -> Path: neuro = pd.DataFrame( { - "RID": [1, 2, 12, 100, 100], # %m/%d/%Y - "VISCODE": ["bl", "bl", "bl", "bl", "m12"], + "RID": [1, 2, 12, 100, 100, 109, 109], # %m/%d/%Y + "VISCODE": ["bl", "bl", "bl", "bl", "m12", "bl", "m06"], "EXAMDATE": [ "01/01/2001", "01/01/2002", "01/01/2012", "01/01/2100", "12/01/2100", + "01/01/2109", + -4, ], } ) @@ -181,34 +170,148 @@ def build_clinical_data(tmp_path: Path) -> Path: cdr = pd.DataFrame( { - "RID": [1, 2, 12, 100, 100], - "VISCODE": ["bl", "bl", "bl", "bl", "m12"], - "CDGLOBAL": [-4, 1, 0.5, 0, 0], + "RID": [1, 2, 12, 100, 100, 109, 109], + "VISCODE": ["bl", "bl", "bl", "bl", "m12", "bl", "m06"], + "CDGLOBAL": [-4, 1, 0.5, 0, 0, 0, 0], + "EXAMDATE": [ + "01/01/2001", + "01/01/2002", + "01/01/2012", + "01/01/2100", + "12/01/2100", + "01/01/2109", + -4, + ], } ) # rq:float cdr.to_csv(data_path / "aibl_cdr_230ct2024.csv", index=False) mmse = pd.DataFrame( { - "RID": [1, 2, 12, 100, 100], - "VISCODE": ["bl", "bl", "bl", "bl", "m12"], - "MMSCORE": [-4, 10, 10, 30, 29], + "RID": [1, 2, 12, 100, 100, 109, 109], + "VISCODE": ["bl", "bl", "bl", "bl", "m12", "bl", "m06"], + "MMSCORE": [-4, 10, 10, 30, 29, 10, 10], + "EXAMDATE": [ + "01/01/2001", + "01/01/2002", + "01/01/2012", + "01/01/2100", + "12/01/2100", + "01/01/2109", + -4, + ], } - ) # rq:int + ) mmse.to_csv(data_path / "aibl_mmse_230ct2024.csv", index=False) pdx = pd.DataFrame( { - "RID": [1, 2, 12, 100, 100], - "VISCODE": ["bl", "bl", "bl", "bl", "m12"], - "DXCURREN": [-4, 0, 0, 1, 3], + "RID": [1, 2, 12, 100, 100, 109, 109], + "VISCODE": ["bl", "bl", "bl", "bl", "m12", "bl", "m06"], + "DXCURREN": [-4, 0, 0, 1, 3, 2, 2], } - ) # rq : int + ) pdx.to_csv(data_path / "aibl_pdxconv_230ct2024.csv", index=False) + mri3 = pd.DataFrame( + { + "RID": [1, 2, 12, 100, 100, 109, 109], # %m/%d/%Y + "VISCODE": ["bl", "bl", "bl", "bl", "m12", "bl", "m06"], + "EXAMDATE": [ + "01/01/2001", + "01/01/2002", + "01/01/2012", + "01/01/2100", + "12/01/2100", + "01/01/2109", + -4, + ], + } + ) + mri3.to_csv(data_path / "aibl_mri3meta_230ct2024.csv", index=False) return data_path +def test_extract_metadata_df(tmp_path): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _extract_metadata_df, + ) + + clinical_dir = build_clinical_data(tmp_path) + expected = pd.DataFrame( + { + "session_id": ["ses-M000", "ses-M006"], + "examination_date": ["01/01/2109", "-4"], + } + ).set_index("session_id", drop=True) + result = _extract_metadata_df( + pd.read_csv(clinical_dir / "aibl_neurobat_230ct2024.csv", dtype={"text": str}), + 109, + bids_metadata="examination_date", + source_metadata="EXAMDATE", + ) + + assert_frame_equal(expected, result) + + +@pytest.mark.parametrize( + "source_id, session_id, expected", + [ + (109, "ses-M000", "01/01/2109"), + (109, "ses-M006", None), + (109, "ses-M014", None), + (0, "ses-M014", None), + ], +) +def test_find_exam_date_in_other_csv_files(tmp_path, source_id, session_id, expected): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _find_exam_date_in_other_csv_files, + ) + + clinical_dir = build_clinical_data(tmp_path) + assert ( + _find_exam_date_in_other_csv_files(source_id, session_id, clinical_dir) + == expected + ) + + +def test_get_csv_paths(tmp_path): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import _get_csv_paths + + assert _get_csv_paths(tmp_path) == () + + clinical_dir = build_clinical_data(tmp_path) + csv_paths = [Path(path).name for path in _get_csv_paths(clinical_dir)] + + assert set(csv_paths) == { + "aibl_cdr_230ct2024.csv", + "aibl_mmse_230ct2024.csv", + "aibl_mri3meta_230ct2024.csv", + } + + +@pytest.mark.parametrize( + "rid, session_id, exam_date, expected", + [ + (0, "foo", "01/01/2000", "01/01/2000"), + (0, None, "01/01/2000", "01/01/2000"), + (0, None, None, None), + (109, "ses-M000", None, "01/01/2109"), + (109, "ses-M006", None, None), + ], +) +def test_complete_examination_dates(tmp_path, rid, session_id, exam_date, expected): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _complete_examination_dates, + ) + + clinical_dir = build_clinical_data(tmp_path) + assert ( + _complete_examination_dates(rid, session_id, exam_date, clinical_dir) + == expected + ) + + def test_create_sessions_tsv(tmp_path): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( create_sessions_tsv_file, @@ -223,17 +326,20 @@ def test_create_sessions_tsv(tmp_path): ) result_sub100_list = list(bids_path.rglob("*sub-AIBL100_sessions.tsv")) result_sub1_list = list(bids_path.rglob("*sub-AIBL1_sessions.tsv")) + result_sub109_list = list(bids_path.rglob("*sub-AIBL109_sessions.tsv")) + assert len(result_sub109_list) == 1 assert len(result_sub100_list) == 1 assert len(result_sub1_list) == 1 - result_sub100 = pd.read_csv(result_sub100_list[0], sep="\t") - result_sub1 = pd.read_csv(result_sub1_list[0], sep="\t") + result_sub109 = pd.read_csv(result_sub109_list[0], sep="\t", keep_default_na=False) + result_sub100 = pd.read_csv(result_sub100_list[0], sep="\t", keep_default_na=False) + result_sub1 = pd.read_csv(result_sub1_list[0], sep="\t", keep_default_na=False) expected_sub100 = pd.DataFrame( { "session_id": ["ses-M000", "ses-M012"], - "age": [np.nan, np.nan], + "age": ["n/a", "n/a"], "MMS": [30, 29], "cdr_global": [0.0, 0.0], "diagnosis": ["CN", "AD"], @@ -245,12 +351,24 @@ def test_create_sessions_tsv(tmp_path): { "session_id": ["ses-M000"], "age": [100], - "MMS": [np.nan], - "cdr_global": [np.nan], - "diagnosis": [np.nan], + "MMS": ["n/a"], + "cdr_global": ["n/a"], + "diagnosis": ["n/a"], "examination_date": ["01/01/2001"], } ) + expected_sub109 = pd.DataFrame( + { + "session_id": ["ses-M000", "ses-M006"], + "age": ["n/a", "n/a"], + "MMS": [10, 10], + "cdr_global": [0.0, 0.0], + "diagnosis": ["MCI", "MCI"], + "examination_date": ["01/01/2109", "n/a"], + } + ) + assert_frame_equal(result_sub1, expected_sub1, check_like=True) assert_frame_equal(result_sub100, expected_sub100, check_like=True) + assert_frame_equal(result_sub109, expected_sub109, check_like=True) From d29a1b930220a796c25ccaf4a87d4468e5febda0 Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Wed, 30 Oct 2024 17:33:28 +0100 Subject: [PATCH 4/7] Fix name --- .../converters/aibl_to_bids/utils/clinical.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index 919c4b77a..a68b8ba2d 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -206,7 +206,6 @@ def create_sessions_tsv_file( clinical_specifications_folder : Path The path to the folder containing the clinical specification files. """ - # todo :rename test import glob from clinica.iotools.bids_utils import ( @@ -223,7 +222,7 @@ def create_sessions_tsv_file( for bids_id in get_bids_subjs_list(bids_dir): rid = int(bids_id_factory(study)(bids_id).to_original_study_id()) - test = pd.DataFrame( + sessions = pd.DataFrame( {"session_id": get_bids_sess_list(bids_dir / bids_id)} ).set_index("session_id", drop=False) @@ -238,13 +237,15 @@ def create_sessions_tsv_file( bids_metadata=row["BIDS CLINICA"], source_metadata=row[study], ) - test = pd.concat([test, extract], axis=1) + sessions = pd.concat([sessions, extract], axis=1) - test.sort_index(inplace=True) + sessions.sort_index(inplace=True) # -4 are considered missing values in AIBL - test.replace([-4, "-4", np.nan], None, inplace=True) - test["diagnosis"] = test.diagnosis.apply(lambda x: _mapping_diagnosis(x)) - test["examination_date"] = test.apply( + sessions.replace([-4, "-4", np.nan], None, inplace=True) + sessions["diagnosis"] = sessions.diagnosis.apply( + lambda x: _mapping_diagnosis(x) + ) + sessions["examination_date"] = sessions.apply( lambda x: _complete_examination_dates( rid, x.session_id, x.examination_date, clinical_data_dir ), @@ -252,17 +253,17 @@ def create_sessions_tsv_file( ) # in general age metadata is present only for baseline session - test["age"] = test["age"].ffill() - test["age"] = test.apply( + sessions["age"] = sessions["age"].ffill() + sessions["age"] = sessions.apply( lambda x: _compute_age_at_exam(x.age, x.examination_date), axis=1 ) # in case there is a session in clinical data that was not actually converted - test.dropna(subset=["session_id"], inplace=True) - test.fillna("n/a", inplace=True) + sessions.dropna(subset=["session_id"], inplace=True) + sessions.fillna("n/a", inplace=True) bids_id = bids_id_factory(StudyName.AIBL).from_original_study_id(str(rid)) - test.to_csv( + sessions.to_csv( bids_dir / bids_id / f"{bids_id}_sessions.tsv", sep="\t", index=False, From 1ae8a53a28f6c2dd8994f0cf9ac1b77233024dcc Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Wed, 30 Oct 2024 17:36:18 +0100 Subject: [PATCH 5/7] Fix import --- .../iotools/converters/aibl_to_bids/test_aibl_utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py index 6e8277ad1..b445a5ac1 100644 --- a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py +++ b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py @@ -1,7 +1,5 @@ -from distutils.command.build import build from pathlib import Path -import numpy as np import pandas as pd import pytest from pandas.testing import assert_frame_equal From 56ed48bcb80d6eee6b3d87ce325013be4ce8eebe Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Wed, 6 Nov 2024 14:34:49 +0100 Subject: [PATCH 6/7] Changes as suggested --- .../converters/aibl_to_bids/utils/clinical.py | 77 +- .../converters/specifications/sessions.tsv | 863 +++++++++--------- .../aibl_to_bids/test_aibl_utils.py | 103 ++- 3 files changed, 572 insertions(+), 471 deletions(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index a68b8ba2d..d3fa30891 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -1,3 +1,4 @@ +from multiprocessing.managers import Value from pathlib import Path from typing import Optional, Tuple @@ -149,7 +150,7 @@ def _load_specifications( return pd.read_csv(specifications, sep="\t") -def _mapping_diagnosis(diagnosis: int) -> str: +def _map_diagnosis(diagnosis: int) -> str: if diagnosis == 1: return "CN" elif diagnosis == 2: @@ -160,7 +161,7 @@ def _mapping_diagnosis(diagnosis: int) -> str: return "n/a" -def _extract_metadata_df( +def _format_metadata_for_rid( input_df: pd.DataFrame, source_id: int, bids_metadata: str, source_metadata: str ) -> pd.DataFrame: from clinica.iotools.converter_utils import viscode_to_session @@ -178,7 +179,7 @@ def _extract_metadata_df( def _compute_age_at_exam( birth_date: Optional[str], exam_date: Optional[str] -) -> Optional[float]: +) -> Optional[int]: from datetime import datetime if birth_date and exam_date: @@ -188,6 +189,22 @@ def _compute_age_at_exam( return None +def _set_age_from_birth(df: pd.DataFrame) -> pd.DataFrame: + if "date_of_birth" not in df.columns or "examination_date" not in df.columns: + raise ValueError( + "Columns date_of_birth or/and examination_date were not found in the sessions metadata dataframe." + "Please check your study metadata." + ) + if len(df["date_of_birth"].dropna().unique()) <= 1: + df["date_of_birth"] = df["date_of_birth"].ffill() + df["age"] = df.apply( + lambda x: _compute_age_at_exam(x.date_of_birth, x.examination_date), axis=1 + ) + else: + df["age"] = None + return df.drop(labels="date_of_birth", axis=1) + + def create_sessions_tsv_file( bids_dir: Path, clinical_data_dir: Path, @@ -227,36 +244,37 @@ def create_sessions_tsv_file( ).set_index("session_id", drop=False) for _, row in specifications.iterrows(): - df = pd.read_csv( - glob.glob(str(clinical_data_dir / row[f"{study} location"]))[0], - dtype={"text": str}, - ) - extract = _extract_metadata_df( + try: + df = pd.read_csv( + next(clinical_data_dir.glob(row[f"{study} location"])), + dtype={"text": str}, + ) + except StopIteration: + raise FileNotFoundError( + f"Clinical data file corresponding to pattern {row[f'{study} location']} was not found in folder " + f"{clinical_data_dir}" + ) + + data = _format_metadata_for_rid( input_df=df, source_id=rid, bids_metadata=row["BIDS CLINICA"], source_metadata=row[study], ) - sessions = pd.concat([sessions, extract], axis=1) + sessions = pd.concat([sessions, data], axis=1) sessions.sort_index(inplace=True) + # -4 are considered missing values in AIBL sessions.replace([-4, "-4", np.nan], None, inplace=True) - sessions["diagnosis"] = sessions.diagnosis.apply( - lambda x: _mapping_diagnosis(x) - ) + sessions["diagnosis"] = sessions.diagnosis.apply(lambda x: _map_diagnosis(x)) sessions["examination_date"] = sessions.apply( lambda x: _complete_examination_dates( - rid, x.session_id, x.examination_date, clinical_data_dir + rid, clinical_data_dir, x.session_id, x.examination_date ), axis=1, ) - - # in general age metadata is present only for baseline session - sessions["age"] = sessions["age"].ffill() - sessions["age"] = sessions.apply( - lambda x: _compute_age_at_exam(x.age, x.examination_date), axis=1 - ) + sessions = _set_age_from_birth(sessions) # in case there is a session in clinical data that was not actually converted sessions.dropna(subset=["session_id"], inplace=True) @@ -273,9 +291,9 @@ def create_sessions_tsv_file( def _complete_examination_dates( rid: int, - session_id: Optional[str], - examination_date: Optional[str], clinical_data_dir: Path, + session_id: Optional[str] = None, + examination_date: Optional[str] = None, ) -> Optional[str]: if examination_date: return examination_date @@ -290,7 +308,7 @@ def _find_exam_date_in_other_csv_files( """Try to find an alternative exam date by searching in other CSV files.""" from clinica.iotools.converter_utils import viscode_to_session - for csv in _get_csv_paths(clinical_data_dir): + for csv in _get_csv_files_for_alternative_exam_date(clinical_data_dir): csv_data = pd.read_csv(csv, low_memory=False) csv_data["SESSION"] = csv_data.VISCODE.apply(lambda x: viscode_to_session(x)) exam_date = csv_data[(csv_data.RID == rid) & (csv_data.SESSION == session_id)] @@ -299,11 +317,11 @@ def _find_exam_date_in_other_csv_files( return None -def _get_csv_paths(clinical_data_dir: Path) -> Tuple[str]: +def _get_csv_files_for_alternative_exam_date(clinical_data_dir: Path) -> Tuple[Path]: """Return a list of paths to CSV files in which an alternative exam date could be found.""" import glob - pattern_list = ( + patterns = ( "aibl_mri3meta_*.csv", "aibl_mrimeta_*.csv", "aibl_cdr_*.csv", @@ -312,15 +330,14 @@ def _get_csv_paths(clinical_data_dir: Path) -> Tuple[str]: "aibl_pibmeta_*.csv", ) - paths_list = () + paths = () - for pattern in pattern_list: + for pattern in patterns: try: - path = glob.glob(str(clinical_data_dir / pattern))[0] - paths_list += (path,) - except IndexError: + paths += (next(clinical_data_dir.glob(pattern)),) + except StopIteration: pass - return paths_list + return paths def create_scans_tsv_file( diff --git a/clinica/iotools/converters/specifications/sessions.tsv b/clinica/iotools/converters/specifications/sessions.tsv index 7d7f23a2d..aafe2b517 100644 --- a/clinica/iotools/converters/specifications/sessions.tsv +++ b/clinica/iotools/converters/specifications/sessions.tsv @@ -1,431 +1,432 @@ -Field BIDS CLINICA BIDS format BIDS type INSIGHT INSIGHT location CLINAD AIBL AIBL location OASIS OASIS location OASIS3 OASIS3 location -BIDS session id session_id Keyword 'ses-' followed by the original session id of each dataset without special characters or symbols string -Date of the examination examination_date YYYY-MM-DD HH:MM:SS string date d'evaluation EXAMDATE aibl_neurobat_*.csv -Age at the session age float PTDOB aibl_ptdemog_*.csv Age oasis3_sessions.csv - current_study free format - adni_fdg free format - adni_pib free format - adni_av45 free format - cdr_global CDGLOBAL aibl_cdr_*.csv CDR oasis_cross-sectional-5708aa0a98d82080.xlsx cdr oasis3_sessions.csv - cdr_sb - adas11 - adas13 -Mini-mental state exam MMS int MMS MMSCORE aibl_mmse_*.csv MMSE oasis_cross-sectional-5708aa0a98d82080.xlsx mmse oasis3_sessions.csv - FAQ - adni_ventricles_vol - adni_hippocampus_vol - adni_brain_vol - adni_entorhinal_vol -Intracranial volume adni_icv -Diagnosis at current session diagnosis DXCURREN aibl_pdxconv_*.csv CDR oasis_cross-sectional-5708aa0a98d82080.xlsx cdr oasis3_sessions.csv - cati_sacha_vol_left_hippocampus cm3 float vol_left_hippocampus Analyses_INSIGHT_M0_20151201/Analyses_HPC_SACHA - cati_sacha_vol_right_hippocampus cm3 float vol_right_hippocampus Analyses_INSIGHT_M0_20151202/Analyses_HPC_SACHA - cati_whasa_volume cm3 float volume (cm3) Analyses_INSIGHT_M0_20151203/Analyses_HPC_WHASA - mattis_attention - mattis_initiation - mattis_construction - mattis_concepts - mattis_memory - MATTIS int - FBI -Verbal Fluency Test categorical_fluency int Categorical Verbal Fluency Tst_NRO_NP -Verbal Fluency Test p_fluency int -Grober and Buschke test grober_buschke_free_cued_recall int -Frontal assessment battery FAB int BREF - freesurfer_rh_mean_thickness rh_MeanThickness_thickness (mm) Analyses_INSIGHT_M0_20151201/Analyses_thichness_Freesurfer - freesurfer_lh_mean_thickness lh_MeanThickness_thickness (mm) Analyses_INSIGHT_M0_20151201/Analyses_thichness_Freesurfer - EQ EQ_SCORE TST_NRO_NL.xls/EQ5D - SPPB Total Score TST_NRO_NL.xls/SPPB - AD8 AD8_SCORE Tst_NRO_NP.xlsx/AD8 - MEM MEM_SCORE Tst_NRO_NP.xlsx/MCQ - AD AD_SCORE Tst_NRO_NP.xlsx/AD8 -Grober and Buschke test grober_buschke_free_recall int RL -Grober and Buschke test grober_buschke_total_recall int RT - grober_buschke_free_recall_delayed int RLD - grober_buschke_total_recall_delayed int RTD - motivation_starkstein (Starkstein) Motivation scale Tst_NRO_NP.xlsx/(Starkstein) - verbal_fluency Lexical Verbal Fluency Score Tst_NRO_NP.xlsx/(Verbal Fluency) -Innotest amyloid/tau index IATI float IATI - clinad_CSF CSF AD profile - clinad_amyloidB int B-Amyloide - clinad_tau int Tau - clinad_p_tau int P-Tau - clinad_p_tau_Aß float PTau/Aß - clinad_delay_MRI_CSF Délai IRM PL - clinad_date_MRI_closest_to_CSF Date IRM proche PL - - prevdemals_benson_copy - prevdemals_benson_rappel - prevdemals_benson_total - prevdemals_faux_pas - praxies_dexterity - praxies_gesture_kinetic - praxies_non_meaning_gestures - praxies_intransitive gestures - praxies_transitive_gestures - praxies_total - prevdemals_emotion_total - prevdemals_als - prevdemals_ftd - - - - - - - clinad_amnestic_syndrome_of_hippocampal_type Sd amn hip -Number of words that was not cointaned in the original dataset of words grober_buschke_intrusions intrusions - - clinad_reac_indic Réac indic - clinad_correct_recognitions reconnaissances correctes - clinad_false_recognitions fausses reconnaissnces - - clinad_date_csf Date PL - clinad_spm_vol_gm Vol_SG - clinad_spm_vol_wm Vol_SB - clinad_spm_vol_csf Vol_CSF - clinad_spm_vol_total Vol_Total - clinad_volbrain_scale_factor Scale factor - clinad_volbrain_snr float SNR - clinad_volbrain_msnr float mSNR - clinad_volbrain_qc float QC - clinad_volbrain_tissue_wm_cm3 float Tissue WM cm3 - clinad_volbrain_tissue_wm_% float Tissue WM % - clinad_volbrain_tissue_gm_cm3 float Tissue GM cm3 - clinad_volbrain_tissue_gm_% float Tissue GM % - clinad_volbrain_tissue_csf_cm3 float Tissue CSF cm3 - clinad_volbrain_tissue_csf_% float Tissue CSF % - clinad_volbrain_tissue_brain_cm3 float Tissue Brain cm3 - clinad_volbrain_tissue_brain_% float Tissue Brain % - clinad_volbrain_tissue_ic_cm3 float Tissue IC cm3 - clinad_volbrain_tissue_ic_% float Tissue IC % - clinad_volbrain_cerebrum_total_cm3 float Cerebrum Total cm3 - clinad_volbrain_cerebrum_total_% float Cerebrum Total % - clinad_volbrain_cerebrum_t_gm_cm3 float Cerebrum T GM cm3 - clinad_volbrain_cerebrum_t_gm_% float Cerebrum T GM % - clinad_volbrain_cerebrum_t_wm_cm3 float Cerebrum T WM cm3 - clinad_volbrain_cerebrum_t_wm_% float Cerebrum T WM % - clinad_volbrain_cerebrum_right_cm3 float Cerebrum Right cm3 - clinad_volbrain_cerebrum_right_% float Cerebrum Right % - clinad_volbrain_cerebrum_r_gm_cm3 float Cerebrum R GM cm3 - clinad_volbrain_cerebrum_r_gm_% float Cerebrum R GM % - clinad_volbrain_cerebrum_r_wm_cm3 float Cerebrum R WM cm3 - clinad_volbrain_cerebrum_r_wm_% float Cerebrum R WM % - clinad_volbrain_cerebrum_left_cm3 float Cerebrum Left cm3 - clinad_volbrain_cerebrum_left_% float Cerebrum Left % - clinad_volbrain_cerebrum_l_gm_cm3 float Cerebrum L GM cm3 - clinad_volbrain_cerebrum_l_gm_% float Cerebrum L GM % - clinad_volbrain_cerebrum_l_wm_cm3 float Cerebrum L WM cm3 - clinad_volbrain_cerebrum_l_wm_% float Cerebrum L WM % - clinad_volbrain_cerebrum_assymetry float Cerebrum Asymmetry - clinad_volbrain_cerebelum_total_cm3 float Cerebelum Total cm3 - clinad_volbrain_cerebelum_total_% float Cerebelum Total % - clinad_volbrain_cerebelum_t_gm_cm3 float Cerebelum T GM cm3 - clinad_volbrain_cerebelum_t_gm_% float Cerebelum T GM % - clinad_volbrain_cerebelum_t_wm_cm3 float Cerebelum T WM cm3 - clinad_volbrain_cerebelum_t_wm_% float Cerebelum T WM % - clinad_volbrain_cerebelum_right_cm3 float Cerebelum Right cm3 - clinad_volbrain_cerebelum_right_% float Cerebelum Right % - clinad_volbrain_cerebelum_r_gm_cm3 float Cerebelum R GM cm3 - clinad_volbrain_cerebelum_r_gm_% float Cerebelum R GM % - clinad_volbrain_cerebelum_r_wm_cm3 float Cerebelum R WM cm3 - clinad_volbrain_cerebelum_r_wm_% float Cerebelum R WM % - clinad_volbrain_cerebelum_left_cm3 float Cerebelum Left cm3 - clinad_volbrain_cerebelum_left_% float Cerebelum Left % - clinad_volbrain_cerebelum_l_gm_cm3 float Cerebelum L GM cm3 - clinad_volbrain_cerebelum_l_gm_% float Cerebelum L GM % - clinad_volbrain_cerebelum_l_wm_cm3 float Cerebelum L WM cm3 - clinad_volbrain_cerebelum_l_wm_% float Cerebelum L WM % - clinad_volbrain_cerebelum_assymetry float Cerebelum Asymmetry - clinad_volbrain_brainstem_cm3 float Brainstem cm3 - clinad_volbrain_brainstem_% float Brainstem % - clinad_volbrain_lateral_ventricles_total_cm3 float Lateral ventricles Total cm3 - clinad_volbrain_lateral_ventricles_total_% float Lateral ventricles Total % - clinad_volbrain_lateral_ventricles_right_cm3 float Lateral ventricles Right cm3 - clinad_volbrain_lateral_ventricles_right_% float Lateral ventricles Right % - clinad_volbrain_lateral_ventricles_left_cm3 float Lateral ventricles Left cm3 - clinad_volbrain_lateral_ventricles_left_% float Lateral ventricles Left % - clinad_volbrain_lateral_ventricles_asymmetry float Lateral ventricles Asymmetry - clinad_volbrain_caudate_total_cm3 float Caudate Total cm3 - clinad_volbrain_caudate_total_% float Caudate Total % - clinad_volbrain_caudate_right_cm3 float Caudate Right cm3 - clinad_volbrain_caudate_right_% float Caudate Right % - clinad_volbrain_caudate_left_cm3 float Caudate Left cm3 - clinad_volbrain_caudate_left_% float Caudate Left % - clinad_volbrain_caudate_asymmetry float Caudate Asymmetry - clinad_volbrain_putamen_total_cm3 float Putamen Total cm3 - clinad_volbrain_putamen_total_% float Putamen Total % - clinad_volbrain_putamen_right_cm3 float Putamen Right cm3 - clinad_volbrain_putamen_right_% float Putamen Right % - clinad_volbrain_putamen_left_cm3 float Putamen Left cm3 - clinad_volbrain_putamen_left_% float Putamen Left % - clinad_volbrain_putamen_asymmetry float Putamen Asymmetry - clinad_volbrain_thalamus_total_cm3 float Thalamus Total cm3 - clinad_volbrain_thalamus_total_% float Thalamus Total % - clinad_volbrain_thalamus_right_cm3 float Thalamus Right cm3 - clinad_volbrain_thalamus_right_% float Thalamus Right % - clinad_volbrain_thalamus_left_cm3 float Thalamus Left cm3 - clinad_volbrain_thalamus_left_% float Thalamus Left % - clinad_volbrain_thalamus_asymmetry float Thalamus Asymmetry - clinad_volbrain_globus_pallidus_total_cm3 float Globus Pallidus Total cm3 - clinad_volbrain_globus_pallidus_total_% float Globus Pallidus Total % - clinad_volbrain_globus_pallidus_right_cm3 float Globus Pallidus Right cm3 - clinad_volbrain_globus_pallidus_right_% float Globus Pallidus Right % - clinad_volbrain_globus_pallidus_left_cm3 float Globus Pallidus Left cm3 - clinad_volbrain_globus_pallidus_left_% float Globus Pallidus Left % - clinad_volbrain_globus_pallidus_asymmetry float Globus Pallidus Asymmetry - clinad_volbrain_hippocampus_total_cm3 float Hippocampus Total cm3 - clinad_volbrain_hippocampus_total_% float Hippocampus Total % - clinad_volbrain_hippocampus_right_cm3 float Hippocampus Right cm3 - clinad_volbrain_hippocampus_right_% float Hippocampus Right % - clinad_volbrain_hippocampus_left_cm3 float Hippocampus Left cm3 - clinad_volbrain_hippocampus_left_% float Hippocampus Left % - clinad_volbrain_hippocampus_asymmetry float Hippocampus Asymmetry - clinad_volbrain_amygdala_total_cm3 float Amygdala Total cm3 - clinad_volbrain_amygdala_total_% float Amygdala Total % - clinad_volbrain_amygdala_right_cm3 float Amygdala Right cm3 - clinad_volbrain_amygdala_right_% float Amygdala Right % - clinad_volbrain_amygdala_left_cm3 float Amygdala Left cm3 - clinad_volbrain_amygdala_left_% float Amygdala Left % - clinad_volbrain_amygdala_asymmetry float Amygdala Asymmetry - clinad_volbrain_accumbens_total_cm3 Accumbens Total cm3 - clinad_volbrain_accumbens_total_% Accumbens Total % - clinad_volbrain_accumbens_right_cm3 Accumbens Right cm3 - clinad_volbrain_accumbens_right_% Accumbens Right % - clinad_volbrain_accumbens_left_cm3 Accumbens Left cm3 - clinad_volbrain_accumbens_left_% Accumbens Left % - clinad_volbrain_accumbens_asymmetry Accumbens Asymmetry - clinad_brainreader_id_rm MR ID - clinad_brainreader_clinical_image_id Clinical image id - clinad_brainreader_filename Filename - clinad_brainreader_nr_version NR version - clinad_brainreader_mtiv_in_ml float The measured total intracranial volume (mTIV) in ml - clinad_brainreader_hippocampal_left_right_asymmetry_index float Hippocampal Left-Right Asymmetry Index - clinad_brainreader_hippocampal_left_right_asymmetry_index_nr_index float Hippocampal Left-Right Asymmetry Index NR Index - clinad_brainreader_hippocampal_left_right_asymmetry_index_z_score float Hippocampal Left-Right Asymmetry Index z-score - clinad_brainreader_hippocampal_left_right_asymmetry_index_percentile float Hippocampal Left-Right Asymmetry Index percentile - clinad_brainreader_whole_brain_matter_volume_in_ml float Whole-Brain-Matter volume in ml - clinad_brainreader_whole_brain_matter_vol_mtiv_ratio float Whole-Brain-Matter Vol/mTIV ratio - clinad_brainreader_whole_brain_matter_nr_index float Whole-Brain-Matter NR Index - clinad_brainreader_whole_brain_matter_z_score float Whole-Brain-Matter z-score - clinad_brainreader_whole_brain_matter_percentile float Whole-Brain-Matter percentile - clinad_brainreader_white_matter_volume_in_ml float White-Matter volume in ml - clinad_brainreader_white_matter_vol_mtiv_ratio float White-Matter Vol/mTIV ratio - clinad_brainreader_white_matter_nr_index float White-Matter NR Index - clinad_brainreader_white_matter_z_score float White-Matter z-score - clinad_brainreader_white_matter_percentile float White-Matter percentile - clinad_brainreader_gray_matter_volume_in_ml float Gray-Matter volume in ml - clinad_brainreader_gray_matter_vol_mtiv_ratio float Gray-Matter Vol/mTIV ratio - clinad_brainreader_gray_matter_nr_index float Gray-Matter NR Index - clinad_brainreader_gray_matter_z_score float Gray-Matter z-score - clinad_brainreader_gray_matter_percentile float Gray-Matter percentile - clinad_brainreader_csf_dura_volume_in_ml float CSF-(+-dura) volume in ml - clinad_brainreader_csf_dura_vol_mtiv_ratio float CSF-(+-dura) Vol/mTIV ratio - clinad_brainreader_csf_dura_nr_index float CSF-(+-dura) NR Index - clinad_brainreader_csf_dura_z_score float CSF-(+-dura) z-score - clinad_brainreader_csf_dura_percentile float CSF-(+-dura) percentile - clinad_brainreader_left_hippocampus_volume_in_ml float Left-Hippocampus volume in ml - clinad_brainreader_left_hippocampus_vol_mtiv_ratio float Left-Hippocampus Vol/mTIV ratio - clinad_brainreader_left_hippocampus_nr_index float Left-Hippocampus NR Index - clinad_brainreader_left_hippocampus_z_score float Left-Hippocampus z-score - clinad_brainreader_left_hippocampus_percentile float Left-Hippocampus percentile - clinad_brainreader_right_hippocampus_volume_in_ml float Right-Hippocampus volume in ml - clinad_brainreader_right_hippocampus_vol_mtiv_ratio float Right-Hippocampus Vol/mTIV ratio - clinad_brainreader_right_hippocampus_nr_index float Right-Hippocampus NR Index - clinad_brainreader_right_hippocampus_z_score float Right-Hippocampus z-score - clinad_brainreader_right_hippocampus_percentile float Right-Hippocampus percentile - clinad_brainreader_hippocampus_volume_in_ml float Hippocampus volume in ml - clinad_brainreader_hippocampus_vol_mtiv_ratio float Hippocampus Vol/mTIV ratio - clinad_brainreader_hippocampus_nr_index float Hippocampus NR Index - clinad_brainreader_hippocampus_z_score float Hippocampus z-score - clinad_brainreader_hippocampus_percentile float Hippocampus percentile - clinad_brainreader_left_amygdala_volume_in_ml float Left-Amygdala volume in ml - clinad_brainreader_left_amygdala_vol_mtiv_ratio float Left-Amygdala Vol/mTIV ratio - clinad_brainreader_left_amygdala_nr_index float Left-Amygdala NR Index - clinad_brainreader_left_amygdala_z_score float Left-Amygdala z-score - clinad_brainreader_left_amygdala_percentile float Left-Amygdala percentile - clinad_brainreader_right_amygdala_volume_in_ml float Right-Amygdala volume in ml - clinad_brainreader_right_amygdala_vol_mtiv_ratio float Right-Amygdala Vol/mTIV ratio - clinad_brainreader_right_amygdala_nr_index float Right-Amygdala NR Index - clinad_brainreader_right_amygdala_z_score float Right-Amygdala z-score - clinad_brainreader_right_amygdala_percentile float Right-Amygdala percentile - clinad_brainreader_amygdala_volume_in_ml float Amygdala volume in ml - clinad_brainreader_amygdala_vol_mtiv_ratio float Amygdala Vol/mTIV ratio - clinad_brainreader_amygdala_nr_index float Amygdala NR Index - clinad_brainreader_amygdala_z_score float Amygdala z-score - clinad_brainreader_amygdala_percentile float Amygdala percentile - clinad_brainreader_brain_stem_volume_in_ml float Brain-Stem volume in ml - clinad_brainreader_brain_stem_vol_mtiv_ratio float Brain-Stem Vol/mTIV ratio - clinad_brainreader_brain_stem_nr_index float Brain-Stem NR Index - clinad_brainreader_brain_stem_z_score float Brain-Stem z-score - clinad_brainreader_brain_stem_percentile float Brain-Stem percentile - clinad_brainreader_caudate_volume_in_ml float Caudate volume in ml - clinad_brainreader_caudate_vol_mtiv_ratio float Caudate Vol/mTIV ratio - clinad_brainreader_caudate_nr_index float Caudate NR Index - clinad_brainreader_caudate_z_score float Caudate z-score - clinad_brainreader_caudate_percentile float Caudate percentile - clinad_brainreader_left_caudate_volume_in_ml float Left-Caudate volume in ml - clinad_brainreader_left_caudate_vol_mtiv_ratio float Left-Caudate Vol/mTIV ratio - clinad_brainreader_left_caudate_nr_index float Left-Caudate NR Index - clinad_brainreader_left_caudate_z_score float Left-Caudate z-score - clinad_brainreader_left_caudate_percentile float Left-Caudate percentile - clinad_brainreader_right_caudate_volume_in_ml float Right-Caudate volume in ml - clinad_brainreader_right_caudate_vol_mtiv_ratio float Right-Caudate Vol/mTIV ratio - clinad_brainreader_right_caudate_nr_index float Right-Caudate NR Index - clinad_brainreader_right_caudate_z_score float Right-Caudate z-score - clinad_brainreader_right_caudate_percentile float Right-Caudate percentile - clinad_brainreader_left_cerebellum_volume_in_ml float Left-Cerebellum volume in ml - clinad_brainreader_left_cerebellum_vol_mtiv_ratio float Left-Cerebellum Vol/mTIV ratio - clinad_brainreader_left_cerebellum_nr_index float Left-Cerebellum NR Index - clinad_brainreader_left_cerebellum_z_score float Left-Cerebellum z-score - clinad_brainreader_left_cerebellum_percentile float Left-Cerebellum percentile - clinad_brainreader_right_cerebellum_volume_in_ml float Right-Cerebellum volume in ml - clinad_brainreader_right_cerebellum_vol_mtiv_ratio float Right-Cerebellum Vol/mTIV ratio - clinad_brainreader_right_cerebellum_nr_index float Right-Cerebellum NR Index - clinad_brainreader_right_cerebellum_z_score float Right-Cerebellum z-score - clinad_brainreader_right_cerebellum_percentile float Right-Cerebellum percentile - clinad_brainreader_cerebellum_volume_in_ml float Cerebellum volume in ml - clinad_brainreader_cerebellum_vol_mtiv_ratio float Cerebellum Vol/mTIV ratio - clinad_brainreader_cerebellum_nr_index float Cerebellum NR Index - clinad_brainreader_cerebellum_z_score float Cerebellum z-score - clinad_brainreader_cerebellum_percentile float Cerebellum percentile - clinad_brainreader_lateral_ventricle_volume_in_ml float Lateral-Ventricle volume in ml - clinad_brainreader_lateral_ventricle_vol_mtiv_ratio float Lateral-Ventricle Vol/mTIV ratio - clinad_brainreader_lateral_ventricle_nr_index float Lateral-Ventricle NR Index - clinad_brainreader_lateral_ventricle_z_score float Lateral-Ventricle z-score - clinad_brainreader_lateral_ventricle_percentile float Lateral-Ventricle percentile - clinad_brainreader_left_lateral_ventricle_volume_in_ml float Left-Lateral-Ventricle volume in ml - clinad_brainreader_left_lateral_ventricle_vol_mtiv_ratio float Left-Lateral-Ventricle Vol/mTIV ratio - clinad_brainreader_left_lateral_ventricle_nr_index float Left-Lateral-Ventricle NR Index - clinad_brainreader_left_lateral_ventricle_z_score float Left-Lateral-Ventricle z-score - clinad_brainreader_left_lateral_ventricle_percentile float Left-Lateral-Ventricle percentile - clinad_brainreader_right_lateral_ventricle_volume_in_ml float Right-Lateral-Ventricle volume in ml - clinad_brainreader_right_lateral_ventricle_vol_mtiv_ratio float Right-Lateral-Ventricle Vol/mTIV ratio - clinad_brainreader_right_lateral_ventricle_nr_index float Right-Lateral-Ventricle NR Index - clinad_brainreader_right_lateral_ventricle_z_score float Right-Lateral-Ventricle z-score - clinad_brainreader_right_lateral_ventricle_percentile float Right-Lateral-Ventricle percentile - clinad_brainreader_putamen_volume_in_ml float Putamen volume in ml - clinad_brainreader_putamen_vol_mtiv_ratio float Putamen Vol/mTIV ratio - clinad_brainreader_putamen_nr_index float Putamen NR Index - clinad_brainreader_putamen_z_score float Putamen z-score - clinad_brainreader_putamen_percentile float Putamen percentile - clinad_brainreader_left_putamen_volume_in_ml float Left-Putamen volume in ml - clinad_brainreader_left_putamen_vol_mtiv_ratio float Left-Putamen Vol/mTIV ratio - clinad_brainreader_left_putamen_nr_index float Left-Putamen NR Index - clinad_brainreader_left_putamen_z_score float Left-Putamen z-score - clinad_brainreader_left_putamen_percentile float Left-Putamen percentile - clinad_brainreader_right_putamen_volume_in_ml float Right-Putamen volume in ml - clinad_brainreader_right_putamen_vol_mtiv_ratio float Right-Putamen Vol/mTIV ratio - clinad_brainreader_right_putamen_nr_index float Right-Putamen NR Index - clinad_brainreader_right_putamen_z_score float Right-Putamen z-score - clinad_brainreader_right_putamen_percentile float Right-Putamen percentile - clinad_brainreader_thalamus_volume_in_ml float Thalamus volume in ml - clinad_brainreader_thalamus_vol_mtiv_ratio float Thalamus Vol/mTIV ratio - clinad_brainreader_thalamus_nr_index float Thalamus NR Index - clinad_brainreader_thalamus_z_score float Thalamus z-score - clinad_brainreader_thalamus_percentile float Thalamus percentile - clinad_brainreader_left_thalamus_volume_in_ml float Left-Thalamus volume in ml - clinad_brainreader_left_thalamus_vol_mtiv_ratio float Left-Thalamus Vol/mTIV ratio - clinad_brainreader_left_thalamus_nr_index float Left-Thalamus NR Index - clinad_brainreader_left_thalamus_z_score float Left-Thalamus z-score - clinad_brainreader_left_thalamus_percentile float Left-Thalamus percentile - clinad_brainreader_right_thalamus_volume_in_ml float Right-Thalamus volume in ml - clinad_brainreader_right_thalamus_vol_mtiv_ratio float Right-Thalamus Vol/mTIV ratio - clinad_brainreader_right_thalamus_nr_index float Right-Thalamus NR Index - clinad_brainreader_right_thalamus_z_score float Right-Thalamus z-score - clinad_brainreader_right_thalamus_percentile float Right-Thalamus percentile - clinad_brainreader_ventral_diencephalon_volume_in_ml float Ventral-Diencephalon volume in ml - clinad_brainreader_ventral_diencephalon_vol_mtiv_ratio float Ventral-Diencephalon Vol/mTIV ratio - clinad_brainreader_ventral_diencephalon_nr_index float Ventral-Diencephalon NR Index - clinad_brainreader_ventral_diencephalon_z_score float Ventral-Diencephalon z-score - clinad_brainreader_ventral_diencephalon_percentile float Ventral-Diencephalon percentile - clinad_brainreader_left_ventral_diencephalon_volume_in_ml float Left-Ventral-Diencephalon volume in ml - clinad_brainreader_left_ventral_diencephalon_vol_mtiv_ratio float Left-Ventral-Diencephalon Vol/mTIV ratio - clinad_brainreader_left_ventral_diencephalon_nr_index float Left-Ventral-Diencephalon NR Index - clinad_brainreader_left_ventral_diencephalon_z_score float Left-Ventral-Diencephalon z-score - clinad_brainreader_left_ventral_diencephalon_percentile float Left-Ventral-Diencephalon percentile - clinad_brainreader_right_ventral_diencephalon_volume_in_ml float Right-Ventral-Diencephalon volume in ml - clinad_brainreader_right_ventral_diencephalon_vol_mtiv_ratio float Right-Ventral-Diencephalon Vol/mTIV ratio - clinad_brainreader_right_ventral_diencephalon_nr_index float Right-Ventral-Diencephalon NR Index - clinad_brainreader_right_ventral_diencephalon_z_score float Right-Ventral-Diencephalon z-score - clinad_brainreader_right_ventral_diencephalon_percentile float Right-Ventral-Diencephalon percentile - clinad_brainreader_left_frontal_lobe_volume_in_ml float Left-Frontal-Lobe volume in ml - clinad_brainreader_left_frontal_lobe_vol_mtiv_ratio float Left-Frontal-Lobe Vol/mTIV ratio - clinad_brainreader_left_frontal_lobe_nr_index float Left-Frontal-Lobe NR Index - clinad_brainreader_left_frontal_lobe_z_score float Left-Frontal-Lobe z-score - clinad_brainreader_left_frontal_lobe_percentile float Left-Frontal-Lobe percentile - clinad_brainreader_right_frontal_lobe_volume_in_ml float Right-Frontal-Lobe volume in ml - clinad_brainreader_right_frontal_lobe_vol_mtiv_ratio float Right-Frontal-Lobe Vol/mTIV ratio - clinad_brainreader_right_frontal_lobe_nr_index float Right-Frontal-Lobe NR Index - clinad_brainreader_right_frontal_lobe_z_score float Right-Frontal-Lobe z-score - clinad_brainreader_right_frontal_lobe_percentile float Right-Frontal-Lobe percentile - clinad_brainreader_left_parietal_lobe_volume_in_ml float Left-Parietal-Lobe volume in ml - clinad_brainreader_left_parietal_lobe_vol_mtiv_ratio float Left-Parietal-Lobe Vol/mTIV ratio - clinad_brainreader_left_parietal_lobe_nr_index float Left-Parietal-Lobe NR Index - clinad_brainreader_left_parietal_lobe_z_score float Left-Parietal-Lobe z-score - clinad_brainreader_left_parietal_lobe_percentile float Left-Parietal-Lobe percentile - clinad_brainreader_right_parietal_lobe_volume_in_ml float Right-Parietal-Lobe volume in ml - clinad_brainreader_right_parietal_lobe_vol_mtiv_ratio float Right-Parietal-Lobe Vol/mTIV ratio - clinad_brainreader_right_parietal_lobe_nr_index float Right-Parietal-Lobe NR Index - clinad_brainreader_right_parietal_lobe_z_score float Right-Parietal-Lobe z-score - clinad_brainreader_right_parietal_lobe_percentile float Right-Parietal-Lobe percentile - clinad_brainreader_left_occipital_lobe_volume_in_ml float Left-Occipital-Lobe volume in ml - clinad_brainreader_left_occipital_lobe_vol_mtiv_ratio float Left-Occipital-Lobe Vol/mTIV ratio - clinad_brainreader_left_occipital_lobe_nr_index float Left-Occipital-Lobe NR Index - clinad_brainreader_left_occipital_lobe_z_score float Left-Occipital-Lobe z-score - clinad_brainreader_left_occipital_lobe_percentile float Left-Occipital-Lobe percentile - clinad_brainreader_right_occipital_lobe_volume_in_ml float Right-Occipital-Lobe volume in ml - clinad_brainreader_right_occipital_lobe_vol_mtiv_ratio float Right-Occipital-Lobe Vol/mTIV ratio - clinad_brainreader_right_occipital_lobe_nr_index float Right-Occipital-Lobe NR Index - clinad_brainreader_right_occipital_lobe_z_score float Right-Occipital-Lobe z-score - clinad_brainreader_right_occipital_lobe_percentile float Right-Occipital-Lobe percentile - clinad_brainreader_left_temporal_lobe_volume_in_ml float Left-Temporal-Lobe volume in ml - clinad_brainreader_left_temporal_lobe_vol_mtiv_ratio float Left-Temporal-Lobe Vol/mTIV ratio - clinad_brainreader_left_temporal_lobe_nr_index float Left-Temporal-Lobe NR Index - clinad_brainreader_left_temporal_lobe_z_score float Left-Temporal-Lobe z-score - clinad_brainreader_left_temporal_lobe_percentile float Left-Temporal-Lobe percentile - clinad_brainreader_right_temporal_lobe_volume_in_ml float Right-Temporal-Lobe volume in ml - clinad_brainreader_right_temporal_lobe_vol_mtiv_ratio float Right-Temporal-Lobe Vol/mTIV ratio - clinad_brainreader_right_temporal_lobe_nr_index float Right-Temporal-Lobe NR Index - clinad_brainreader_right_temporal_lobe_z_score float Right-Temporal-Lobe z-score - clinad_brainreader_right_temporal_lobe_percentile float Right-Temporal-Lobe percentile - clinad_brainreader_frontal_lobe_volume_in_ml float Frontal-Lobe volume in ml - clinad_brainreader_frontal_lobe_vol_mtiv_ratio float Frontal-Lobe Vol/mTIV ratio - clinad_brainreader_frontal_lobe_nr_index float Frontal-Lobe NR Index - clinad_brainreader_frontal_lobe_z_score float Frontal-Lobe z-score - clinad_brainreader_frontal_lobe_percentile float Frontal-Lobe percentile - clinad_brainreader_parietal_lobe_volume_in_ml float Parietal-Lobe volume in ml - clinad_brainreader_parietal_lobe_vol_mtiv_ratio float Parietal-Lobe Vol/mTIV ratio - clinad_brainreader_parietal_lobe_nr_index float Parietal-Lobe NR Index - clinad_brainreader_parietal_lobe_z_score float Parietal-Lobe z-score - clinad_brainreader_parietal_lobe_percentile float Parietal-Lobe percentile - clinad_brainreader_occipital_lobe_volume_in_ml float Occipital-Lobe volume in ml - clinad_brainreader_occipital_lobe_vol_mtiv_ratio float Occipital-Lobe Vol/mTIV ratio - clinad_brainreader_occipital_lobe_nr_index float Occipital-Lobe NR Index - clinad_brainreader_occipital_lobe_z_score float Occipital-Lobe z-score - clinad_brainreader_occipital_lobe_percentile float Occipital-Lobe percentile - clinad_brainreader_temporal_lobe_volume_in_ml float Temporal-Lobe volume in ml - clinad_brainreader_temporal_lobe_vol_mtiv_ratio float Temporal-Lobe Vol/mTIV ratio - clinad_brainreader_temporal_lobe_nr_index float Temporal-Lobe NR Index - clinad_brainreader_temporal_lobe_z_score float Temporal-Lobe z-score - clinad_brainreader_temporal_lobe_percentile float Temporal-Lobe percentile - clinad_brainreader_left_pallidum_volume_in_ml float Left-Pallidum volume in ml - clinad_brainreader_left_pallidum_vol_mtiv_ratio float Left-Pallidum Vol/mTIV ratio - clinad_brainreader_left_pallidum_nr_index float Left-Pallidum NR Index - clinad_brainreader_left_pallidum_z_score float Left-Pallidum z-score - clinad_brainreader_left_pallidum_percentile float Left-Pallidum percentile - clinad_brainreader_right_pallidum_volume_in_ml float Right-Pallidum volume in ml - clinad_brainreader_right_pallidum_vol_mtiv_ratio float Right-Pallidum Vol/mTIV ratio - clinad_brainreader_right_pallidum_nr_index float Right-Pallidum NR Index - clinad_brainreader_right_pallidum_z_score float Right-Pallidum z-score - clinad_brainreader_right_pallidum_percentile float Right-Pallidum percentile - clinad_brainreader_pallidum_volume_in_ml float Pallidum volume in ml - clinad_brainreader_pallidum_vol_mtiv_ratio float Pallidum Vol/mTIV ratio - clinad_brainreader_pallidum_nr_index float Pallidum NR Index - clinad_brainreader_pallidum_z_score float Pallidum z-score - clinad_brainreader_pallidum_percentile float Pallidum percentile - clinad_brainreader_pallidum_volume_in_ml float Pallidum volume in ml - clinad_brainreader_pallidum_vol_mtiv_ratio float Pallidum Vol/mTIV ratio - clinad_brainreader_pallidum_nr_index float Pallidum NR Index - clinad_brainreader_pallidum_z_score float Pallidum z-score - clinad_brainreader_pallidum_percentile float Pallidum percentile +Field BIDS CLINICA BIDS format BIDS type INSIGHT INSIGHT location CLINAD AIBL AIBL location OASIS OASIS location OASIS3 OASIS3 location +BIDS session id session_id Keyword 'ses-' followed by the original session id of each dataset without special characters or symbols string +Date of the examination examination_date YYYY-MM-DD HH:MM:SS string date d'evaluation EXAMDATE aibl_neurobat_*.csv +Date of birth date_of_birth PTDOB aibl_ptdemog_*.csv +Age at the session age float Age oasis3_sessions.csv + current_study free format + adni_fdg free format + adni_pib free format + adni_av45 free format + cdr_global CDGLOBAL aibl_cdr_*.csv CDR oasis_cross-sectional-5708aa0a98d82080.xlsx cdr oasis3_sessions.csv + cdr_sb + adas11 + adas13 +Mini-mental state exam MMS int MMS MMSCORE aibl_mmse_*.csv MMSE oasis_cross-sectional-5708aa0a98d82080.xlsx mmse oasis3_sessions.csv + FAQ + adni_ventricles_vol + adni_hippocampus_vol + adni_brain_vol + adni_entorhinal_vol +Intracranial volume adni_icv +Diagnosis at current session diagnosis DXCURREN aibl_pdxconv_*.csv CDR oasis_cross-sectional-5708aa0a98d82080.xlsx cdr oasis3_sessions.csv + cati_sacha_vol_left_hippocampus cm3 float vol_left_hippocampus Analyses_INSIGHT_M0_20151201/Analyses_HPC_SACHA + cati_sacha_vol_right_hippocampus cm3 float vol_right_hippocampus Analyses_INSIGHT_M0_20151202/Analyses_HPC_SACHA + cati_whasa_volume cm3 float volume (cm3) Analyses_INSIGHT_M0_20151203/Analyses_HPC_WHASA + mattis_attention + mattis_initiation + mattis_construction + mattis_concepts + mattis_memory + MATTIS int + FBI +Verbal Fluency Test categorical_fluency int Categorical Verbal Fluency Tst_NRO_NP +Verbal Fluency Test p_fluency int +Grober and Buschke test grober_buschke_free_cued_recall int +Frontal assessment battery FAB int BREF + freesurfer_rh_mean_thickness rh_MeanThickness_thickness (mm) Analyses_INSIGHT_M0_20151201/Analyses_thichness_Freesurfer + freesurfer_lh_mean_thickness lh_MeanThickness_thickness (mm) Analyses_INSIGHT_M0_20151201/Analyses_thichness_Freesurfer + EQ EQ_SCORE TST_NRO_NL.xls/EQ5D + SPPB Total Score TST_NRO_NL.xls/SPPB + AD8 AD8_SCORE Tst_NRO_NP.xlsx/AD8 + MEM MEM_SCORE Tst_NRO_NP.xlsx/MCQ + AD AD_SCORE Tst_NRO_NP.xlsx/AD8 +Grober and Buschke test grober_buschke_free_recall int RL +Grober and Buschke test grober_buschke_total_recall int RT + grober_buschke_free_recall_delayed int RLD + grober_buschke_total_recall_delayed int RTD + motivation_starkstein (Starkstein) Motivation scale Tst_NRO_NP.xlsx/(Starkstein) + verbal_fluency Lexical Verbal Fluency Score Tst_NRO_NP.xlsx/(Verbal Fluency) +Innotest amyloid/tau index IATI float IATI + clinad_CSF CSF AD profile + clinad_amyloidB int B-Amyloide + clinad_tau int Tau + clinad_p_tau int P-Tau + clinad_p_tau_Aß float PTau/Aß + clinad_delay_MRI_CSF Délai IRM PL + clinad_date_MRI_closest_to_CSF Date IRM proche PL + + prevdemals_benson_copy + prevdemals_benson_rappel + prevdemals_benson_total + prevdemals_faux_pas + praxies_dexterity + praxies_gesture_kinetic + praxies_non_meaning_gestures + praxies_intransitive gestures + praxies_transitive_gestures + praxies_total + prevdemals_emotion_total + prevdemals_als + prevdemals_ftd + + + + + + + clinad_amnestic_syndrome_of_hippocampal_type Sd amn hip +Number of words that was not cointaned in the original dataset of words grober_buschke_intrusions intrusions + + clinad_reac_indic Réac indic + clinad_correct_recognitions reconnaissances correctes + clinad_false_recognitions fausses reconnaissnces + + clinad_date_csf Date PL + clinad_spm_vol_gm Vol_SG + clinad_spm_vol_wm Vol_SB + clinad_spm_vol_csf Vol_CSF + clinad_spm_vol_total Vol_Total + clinad_volbrain_scale_factor Scale factor + clinad_volbrain_snr float SNR + clinad_volbrain_msnr float mSNR + clinad_volbrain_qc float QC + clinad_volbrain_tissue_wm_cm3 float Tissue WM cm3 + clinad_volbrain_tissue_wm_% float Tissue WM % + clinad_volbrain_tissue_gm_cm3 float Tissue GM cm3 + clinad_volbrain_tissue_gm_% float Tissue GM % + clinad_volbrain_tissue_csf_cm3 float Tissue CSF cm3 + clinad_volbrain_tissue_csf_% float Tissue CSF % + clinad_volbrain_tissue_brain_cm3 float Tissue Brain cm3 + clinad_volbrain_tissue_brain_% float Tissue Brain % + clinad_volbrain_tissue_ic_cm3 float Tissue IC cm3 + clinad_volbrain_tissue_ic_% float Tissue IC % + clinad_volbrain_cerebrum_total_cm3 float Cerebrum Total cm3 + clinad_volbrain_cerebrum_total_% float Cerebrum Total % + clinad_volbrain_cerebrum_t_gm_cm3 float Cerebrum T GM cm3 + clinad_volbrain_cerebrum_t_gm_% float Cerebrum T GM % + clinad_volbrain_cerebrum_t_wm_cm3 float Cerebrum T WM cm3 + clinad_volbrain_cerebrum_t_wm_% float Cerebrum T WM % + clinad_volbrain_cerebrum_right_cm3 float Cerebrum Right cm3 + clinad_volbrain_cerebrum_right_% float Cerebrum Right % + clinad_volbrain_cerebrum_r_gm_cm3 float Cerebrum R GM cm3 + clinad_volbrain_cerebrum_r_gm_% float Cerebrum R GM % + clinad_volbrain_cerebrum_r_wm_cm3 float Cerebrum R WM cm3 + clinad_volbrain_cerebrum_r_wm_% float Cerebrum R WM % + clinad_volbrain_cerebrum_left_cm3 float Cerebrum Left cm3 + clinad_volbrain_cerebrum_left_% float Cerebrum Left % + clinad_volbrain_cerebrum_l_gm_cm3 float Cerebrum L GM cm3 + clinad_volbrain_cerebrum_l_gm_% float Cerebrum L GM % + clinad_volbrain_cerebrum_l_wm_cm3 float Cerebrum L WM cm3 + clinad_volbrain_cerebrum_l_wm_% float Cerebrum L WM % + clinad_volbrain_cerebrum_assymetry float Cerebrum Asymmetry + clinad_volbrain_cerebelum_total_cm3 float Cerebelum Total cm3 + clinad_volbrain_cerebelum_total_% float Cerebelum Total % + clinad_volbrain_cerebelum_t_gm_cm3 float Cerebelum T GM cm3 + clinad_volbrain_cerebelum_t_gm_% float Cerebelum T GM % + clinad_volbrain_cerebelum_t_wm_cm3 float Cerebelum T WM cm3 + clinad_volbrain_cerebelum_t_wm_% float Cerebelum T WM % + clinad_volbrain_cerebelum_right_cm3 float Cerebelum Right cm3 + clinad_volbrain_cerebelum_right_% float Cerebelum Right % + clinad_volbrain_cerebelum_r_gm_cm3 float Cerebelum R GM cm3 + clinad_volbrain_cerebelum_r_gm_% float Cerebelum R GM % + clinad_volbrain_cerebelum_r_wm_cm3 float Cerebelum R WM cm3 + clinad_volbrain_cerebelum_r_wm_% float Cerebelum R WM % + clinad_volbrain_cerebelum_left_cm3 float Cerebelum Left cm3 + clinad_volbrain_cerebelum_left_% float Cerebelum Left % + clinad_volbrain_cerebelum_l_gm_cm3 float Cerebelum L GM cm3 + clinad_volbrain_cerebelum_l_gm_% float Cerebelum L GM % + clinad_volbrain_cerebelum_l_wm_cm3 float Cerebelum L WM cm3 + clinad_volbrain_cerebelum_l_wm_% float Cerebelum L WM % + clinad_volbrain_cerebelum_assymetry float Cerebelum Asymmetry + clinad_volbrain_brainstem_cm3 float Brainstem cm3 + clinad_volbrain_brainstem_% float Brainstem % + clinad_volbrain_lateral_ventricles_total_cm3 float Lateral ventricles Total cm3 + clinad_volbrain_lateral_ventricles_total_% float Lateral ventricles Total % + clinad_volbrain_lateral_ventricles_right_cm3 float Lateral ventricles Right cm3 + clinad_volbrain_lateral_ventricles_right_% float Lateral ventricles Right % + clinad_volbrain_lateral_ventricles_left_cm3 float Lateral ventricles Left cm3 + clinad_volbrain_lateral_ventricles_left_% float Lateral ventricles Left % + clinad_volbrain_lateral_ventricles_asymmetry float Lateral ventricles Asymmetry + clinad_volbrain_caudate_total_cm3 float Caudate Total cm3 + clinad_volbrain_caudate_total_% float Caudate Total % + clinad_volbrain_caudate_right_cm3 float Caudate Right cm3 + clinad_volbrain_caudate_right_% float Caudate Right % + clinad_volbrain_caudate_left_cm3 float Caudate Left cm3 + clinad_volbrain_caudate_left_% float Caudate Left % + clinad_volbrain_caudate_asymmetry float Caudate Asymmetry + clinad_volbrain_putamen_total_cm3 float Putamen Total cm3 + clinad_volbrain_putamen_total_% float Putamen Total % + clinad_volbrain_putamen_right_cm3 float Putamen Right cm3 + clinad_volbrain_putamen_right_% float Putamen Right % + clinad_volbrain_putamen_left_cm3 float Putamen Left cm3 + clinad_volbrain_putamen_left_% float Putamen Left % + clinad_volbrain_putamen_asymmetry float Putamen Asymmetry + clinad_volbrain_thalamus_total_cm3 float Thalamus Total cm3 + clinad_volbrain_thalamus_total_% float Thalamus Total % + clinad_volbrain_thalamus_right_cm3 float Thalamus Right cm3 + clinad_volbrain_thalamus_right_% float Thalamus Right % + clinad_volbrain_thalamus_left_cm3 float Thalamus Left cm3 + clinad_volbrain_thalamus_left_% float Thalamus Left % + clinad_volbrain_thalamus_asymmetry float Thalamus Asymmetry + clinad_volbrain_globus_pallidus_total_cm3 float Globus Pallidus Total cm3 + clinad_volbrain_globus_pallidus_total_% float Globus Pallidus Total % + clinad_volbrain_globus_pallidus_right_cm3 float Globus Pallidus Right cm3 + clinad_volbrain_globus_pallidus_right_% float Globus Pallidus Right % + clinad_volbrain_globus_pallidus_left_cm3 float Globus Pallidus Left cm3 + clinad_volbrain_globus_pallidus_left_% float Globus Pallidus Left % + clinad_volbrain_globus_pallidus_asymmetry float Globus Pallidus Asymmetry + clinad_volbrain_hippocampus_total_cm3 float Hippocampus Total cm3 + clinad_volbrain_hippocampus_total_% float Hippocampus Total % + clinad_volbrain_hippocampus_right_cm3 float Hippocampus Right cm3 + clinad_volbrain_hippocampus_right_% float Hippocampus Right % + clinad_volbrain_hippocampus_left_cm3 float Hippocampus Left cm3 + clinad_volbrain_hippocampus_left_% float Hippocampus Left % + clinad_volbrain_hippocampus_asymmetry float Hippocampus Asymmetry + clinad_volbrain_amygdala_total_cm3 float Amygdala Total cm3 + clinad_volbrain_amygdala_total_% float Amygdala Total % + clinad_volbrain_amygdala_right_cm3 float Amygdala Right cm3 + clinad_volbrain_amygdala_right_% float Amygdala Right % + clinad_volbrain_amygdala_left_cm3 float Amygdala Left cm3 + clinad_volbrain_amygdala_left_% float Amygdala Left % + clinad_volbrain_amygdala_asymmetry float Amygdala Asymmetry + clinad_volbrain_accumbens_total_cm3 Accumbens Total cm3 + clinad_volbrain_accumbens_total_% Accumbens Total % + clinad_volbrain_accumbens_right_cm3 Accumbens Right cm3 + clinad_volbrain_accumbens_right_% Accumbens Right % + clinad_volbrain_accumbens_left_cm3 Accumbens Left cm3 + clinad_volbrain_accumbens_left_% Accumbens Left % + clinad_volbrain_accumbens_asymmetry Accumbens Asymmetry + clinad_brainreader_id_rm MR ID + clinad_brainreader_clinical_image_id Clinical image id + clinad_brainreader_filename Filename + clinad_brainreader_nr_version NR version + clinad_brainreader_mtiv_in_ml float The measured total intracranial volume (mTIV) in ml + clinad_brainreader_hippocampal_left_right_asymmetry_index float Hippocampal Left-Right Asymmetry Index + clinad_brainreader_hippocampal_left_right_asymmetry_index_nr_index float Hippocampal Left-Right Asymmetry Index NR Index + clinad_brainreader_hippocampal_left_right_asymmetry_index_z_score float Hippocampal Left-Right Asymmetry Index z-score + clinad_brainreader_hippocampal_left_right_asymmetry_index_percentile float Hippocampal Left-Right Asymmetry Index percentile + clinad_brainreader_whole_brain_matter_volume_in_ml float Whole-Brain-Matter volume in ml + clinad_brainreader_whole_brain_matter_vol_mtiv_ratio float Whole-Brain-Matter Vol/mTIV ratio + clinad_brainreader_whole_brain_matter_nr_index float Whole-Brain-Matter NR Index + clinad_brainreader_whole_brain_matter_z_score float Whole-Brain-Matter z-score + clinad_brainreader_whole_brain_matter_percentile float Whole-Brain-Matter percentile + clinad_brainreader_white_matter_volume_in_ml float White-Matter volume in ml + clinad_brainreader_white_matter_vol_mtiv_ratio float White-Matter Vol/mTIV ratio + clinad_brainreader_white_matter_nr_index float White-Matter NR Index + clinad_brainreader_white_matter_z_score float White-Matter z-score + clinad_brainreader_white_matter_percentile float White-Matter percentile + clinad_brainreader_gray_matter_volume_in_ml float Gray-Matter volume in ml + clinad_brainreader_gray_matter_vol_mtiv_ratio float Gray-Matter Vol/mTIV ratio + clinad_brainreader_gray_matter_nr_index float Gray-Matter NR Index + clinad_brainreader_gray_matter_z_score float Gray-Matter z-score + clinad_brainreader_gray_matter_percentile float Gray-Matter percentile + clinad_brainreader_csf_dura_volume_in_ml float CSF-(+-dura) volume in ml + clinad_brainreader_csf_dura_vol_mtiv_ratio float CSF-(+-dura) Vol/mTIV ratio + clinad_brainreader_csf_dura_nr_index float CSF-(+-dura) NR Index + clinad_brainreader_csf_dura_z_score float CSF-(+-dura) z-score + clinad_brainreader_csf_dura_percentile float CSF-(+-dura) percentile + clinad_brainreader_left_hippocampus_volume_in_ml float Left-Hippocampus volume in ml + clinad_brainreader_left_hippocampus_vol_mtiv_ratio float Left-Hippocampus Vol/mTIV ratio + clinad_brainreader_left_hippocampus_nr_index float Left-Hippocampus NR Index + clinad_brainreader_left_hippocampus_z_score float Left-Hippocampus z-score + clinad_brainreader_left_hippocampus_percentile float Left-Hippocampus percentile + clinad_brainreader_right_hippocampus_volume_in_ml float Right-Hippocampus volume in ml + clinad_brainreader_right_hippocampus_vol_mtiv_ratio float Right-Hippocampus Vol/mTIV ratio + clinad_brainreader_right_hippocampus_nr_index float Right-Hippocampus NR Index + clinad_brainreader_right_hippocampus_z_score float Right-Hippocampus z-score + clinad_brainreader_right_hippocampus_percentile float Right-Hippocampus percentile + clinad_brainreader_hippocampus_volume_in_ml float Hippocampus volume in ml + clinad_brainreader_hippocampus_vol_mtiv_ratio float Hippocampus Vol/mTIV ratio + clinad_brainreader_hippocampus_nr_index float Hippocampus NR Index + clinad_brainreader_hippocampus_z_score float Hippocampus z-score + clinad_brainreader_hippocampus_percentile float Hippocampus percentile + clinad_brainreader_left_amygdala_volume_in_ml float Left-Amygdala volume in ml + clinad_brainreader_left_amygdala_vol_mtiv_ratio float Left-Amygdala Vol/mTIV ratio + clinad_brainreader_left_amygdala_nr_index float Left-Amygdala NR Index + clinad_brainreader_left_amygdala_z_score float Left-Amygdala z-score + clinad_brainreader_left_amygdala_percentile float Left-Amygdala percentile + clinad_brainreader_right_amygdala_volume_in_ml float Right-Amygdala volume in ml + clinad_brainreader_right_amygdala_vol_mtiv_ratio float Right-Amygdala Vol/mTIV ratio + clinad_brainreader_right_amygdala_nr_index float Right-Amygdala NR Index + clinad_brainreader_right_amygdala_z_score float Right-Amygdala z-score + clinad_brainreader_right_amygdala_percentile float Right-Amygdala percentile + clinad_brainreader_amygdala_volume_in_ml float Amygdala volume in ml + clinad_brainreader_amygdala_vol_mtiv_ratio float Amygdala Vol/mTIV ratio + clinad_brainreader_amygdala_nr_index float Amygdala NR Index + clinad_brainreader_amygdala_z_score float Amygdala z-score + clinad_brainreader_amygdala_percentile float Amygdala percentile + clinad_brainreader_brain_stem_volume_in_ml float Brain-Stem volume in ml + clinad_brainreader_brain_stem_vol_mtiv_ratio float Brain-Stem Vol/mTIV ratio + clinad_brainreader_brain_stem_nr_index float Brain-Stem NR Index + clinad_brainreader_brain_stem_z_score float Brain-Stem z-score + clinad_brainreader_brain_stem_percentile float Brain-Stem percentile + clinad_brainreader_caudate_volume_in_ml float Caudate volume in ml + clinad_brainreader_caudate_vol_mtiv_ratio float Caudate Vol/mTIV ratio + clinad_brainreader_caudate_nr_index float Caudate NR Index + clinad_brainreader_caudate_z_score float Caudate z-score + clinad_brainreader_caudate_percentile float Caudate percentile + clinad_brainreader_left_caudate_volume_in_ml float Left-Caudate volume in ml + clinad_brainreader_left_caudate_vol_mtiv_ratio float Left-Caudate Vol/mTIV ratio + clinad_brainreader_left_caudate_nr_index float Left-Caudate NR Index + clinad_brainreader_left_caudate_z_score float Left-Caudate z-score + clinad_brainreader_left_caudate_percentile float Left-Caudate percentile + clinad_brainreader_right_caudate_volume_in_ml float Right-Caudate volume in ml + clinad_brainreader_right_caudate_vol_mtiv_ratio float Right-Caudate Vol/mTIV ratio + clinad_brainreader_right_caudate_nr_index float Right-Caudate NR Index + clinad_brainreader_right_caudate_z_score float Right-Caudate z-score + clinad_brainreader_right_caudate_percentile float Right-Caudate percentile + clinad_brainreader_left_cerebellum_volume_in_ml float Left-Cerebellum volume in ml + clinad_brainreader_left_cerebellum_vol_mtiv_ratio float Left-Cerebellum Vol/mTIV ratio + clinad_brainreader_left_cerebellum_nr_index float Left-Cerebellum NR Index + clinad_brainreader_left_cerebellum_z_score float Left-Cerebellum z-score + clinad_brainreader_left_cerebellum_percentile float Left-Cerebellum percentile + clinad_brainreader_right_cerebellum_volume_in_ml float Right-Cerebellum volume in ml + clinad_brainreader_right_cerebellum_vol_mtiv_ratio float Right-Cerebellum Vol/mTIV ratio + clinad_brainreader_right_cerebellum_nr_index float Right-Cerebellum NR Index + clinad_brainreader_right_cerebellum_z_score float Right-Cerebellum z-score + clinad_brainreader_right_cerebellum_percentile float Right-Cerebellum percentile + clinad_brainreader_cerebellum_volume_in_ml float Cerebellum volume in ml + clinad_brainreader_cerebellum_vol_mtiv_ratio float Cerebellum Vol/mTIV ratio + clinad_brainreader_cerebellum_nr_index float Cerebellum NR Index + clinad_brainreader_cerebellum_z_score float Cerebellum z-score + clinad_brainreader_cerebellum_percentile float Cerebellum percentile + clinad_brainreader_lateral_ventricle_volume_in_ml float Lateral-Ventricle volume in ml + clinad_brainreader_lateral_ventricle_vol_mtiv_ratio float Lateral-Ventricle Vol/mTIV ratio + clinad_brainreader_lateral_ventricle_nr_index float Lateral-Ventricle NR Index + clinad_brainreader_lateral_ventricle_z_score float Lateral-Ventricle z-score + clinad_brainreader_lateral_ventricle_percentile float Lateral-Ventricle percentile + clinad_brainreader_left_lateral_ventricle_volume_in_ml float Left-Lateral-Ventricle volume in ml + clinad_brainreader_left_lateral_ventricle_vol_mtiv_ratio float Left-Lateral-Ventricle Vol/mTIV ratio + clinad_brainreader_left_lateral_ventricle_nr_index float Left-Lateral-Ventricle NR Index + clinad_brainreader_left_lateral_ventricle_z_score float Left-Lateral-Ventricle z-score + clinad_brainreader_left_lateral_ventricle_percentile float Left-Lateral-Ventricle percentile + clinad_brainreader_right_lateral_ventricle_volume_in_ml float Right-Lateral-Ventricle volume in ml + clinad_brainreader_right_lateral_ventricle_vol_mtiv_ratio float Right-Lateral-Ventricle Vol/mTIV ratio + clinad_brainreader_right_lateral_ventricle_nr_index float Right-Lateral-Ventricle NR Index + clinad_brainreader_right_lateral_ventricle_z_score float Right-Lateral-Ventricle z-score + clinad_brainreader_right_lateral_ventricle_percentile float Right-Lateral-Ventricle percentile + clinad_brainreader_putamen_volume_in_ml float Putamen volume in ml + clinad_brainreader_putamen_vol_mtiv_ratio float Putamen Vol/mTIV ratio + clinad_brainreader_putamen_nr_index float Putamen NR Index + clinad_brainreader_putamen_z_score float Putamen z-score + clinad_brainreader_putamen_percentile float Putamen percentile + clinad_brainreader_left_putamen_volume_in_ml float Left-Putamen volume in ml + clinad_brainreader_left_putamen_vol_mtiv_ratio float Left-Putamen Vol/mTIV ratio + clinad_brainreader_left_putamen_nr_index float Left-Putamen NR Index + clinad_brainreader_left_putamen_z_score float Left-Putamen z-score + clinad_brainreader_left_putamen_percentile float Left-Putamen percentile + clinad_brainreader_right_putamen_volume_in_ml float Right-Putamen volume in ml + clinad_brainreader_right_putamen_vol_mtiv_ratio float Right-Putamen Vol/mTIV ratio + clinad_brainreader_right_putamen_nr_index float Right-Putamen NR Index + clinad_brainreader_right_putamen_z_score float Right-Putamen z-score + clinad_brainreader_right_putamen_percentile float Right-Putamen percentile + clinad_brainreader_thalamus_volume_in_ml float Thalamus volume in ml + clinad_brainreader_thalamus_vol_mtiv_ratio float Thalamus Vol/mTIV ratio + clinad_brainreader_thalamus_nr_index float Thalamus NR Index + clinad_brainreader_thalamus_z_score float Thalamus z-score + clinad_brainreader_thalamus_percentile float Thalamus percentile + clinad_brainreader_left_thalamus_volume_in_ml float Left-Thalamus volume in ml + clinad_brainreader_left_thalamus_vol_mtiv_ratio float Left-Thalamus Vol/mTIV ratio + clinad_brainreader_left_thalamus_nr_index float Left-Thalamus NR Index + clinad_brainreader_left_thalamus_z_score float Left-Thalamus z-score + clinad_brainreader_left_thalamus_percentile float Left-Thalamus percentile + clinad_brainreader_right_thalamus_volume_in_ml float Right-Thalamus volume in ml + clinad_brainreader_right_thalamus_vol_mtiv_ratio float Right-Thalamus Vol/mTIV ratio + clinad_brainreader_right_thalamus_nr_index float Right-Thalamus NR Index + clinad_brainreader_right_thalamus_z_score float Right-Thalamus z-score + clinad_brainreader_right_thalamus_percentile float Right-Thalamus percentile + clinad_brainreader_ventral_diencephalon_volume_in_ml float Ventral-Diencephalon volume in ml + clinad_brainreader_ventral_diencephalon_vol_mtiv_ratio float Ventral-Diencephalon Vol/mTIV ratio + clinad_brainreader_ventral_diencephalon_nr_index float Ventral-Diencephalon NR Index + clinad_brainreader_ventral_diencephalon_z_score float Ventral-Diencephalon z-score + clinad_brainreader_ventral_diencephalon_percentile float Ventral-Diencephalon percentile + clinad_brainreader_left_ventral_diencephalon_volume_in_ml float Left-Ventral-Diencephalon volume in ml + clinad_brainreader_left_ventral_diencephalon_vol_mtiv_ratio float Left-Ventral-Diencephalon Vol/mTIV ratio + clinad_brainreader_left_ventral_diencephalon_nr_index float Left-Ventral-Diencephalon NR Index + clinad_brainreader_left_ventral_diencephalon_z_score float Left-Ventral-Diencephalon z-score + clinad_brainreader_left_ventral_diencephalon_percentile float Left-Ventral-Diencephalon percentile + clinad_brainreader_right_ventral_diencephalon_volume_in_ml float Right-Ventral-Diencephalon volume in ml + clinad_brainreader_right_ventral_diencephalon_vol_mtiv_ratio float Right-Ventral-Diencephalon Vol/mTIV ratio + clinad_brainreader_right_ventral_diencephalon_nr_index float Right-Ventral-Diencephalon NR Index + clinad_brainreader_right_ventral_diencephalon_z_score float Right-Ventral-Diencephalon z-score + clinad_brainreader_right_ventral_diencephalon_percentile float Right-Ventral-Diencephalon percentile + clinad_brainreader_left_frontal_lobe_volume_in_ml float Left-Frontal-Lobe volume in ml + clinad_brainreader_left_frontal_lobe_vol_mtiv_ratio float Left-Frontal-Lobe Vol/mTIV ratio + clinad_brainreader_left_frontal_lobe_nr_index float Left-Frontal-Lobe NR Index + clinad_brainreader_left_frontal_lobe_z_score float Left-Frontal-Lobe z-score + clinad_brainreader_left_frontal_lobe_percentile float Left-Frontal-Lobe percentile + clinad_brainreader_right_frontal_lobe_volume_in_ml float Right-Frontal-Lobe volume in ml + clinad_brainreader_right_frontal_lobe_vol_mtiv_ratio float Right-Frontal-Lobe Vol/mTIV ratio + clinad_brainreader_right_frontal_lobe_nr_index float Right-Frontal-Lobe NR Index + clinad_brainreader_right_frontal_lobe_z_score float Right-Frontal-Lobe z-score + clinad_brainreader_right_frontal_lobe_percentile float Right-Frontal-Lobe percentile + clinad_brainreader_left_parietal_lobe_volume_in_ml float Left-Parietal-Lobe volume in ml + clinad_brainreader_left_parietal_lobe_vol_mtiv_ratio float Left-Parietal-Lobe Vol/mTIV ratio + clinad_brainreader_left_parietal_lobe_nr_index float Left-Parietal-Lobe NR Index + clinad_brainreader_left_parietal_lobe_z_score float Left-Parietal-Lobe z-score + clinad_brainreader_left_parietal_lobe_percentile float Left-Parietal-Lobe percentile + clinad_brainreader_right_parietal_lobe_volume_in_ml float Right-Parietal-Lobe volume in ml + clinad_brainreader_right_parietal_lobe_vol_mtiv_ratio float Right-Parietal-Lobe Vol/mTIV ratio + clinad_brainreader_right_parietal_lobe_nr_index float Right-Parietal-Lobe NR Index + clinad_brainreader_right_parietal_lobe_z_score float Right-Parietal-Lobe z-score + clinad_brainreader_right_parietal_lobe_percentile float Right-Parietal-Lobe percentile + clinad_brainreader_left_occipital_lobe_volume_in_ml float Left-Occipital-Lobe volume in ml + clinad_brainreader_left_occipital_lobe_vol_mtiv_ratio float Left-Occipital-Lobe Vol/mTIV ratio + clinad_brainreader_left_occipital_lobe_nr_index float Left-Occipital-Lobe NR Index + clinad_brainreader_left_occipital_lobe_z_score float Left-Occipital-Lobe z-score + clinad_brainreader_left_occipital_lobe_percentile float Left-Occipital-Lobe percentile + clinad_brainreader_right_occipital_lobe_volume_in_ml float Right-Occipital-Lobe volume in ml + clinad_brainreader_right_occipital_lobe_vol_mtiv_ratio float Right-Occipital-Lobe Vol/mTIV ratio + clinad_brainreader_right_occipital_lobe_nr_index float Right-Occipital-Lobe NR Index + clinad_brainreader_right_occipital_lobe_z_score float Right-Occipital-Lobe z-score + clinad_brainreader_right_occipital_lobe_percentile float Right-Occipital-Lobe percentile + clinad_brainreader_left_temporal_lobe_volume_in_ml float Left-Temporal-Lobe volume in ml + clinad_brainreader_left_temporal_lobe_vol_mtiv_ratio float Left-Temporal-Lobe Vol/mTIV ratio + clinad_brainreader_left_temporal_lobe_nr_index float Left-Temporal-Lobe NR Index + clinad_brainreader_left_temporal_lobe_z_score float Left-Temporal-Lobe z-score + clinad_brainreader_left_temporal_lobe_percentile float Left-Temporal-Lobe percentile + clinad_brainreader_right_temporal_lobe_volume_in_ml float Right-Temporal-Lobe volume in ml + clinad_brainreader_right_temporal_lobe_vol_mtiv_ratio float Right-Temporal-Lobe Vol/mTIV ratio + clinad_brainreader_right_temporal_lobe_nr_index float Right-Temporal-Lobe NR Index + clinad_brainreader_right_temporal_lobe_z_score float Right-Temporal-Lobe z-score + clinad_brainreader_right_temporal_lobe_percentile float Right-Temporal-Lobe percentile + clinad_brainreader_frontal_lobe_volume_in_ml float Frontal-Lobe volume in ml + clinad_brainreader_frontal_lobe_vol_mtiv_ratio float Frontal-Lobe Vol/mTIV ratio + clinad_brainreader_frontal_lobe_nr_index float Frontal-Lobe NR Index + clinad_brainreader_frontal_lobe_z_score float Frontal-Lobe z-score + clinad_brainreader_frontal_lobe_percentile float Frontal-Lobe percentile + clinad_brainreader_parietal_lobe_volume_in_ml float Parietal-Lobe volume in ml + clinad_brainreader_parietal_lobe_vol_mtiv_ratio float Parietal-Lobe Vol/mTIV ratio + clinad_brainreader_parietal_lobe_nr_index float Parietal-Lobe NR Index + clinad_brainreader_parietal_lobe_z_score float Parietal-Lobe z-score + clinad_brainreader_parietal_lobe_percentile float Parietal-Lobe percentile + clinad_brainreader_occipital_lobe_volume_in_ml float Occipital-Lobe volume in ml + clinad_brainreader_occipital_lobe_vol_mtiv_ratio float Occipital-Lobe Vol/mTIV ratio + clinad_brainreader_occipital_lobe_nr_index float Occipital-Lobe NR Index + clinad_brainreader_occipital_lobe_z_score float Occipital-Lobe z-score + clinad_brainreader_occipital_lobe_percentile float Occipital-Lobe percentile + clinad_brainreader_temporal_lobe_volume_in_ml float Temporal-Lobe volume in ml + clinad_brainreader_temporal_lobe_vol_mtiv_ratio float Temporal-Lobe Vol/mTIV ratio + clinad_brainreader_temporal_lobe_nr_index float Temporal-Lobe NR Index + clinad_brainreader_temporal_lobe_z_score float Temporal-Lobe z-score + clinad_brainreader_temporal_lobe_percentile float Temporal-Lobe percentile + clinad_brainreader_left_pallidum_volume_in_ml float Left-Pallidum volume in ml + clinad_brainreader_left_pallidum_vol_mtiv_ratio float Left-Pallidum Vol/mTIV ratio + clinad_brainreader_left_pallidum_nr_index float Left-Pallidum NR Index + clinad_brainreader_left_pallidum_z_score float Left-Pallidum z-score + clinad_brainreader_left_pallidum_percentile float Left-Pallidum percentile + clinad_brainreader_right_pallidum_volume_in_ml float Right-Pallidum volume in ml + clinad_brainreader_right_pallidum_vol_mtiv_ratio float Right-Pallidum Vol/mTIV ratio + clinad_brainreader_right_pallidum_nr_index float Right-Pallidum NR Index + clinad_brainreader_right_pallidum_z_score float Right-Pallidum z-score + clinad_brainreader_right_pallidum_percentile float Right-Pallidum percentile + clinad_brainreader_pallidum_volume_in_ml float Pallidum volume in ml + clinad_brainreader_pallidum_vol_mtiv_ratio float Pallidum Vol/mTIV ratio + clinad_brainreader_pallidum_nr_index float Pallidum NR Index + clinad_brainreader_pallidum_z_score float Pallidum z-score + clinad_brainreader_pallidum_percentile float Pallidum percentile + clinad_brainreader_pallidum_volume_in_ml float Pallidum volume in ml + clinad_brainreader_pallidum_vol_mtiv_ratio float Pallidum Vol/mTIV ratio + clinad_brainreader_pallidum_nr_index float Pallidum NR Index + clinad_brainreader_pallidum_z_score float Pallidum z-score + clinad_brainreader_pallidum_percentile float Pallidum percentile \ No newline at end of file diff --git a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py index b445a5ac1..3532d372a 100644 --- a/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py +++ b/test/unittests/iotools/converters/aibl_to_bids/test_aibl_utils.py @@ -30,10 +30,10 @@ def test_compute_age_at_exam(birth_date, exam_date, expected): ) def test_mapping_diagnosis(diagnosis, expected): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( - _mapping_diagnosis, + _map_diagnosis, ) - assert _mapping_diagnosis(diagnosis) == expected + assert _map_diagnosis(diagnosis) == expected def test_load_specifications_success(tmp_path): @@ -106,7 +106,7 @@ def build_sessions_spec(tmp_path: Path) -> Path: { "BIDS CLINICA": [ "examination_date", - "age", + "date_of_birth", "cdr_global", "MMS", "diagnosis", @@ -232,7 +232,7 @@ def build_clinical_data(tmp_path: Path) -> Path: def test_extract_metadata_df(tmp_path): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( - _extract_metadata_df, + _format_metadata_for_rid, ) clinical_dir = build_clinical_data(tmp_path) @@ -242,7 +242,7 @@ def test_extract_metadata_df(tmp_path): "examination_date": ["01/01/2109", "-4"], } ).set_index("session_id", drop=True) - result = _extract_metadata_df( + result = _format_metadata_for_rid( pd.read_csv(clinical_dir / "aibl_neurobat_230ct2024.csv", dtype={"text": str}), 109, bids_metadata="examination_date", @@ -273,13 +273,18 @@ def test_find_exam_date_in_other_csv_files(tmp_path, source_id, session_id, expe ) -def test_get_csv_paths(tmp_path): - from clinica.iotools.converters.aibl_to_bids.utils.clinical import _get_csv_paths +def test_get_csv_files_for_alternative_exam_date(tmp_path): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _get_csv_files_for_alternative_exam_date, + ) - assert _get_csv_paths(tmp_path) == () + assert _get_csv_files_for_alternative_exam_date(tmp_path) == () clinical_dir = build_clinical_data(tmp_path) - csv_paths = [Path(path).name for path in _get_csv_paths(clinical_dir)] + csv_paths = [ + Path(path).name + for path in _get_csv_files_for_alternative_exam_date(clinical_dir) + ] assert set(csv_paths) == { "aibl_cdr_230ct2024.csv", @@ -305,11 +310,78 @@ def test_complete_examination_dates(tmp_path, rid, session_id, exam_date, expect clinical_dir = build_clinical_data(tmp_path) assert ( - _complete_examination_dates(rid, session_id, exam_date, clinical_dir) + _complete_examination_dates(rid, clinical_dir, session_id, exam_date) == expected ) +@pytest.mark.parametrize( + "input_df, expected_df", + [ + ( + pd.DataFrame( + { + "date_of_birth": ["/2000", None], + "examination_date": ["01/01/2024", "01/01/2026"], + } + ), + pd.DataFrame( + {"age": [24, 26], "examination_date": ["01/01/2024", "01/01/2026"]} + ), + ), + ( + pd.DataFrame( + { + "date_of_birth": [None, None], + "examination_date": ["01/01/2024", "01/01/2026"], + } + ), + pd.DataFrame( + {"age": [None, None], "examination_date": ["01/01/2024", "01/01/2026"]} + ), + ), + ( + pd.DataFrame( + { + "date_of_birth": ["/2000", "/2001"], + "examination_date": ["01/01/2024", "01/01/2026"], + } + ), + pd.DataFrame( + {"age": [None, None], "examination_date": ["01/01/2024", "01/01/2026"]} + ), + ), + ], +) +def test_set_age_from_birth_success(input_df, expected_df): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _set_age_from_birth, + ) + + assert_frame_equal(_set_age_from_birth(input_df), expected_df, check_like=True) + + +@pytest.mark.parametrize( + "input_df", + [ + pd.DataFrame(), + pd.DataFrame({"date_of_birth": ["foo"]}), + pd.DataFrame({"examination_date": ["bar"]}), + ], +) +def test_set_age_from_birth_raise(input_df): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + _set_age_from_birth, + ) + + with pytest.raises( + ValueError, + match="Columns date_of_birth or/and examination_date were not found in the sessions metadata dataframe." + "Please check your study metadata.", + ): + _set_age_from_birth(input_df) + + def test_create_sessions_tsv(tmp_path): from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( create_sessions_tsv_file, @@ -370,3 +442,14 @@ def test_create_sessions_tsv(tmp_path): assert_frame_equal(result_sub1, expected_sub1, check_like=True) assert_frame_equal(result_sub100, expected_sub100, check_like=True) assert_frame_equal(result_sub109, expected_sub109, check_like=True) + + +def test_create_sessions_tsv_clinical_not_found(tmp_path): + from clinica.iotools.converters.aibl_to_bids.utils.clinical import ( + create_sessions_tsv_file, + ) + + with pytest.raises(FileNotFoundError, match="Clinical data"): + create_sessions_tsv_file( + build_bids_dir(tmp_path), tmp_path, build_sessions_spec(tmp_path) + ) From cfb90f8cc8c576dd8c4773e7ab5b7a1a1e595eae Mon Sep 17 00:00:00 2001 From: AliceJoubert Date: Wed, 6 Nov 2024 14:51:00 +0100 Subject: [PATCH 7/7] Small fix --- clinica/iotools/converters/aibl_to_bids/utils/clinical.py | 1 - 1 file changed, 1 deletion(-) diff --git a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py index d3fa30891..5e3c6ad90 100644 --- a/clinica/iotools/converters/aibl_to_bids/utils/clinical.py +++ b/clinica/iotools/converters/aibl_to_bids/utils/clinical.py @@ -319,7 +319,6 @@ def _find_exam_date_in_other_csv_files( def _get_csv_files_for_alternative_exam_date(clinical_data_dir: Path) -> Tuple[Path]: """Return a list of paths to CSV files in which an alternative exam date could be found.""" - import glob patterns = ( "aibl_mri3meta_*.csv",