From fd9bbf38117ab0687a1c71d7b44ec1b8d328f606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Cl=C3=A9net?= Date: Wed, 15 Nov 2023 16:37:08 +0100 Subject: [PATCH] [TEST] adding unit tests for 08MQ --- narps_open/pipelines/team_08MQ.py | 122 +++++++++++------------------- tests/pipelines/__init__.py | 31 ++++++++ tests/pipelines/test_team_08MQ.py | 42 ++++++++-- 3 files changed, 111 insertions(+), 84 deletions(-) diff --git a/narps_open/pipelines/team_08MQ.py b/narps_open/pipelines/team_08MQ.py index aa51f417..b672367c 100644 --- a/narps_open/pipelines/team_08MQ.py +++ b/narps_open/pipelines/team_08MQ.py @@ -390,29 +390,23 @@ def get_subject_information(event_file): for line in file: info = line.strip().split() - - for condition in condition_names: - if condition == 'gain': - onsets[condition].append(float(info[0])) - durations[condition].append(float(info[4])) # TODO : change to info[1] (= 4) ? - amplitudes[condition].append(float(info[2])) - elif condition == 'loss': - onsets[condition].append(float(info[0])) - durations[condition].append(float(info[4])) # TODO : change to info[1] (= 4) ? - amplitudes[condition].append(float(info[3])) - elif condition == 'event': - onsets[condition].append(float(info[0])) - durations[condition].append(float(info[1])) - amplitudes[condition].append(1.0) - elif condition == 'response': - onsets[condition].append(float(info[0])) - durations[condition].append(float(info[1])) # TODO : change to info[4] (= RT) ? - if 'accept' in info[5]: - amplitudes[condition].append(1.0) - elif 'reject' in info[5]: - amplitudes[condition].append(-1.0) - else: - amplitudes[condition].append(0.0) + onsets['event'].append(float(info[0])) + durations['event'].append(float(info[1])) + amplitudes['event'].append(1.0) + onsets['gain'].append(float(info[0])) + durations['gain'].append(float(info[4])) # TODO : change to info[1] (= 4) ? + amplitudes['gain'].append(float(info[2])) + onsets['loss'].append(float(info[0])) + durations['loss'].append(float(info[4])) # TODO : change to info[1] (= 4) ? + amplitudes['loss'].append(float(info[3])) + onsets['response'].append(float(info[0])) + durations['response'].append(float(info[1])) # TODO : change to info[4] (= RT) ? + if 'accept' in info[5]: + amplitudes['response'].append(1.0) + elif 'reject' in info[5]: + amplitudes['response'].append(-1.0) + else: + amplitudes['response'].append(0.0) return [ Bunch( @@ -433,17 +427,12 @@ def get_run_level_contrasts(): Returns: - contrasts: list of tuples, list of contrasts to analyze """ - # List of condition names conditions = ['gain', 'loss'] - # Return contrast list return [ - # Positive parametric effect of gain - ('positive_effect_gain', 'T', conditions, [1, 0]), - # Positive parametric effect of loss - ('positive_effect_loss', 'T', conditions, [0, 1]), - # Negative parametric effect of loss. - ('negative_effect_loss', 'T', conditions, [0, -1]) + ('positive_effect_gain', 'T', conditions, [1, 0]), # Positive parametric effect of gain + ('positive_effect_loss', 'T', conditions, [0, 1]), # Positive parametric effect of loss + ('negative_effect_loss', 'T', conditions, [0, -1]) # Negative parametric effect of loss ] def get_run_level_analysis(self): @@ -689,18 +678,19 @@ def get_subgroups_contrasts(copes, varcopes, subject_list: list, participants_fi in the equalIndifference group - copes_equal_range : a subset of copes corresponding to subjects in the equalRange group - - copes_global : a list of all copes - varcopes_equal_indifference : a subset of varcopes corresponding to subjects in the equalIndifference group - varcopes_equal_range : a subset of varcopes corresponding to subjects in the equalRange group - equal_indifference_ids : a list of subject ids in the equalIndifference group - equal_range_ids : a list of subject ids in the equalRange group - - varcopes_global : a list of all varcopes """ - equal_range_ids = [] - equal_indifference_ids = [] + subject_list_sub_ids = [] # ids as written in the participants file + equal_range_ids = [] # ids as 3-digit string + equal_indifference_ids = [] # ids as 3-digit string + equal_range_sub_ids = [] # ids as written in the participants file + equal_indifference_sub_ids = [] # ids as written in the participants file # Reading file containing participants IDs and groups with open(participants_file, 'rt') as file: @@ -708,44 +698,26 @@ def get_subgroups_contrasts(copes, varcopes, subject_list: list, participants_fi for line in file: info = line.strip().split() - - # Checking for each participant if its ID was selected - # and separate people depending on their group - if info[0][-3:] in subject_list and info[1] == 'equalIndifference': - equal_indifference_ids.append(info[0][-3:]) - elif info[0][-3:] in subject_list and info[1] == 'equalRange': - equal_range_ids.append(info[0][-3:]) - - copes_equal_indifference = [] - copes_equal_range = [] - copes_global = [] - varcopes_equal_indifference = [] - varcopes_equal_range = [] - varcopes_global = [] - - # Checking for each selected file if the corresponding participant was selected - # and add the file to the list corresponding to its group - for cope, varcope in zip(copes, varcopes): - sub_id = cope.split('/') - if sub_id[-2][-3:] in equal_indifference_ids: - copes_equal_indifference.append(cope) - elif sub_id[-2][-3:] in equal_range_ids: - copes_equal_range.append(cope) - if sub_id[-2][-3:] in subject_list: - copes_global.append(cope) - - sub_id = varcope.split('/') - if sub_id[-2][-3:] in equal_indifference_ids: - varcopes_equal_indifference.append(varcope) - elif sub_id[-2][-3:] in equal_range_ids: - varcopes_equal_range.append(varcope) - if sub_id[-2][-3:] in subject_list: - varcopes_global.append(varcope) - - return copes_equal_indifference, copes_equal_range,\ - varcopes_equal_indifference, varcopes_equal_range,\ - equal_indifference_ids, equal_range_ids,\ - copes_global, varcopes_global + subject_id = info[0][-3:] + subject_group = info[1] + + # Check if the participant ID was selected and sort depending on group + if subject_id in subject_list: + subject_list_sub_ids.append(info[0]) + if subject_group == 'equalIndifference': + equal_indifference_ids.append(subject_id) + equal_indifference_sub_ids.append(info[0]) + elif subject_group == 'equalRange': + equal_range_ids.append(subject_id) + equal_range_sub_ids.append(info[0]) + + # Reurn sorted selected copes and varcopes by group, and corresponding ids + return \ + [c for c in copes if any(i in c for i in equal_indifference_sub_ids)],\ + [c for c in copes if any(i in c for i in equal_range_sub_ids)],\ + [v for v in varcopes if any(i in v for i in equal_indifference_sub_ids)],\ + [v for v in varcopes if any(i in v for i in equal_range_sub_ids)],\ + equal_indifference_ids, equal_range_ids def get_one_sample_t_test_regressors(subject_ids: list) -> dict: """ @@ -850,9 +822,7 @@ def get_group_level_analysis_sub_workflow(self, method): 'varcopes_equal_indifference', 'varcopes_equal_range', 'equal_indifference_ids', - 'equal_range_ids', - 'copes_global', - 'varcopes_global' + 'equal_range_ids' ] ), name = 'get_contrasts', diff --git a/tests/pipelines/__init__.py b/tests/pipelines/__init__.py index e69de29b..d6ad4fdc 100644 --- a/tests/pipelines/__init__.py +++ b/tests/pipelines/__init__.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +# coding: utf-8 + +""" +Configuration for testing of the narps_open.pipelines modules. +""" + +from pytest import helpers + +@helpers.register +def mock_event_data(mocker): + """ Mocks the retrun of the open function with the contents of a fake event file """ + + fake_event_data = 'onset duration\tgain\tloss\tRT\tparticipant_response\n' + fake_event_data += '4.071\t4\t14\t6\t2.388\tweakly_accept\n' + fake_event_data += '11.834\t4\t34\t14\t2.289\tstrongly_accept\n' + + mocker.patch('builtins.open', mocker.mock_open(read_data = fake_event_data)) + + +@helpers.register +def mock_participants_data(mocker): + """ Mocks the retrun of the open function with the contents of a fake participants file """ + + fake_participants_data = 'participant_id\tgroup\tgender\tage\n' + fake_participants_data += 'sub-001\tequalIndifference\tM\t24\n' + fake_participants_data += 'sub-002\tequalRange\tM\t25\n' + fake_participants_data += 'sub-003\tequalIndifference\tF\t27\n' + fake_participants_data += 'sub-004\tequalRange\tM\t25\n' + + mocker.patch('builtins.open', mocker.mock_open(read_data = fake_participants_data)) diff --git a/tests/pipelines/test_team_08MQ.py b/tests/pipelines/test_team_08MQ.py index d5feff70..298107b1 100644 --- a/tests/pipelines/test_team_08MQ.py +++ b/tests/pipelines/test_team_08MQ.py @@ -13,6 +13,7 @@ from pytest import helpers, mark from nipype import Workflow +from nipype.interfaces.base import Bunch from narps_open.pipelines.team_08MQ import PipelineTeam08MQ @@ -63,26 +64,51 @@ def test_outputs(): @staticmethod @mark.unit_test - def test_subject_information(): + def test_subject_information(mocker): """ Test the get_subject_information method """ + helpers.mock_event_data(mocker) + + information = PipelineTeam08MQ.get_subject_information('fake_event_file_path')[0] + + assert isinstance(information, Bunch) + assert information.amplitudes == [[1.0, 1.0], [14.0, 34.0], [6.0, 14.0], [1.0, 1.0]] + assert information.durations == [[4.0, 4.0], [2.388, 2.289], [2.388, 2.289], [4.0, 4.0]] + assert information.conditions == ['event', 'gain', 'loss', 'response'] + assert information.onsets == [ + [4.071, 11.834], [4.071, 11.834], [4.071, 11.834], [4.071, 11.834] + ] + @staticmethod @mark.unit_test def test_run_level_contrasts(): """ Test the get_run_level_contrasts method """ - contrasts = PipelineTeam08MQ.get_run_level_contrasts() + contrasts = PipelineTeam08MQ.get_run_level_contrasts() assert contrasts[0] == ('positive_effect_gain', 'T', ['gain', 'loss'], [1, 0]) - assert contrasts[0] == ('positive_effect_loss', 'T', ['gain', 'loss'], [0, 1]) - assert contrasts[0] == ('negative_effect_loss', 'T', ['gain', 'loss'], [0, -1]) + assert contrasts[1] == ('positive_effect_loss', 'T', ['gain', 'loss'], [0, 1]) + assert contrasts[2] == ('negative_effect_loss', 'T', ['gain', 'loss'], [0, -1]) @staticmethod @mark.unit_test - def test_subgroups_contrasts(): + def test_subgroups_contrasts(mocker): """ Test the get_subgroups_contrasts method """ - #contrasts = PipelineTeam08MQ().get_subgroups_contrasts() - #copes, varcopes, subject_list: list, participants_file: str + helpers.mock_participants_data(mocker) + + cei, cer, vei, ver, eii, eri = PipelineTeam08MQ.get_subgroups_contrasts( + ['sub-001/_contrast_id_1/cope1.nii.gz', 'sub-001/_contrast_id_2/cope1.nii.gz', 'sub-002/_contrast_id_1/cope1.nii.gz', 'sub-002/_contrast_id_2/cope1.nii.gz', 'sub-003/_contrast_id_1/cope1.nii.gz', 'sub-003/_contrast_id_2/cope1.nii.gz', 'sub-004/_contrast_id_1/cope1.nii.gz', 'sub-004/_contrast_id_2/cope1.nii.gz'], # copes + ['sub-001/_contrast_id_1/varcope1.nii.gz', 'sub-001/_contrast_id_2/varcope1.nii.gz', 'sub-002/_contrast_id_1/varcope1.nii.gz', 'sub-002/_contrast_id_2/varcope1.nii.gz', 'sub-003/_contrast_id_1/varcope1.nii.gz', 'sub-003/_contrast_id_2/varcope1.nii.gz', 'sub-004/_contrast_id_1/varcope1.nii.gz', 'sub-004/_contrast_id_2/varcope1.nii.gz'], # varcopes + ['001', '002', '003', '004'], # subject_list + ['fake_participants_file_path'] # participants file + ) + + assert cei == ['sub-001/_contrast_id_1/cope1.nii.gz', 'sub-001/_contrast_id_2/cope1.nii.gz', 'sub-003/_contrast_id_1/cope1.nii.gz', 'sub-003/_contrast_id_2/cope1.nii.gz'] + assert cer == ['sub-002/_contrast_id_1/cope1.nii.gz', 'sub-002/_contrast_id_2/cope1.nii.gz', 'sub-004/_contrast_id_1/cope1.nii.gz', 'sub-004/_contrast_id_2/cope1.nii.gz'] + assert vei == ['sub-001/_contrast_id_1/varcope1.nii.gz', 'sub-001/_contrast_id_2/varcope1.nii.gz', 'sub-003/_contrast_id_1/varcope1.nii.gz', 'sub-003/_contrast_id_2/varcope1.nii.gz'] + assert ver == ['sub-002/_contrast_id_1/varcope1.nii.gz', 'sub-002/_contrast_id_2/varcope1.nii.gz', 'sub-004/_contrast_id_1/varcope1.nii.gz', 'sub-004/_contrast_id_2/varcope1.nii.gz'] + assert eii == ['001', '003'] + assert eri == ['002', '004'] @staticmethod @mark.unit_test @@ -90,7 +116,7 @@ def test_one_sample_t_test_regressors(): """ Test the get_one_sample_t_test_regressors method """ regressors = PipelineTeam08MQ.get_one_sample_t_test_regressors(['001', '002']) - assert regressors == [1, 1] + assert regressors == {'group_mean': [1, 1]} @staticmethod @mark.unit_test