Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

98BT refactoring #119

Merged
merged 42 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6986e90
[BUG] inside unit_tests workflow
bclenet Aug 31, 2023
d6e67f3
Merge branch 'Inria-Empenn:main' into main
bclenet Aug 31, 2023
c3bfc53
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 4, 2023
4b30504
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 19, 2023
fd15ffc
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 21, 2023
6ebe5d2
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 29, 2023
0a584dd
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 29, 2023
e284b80
Merge branch 'Inria-Empenn:main' into main
bclenet Sep 29, 2023
839895f
Refactoring pipeline 98BT
bclenet Oct 4, 2023
ec0f8f2
[TEST] update tests [REFAC] pep8 and bug correction
bclenet Oct 4, 2023
5774813
Merge branch 'Inria-Empenn:main' into main
bclenet Oct 5, 2023
8f12d3d
Merge branch 'Inria-Empenn:main' into main
bclenet Oct 5, 2023
eb2b118
Merge branch 'main' into 98BT_refac
bclenet Oct 5, 2023
1f0a528
Using narps_open.data.task module inside 98BT
bclenet Oct 5, 2023
3e9c01a
[TEST] update + dependancy to niflow
bclenet Oct 5, 2023
91dc744
Merge branch 'Inria-Empenn:main' into main
bclenet Oct 10, 2023
c03e9d1
Merge branch 'Inria-Empenn:main' into main
bclenet Nov 20, 2023
fe0d25b
Merge branch 'Inria-Empenn:main' into main
bclenet Nov 22, 2023
04d5ff2
Merge branch 'Inria-Empenn:main' into main
bclenet Nov 22, 2023
ecf2b11
Merge branch 'main' into 98BT_refac
bclenet Jan 3, 2024
3bedbfd
[REFAC][skip ci]
bclenet Jan 3, 2024
c9ee889
Merge branch 'Inria-Empenn:main' into main
bclenet Jan 5, 2024
1530159
Merge branch 'main' into 98BT_refac [skip ci]
bclenet Jan 5, 2024
c8bddd8
[BUG] input of get_contrats [skip ci]
bclenet Jan 5, 2024
2a8ea4a
Merge branch 'main' into 98BT_refac
bclenet Jan 29, 2024
2d35726
Light bugs + remove large files [skip ci]
bclenet Jan 30, 2024
9831d37
[TEST] adding tests for 98BT
bclenet Feb 6, 2024
c04ba9c
Merge branch 'main' into 98BT_refac
bclenet Feb 6, 2024
acd4548
[TEST] adding tests for 98BT
bclenet Feb 6, 2024
50dff7b
[TEST] adding tests for 98BT
bclenet Feb 6, 2024
bab6126
Output names for 98BT
bclenet Feb 6, 2024
ea8b5c3
Preprocessing output names
bclenet Feb 6, 2024
6c4204e
Subject info issue + output names
bclenet Feb 7, 2024
e641b1e
98BT - Refac get_parameters_files
bclenet Feb 7, 2024
355e33a
[TEST] 98BT get_parameters_file
bclenet Feb 7, 2024
36ff807
Merge branch 'main' into 98BT_refac
bclenet Feb 7, 2024
7bbf479
Using fixture for temporary test dir creation / removal
bclenet Feb 7, 2024
c7cc9e2
Linting pipelines test files
bclenet Feb 7, 2024
f460ed8
Bug with regressors naming
bclenet Feb 7, 2024
c02451b
Merge branch 'main' into 98BT_refac
bclenet Feb 19, 2024
38af98f
pylintrc for pylint config
bclenet Feb 19, 2024
8741d5e
Merge branch 'main' into 98BT_refac
bclenet Mar 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion narps_open/pipelines/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
'6VV2': None,
'80GC': None,
'94GU': None,
'98BT': None,
'98BT': 'PipelineTeam98BT',
'9Q6R': None,
'9T8E': None,
'9U7M': None,
Expand Down
1,702 changes: 920 additions & 782 deletions narps_open/pipelines/team_98BT.py

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
'networkx>=2.0,<3.0', # a workaround to nipype's bug (issue 3530)
'nilearn>=0.10.0,<0.11',
'nipype>=1.8.6,<1.9',
'pandas>=1.5.2,<1.6'
'pandas>=1.5.2,<1.6',
'niflow-nipype1-workflows>=0.0.5,<0.1.0'
]
extras_require = {
'tests': [
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from numpy import isclose
from pytest import helpers, fixture
from pathvalidate import is_valid_filepath
from numpy import isclose

from narps_open.pipelines import Pipeline
from narps_open.runner import PipelineRunner
Expand Down
46 changes: 19 additions & 27 deletions tests/pipelines/templates/template_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@

""" This template can be use to test a pipeline.

- Replace all occurrences of XXXX by the actual id of the team.
- Replace all occurrences of 2T6S by the actual id of the team.
- All lines starting with [INFO], are meant to help you during the reproduction,
these can be removed eventually.
- Also remove lines starting with [TODO], once you did what they suggested.
- Remove this docstring once you are done with coding the tests.
"""

""" Tests of the 'narps_open.pipelines.team_XXXX' module.
""" Tests of the 'narps_open.pipelines.team_2T6S' module.

Launch this test with PyTest

Usage:
======
pytest -q test_team_XXXX.py
pytest -q test_team_XXXX.py -k <selected_test>
pytest -q test_team_2T6S.py
pytest -q test_team_2T6S.py -k <selected_test>
"""

# [INFO] About these imports :
Expand All @@ -28,12 +28,12 @@
# [INFO] Only for type testing
from nipype import Workflow

# [INFO] Of course, import the class you want to test, here the Pipeline class for the team XXXX
from narps_open.pipelines.team_XXXX import PipelineTeamXXXX
# [INFO] Of course, import the class you want to test, here the Pipeline class for the team 2T6S
from narps_open.pipelines.team_2T6S import PipelineTeam2T6S

# [INFO] All tests should be contained in the following class, in order to sort them.
class TestPipelinesTeamXXXX:
""" A class that contains all the unit tests for the PipelineTeamXXXX class."""
class TestPipelinesTeam2T6S:
""" A class that contains all the unit tests for the PipelineTeam2T6S class."""

# [TODO] Write one or several unit_test (and mark them as such)
# [TODO] ideally for each method of the class you test.
Expand All @@ -42,19 +42,19 @@ class TestPipelinesTeamXXXX:
@staticmethod
@mark.unit_test
def test_create():
""" Test the creation of a PipelineTeamXXXX object """
""" Test the creation of a PipelineTeam2T6S object """

pipeline = PipelineTeamXXXX()
pipeline = PipelineTeam2T6S()
assert pipeline.fwhm == 8.0
assert pipeline.team_id == 'XXXX'
assert pipeline.team_id == '2T6S'

# [INFO] Here is one example for the methods returning workflows
@staticmethod
@mark.unit_test
def test_workflows():
""" Test the workflows of a PipelineTeamXXXX object """
""" Test the workflows of a PipelineTeam2T6S object """

pipeline = PipelineTeamXXXX()
pipeline = PipelineTeam2T6S()
assert pipeline.get_preprocessing() is None
assert pipeline.get_run_level_analysis() is None
assert isinstance(pipeline.get_subject_level_analysis(), Workflow)
Expand All @@ -68,24 +68,16 @@ def test_workflows():
@staticmethod
@mark.unit_test
def test_outputs():
""" Test the expected outputs of a PipelineTeamXXXX object """
pipeline = PipelineTeamXXXX()
""" Test the expected outputs of a PipelineTeam2T6S object """
pipeline = PipelineTeam2T6S()

# 1 - 1 subject outputs
pipeline.subject_list = ['001']
assert len(pipeline.get_preprocessing_outputs()) == 0
assert len(pipeline.get_run_level_outputs()) == 0
assert len(pipeline.get_subject_level_outputs()) == 7
assert len(pipeline.get_group_level_outputs()) == 63
assert len(pipeline.get_hypotheses_outputs()) == 18
helpers.test_pipeline_outputs(pipeline, [0, 0, 7, 63, 18])

# 2 - 4 subjects outputs
pipeline.subject_list = ['001', '002', '003', '004']
assert len(pipeline.get_preprocessing_outputs()) == 0
assert len(pipeline.get_run_level_outputs()) == 0
assert len(pipeline.get_subject_level_outputs()) == 28
assert len(pipeline.get_group_level_outputs()) == 63
assert len(pipeline.get_hypotheses_outputs()) == 18
helpers.test_pipeline_outputs(pipeline, [0, 0, 28, 63, 18])

# [TODO] Feel free to add other methods, e.g. to test the custom node functions of the pipeline

Expand All @@ -95,8 +87,8 @@ def test_outputs():
@staticmethod
@mark.pipeline_test
def test_execution():
""" Test the execution of a PipelineTeamXXXX and compare results """
""" Test the execution of a PipelineTeam2T6S and compare results """

# [INFO] We use the `test_pipeline_evaluation` helper which is responsible for running the
# [INFO] pipeline, iterating over subjects and comparing output with expected results.
helpers.test_pipeline_evaluation('XXXX')
helpers.test_pipeline_evaluation('2T6S')
153 changes: 153 additions & 0 deletions tests/pipelines/test_team_98BT.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/python
# coding: utf-8

""" Tests of the 'narps_open.pipelines.team_98BT' module.

Launch this test with PyTest

Usage:
======
pytest -q test_team_98BT.py
pytest -q test_team_98BT.py -k <selected_test>
"""
from os.path import join, exists
from filecmp import cmp

from pytest import helpers, mark
from nipype import Workflow
from nipype.interfaces.base import Bunch

from narps_open.utils.configuration import Configuration
from narps_open.pipelines.team_98BT import PipelineTeam98BT

TEMPORARY_DIR = join(Configuration()['directories']['test_runs'], 'test_98BT')

class TestPipelinesTeam98BT:
""" A class that contains all the unit tests for the PipelineTeam98BT class."""

@staticmethod
@mark.unit_test
def test_create():
""" Test the creation of a PipelineTeam98BT object """

pipeline = PipelineTeam98BT()

# 1 - check the parameters
assert pipeline.fwhm == 8.0
assert pipeline.team_id == '98BT'

# 2 - check workflows
processing = pipeline.get_preprocessing()
assert len(processing) == 2
for sub_workflow in processing:
assert isinstance(sub_workflow, Workflow)

assert pipeline.get_run_level_analysis() is None
assert isinstance(pipeline.get_subject_level_analysis(), Workflow)

group_level = pipeline.get_group_level_analysis()
assert len(group_level) == 3
for sub_workflow in group_level:
assert isinstance(sub_workflow, Workflow)

@staticmethod
@mark.unit_test
def test_outputs():
""" Test the expected outputs of a PipelineTeam98BT object """
pipeline = PipelineTeam98BT()
# 1 - 1 subject outputs
pipeline.subject_list = ['001']
helpers.test_pipeline_outputs(pipeline, [1 + 1*1 + 4*1*5,0,9,84,18])

# 2 - 4 subjects outputs
pipeline.subject_list = ['001', '002', '003', '004']
helpers.test_pipeline_outputs(pipeline, [1 + 4*1 + 4*4*5,0,36,84,18])

@staticmethod
@mark.unit_test
def test_fieldmap_info():
""" Test the get_fieldmap_info method """

filedmap_file_1 = join(
Configuration()['directories']['test_data'], 'pipelines', 'phasediff_1.json')
filedmap_file_2 = join(
Configuration()['directories']['test_data'], 'pipelines', 'phasediff_2.json')

test_result = PipelineTeam98BT.get_fieldmap_info(
filedmap_file_1, ['magnitude_1', 'magnitude_2'])
assert test_result[0] == (0.00492, 0.00738)
assert test_result[1] == 'magnitude_1'
test_result = PipelineTeam98BT.get_fieldmap_info(
filedmap_file_2, ['magnitude_1', 'magnitude_2'])
assert test_result[0] == (0.00492, 0.00738)
assert test_result[1] == 'magnitude_2'

@staticmethod
@mark.unit_test
@mark.parametrize('remove_test_dir', TEMPORARY_DIR)
def test_parameters_files(remove_test_dir):
""" Test the get_parameters_files method
For this test, we created the two following files by downsampling output files
from the preprocessing pipeline :
- wc2sub-001_T1w-32.nii (white matter file)
- uasub-001_task-MGT_run-01_bold_resampled-32.nii (motion corrected file)
Voxel dimension was multiplied by 32, number of slices was reduced to 4.
"""
parameters_file = join(
Configuration()['directories']['test_data'], 'pipelines', 'confounds.tsv')
func_file = join(Configuration()['directories']['test_data'], 'pipelines',
'team_98BT', 'uasub-001_task-MGT_run-01_bold_resampled-32.nii')
wc2_file = join(Configuration()['directories']['test_data'], 'pipelines',
'team_98BT', 'wc2sub-001_T1w-32.nii')
reference_file = join(
Configuration()['directories']['test_data'], 'pipelines',
'team_98BT', 'parameters_file.tsv')

# Get new parameters file
PipelineTeam98BT.get_parameters_file(
parameters_file, wc2_file, func_file, 'sid', 'rid', TEMPORARY_DIR)

# Check parameters file was created
created_parameters_file = join(
TEMPORARY_DIR, 'parameters_files', 'parameters_file_sub-sid_run-rid.tsv')
assert exists(created_parameters_file)

# Check contents
assert cmp(reference_file, created_parameters_file)

@staticmethod
@mark.unit_test
def test_subject_information():
""" Test the get_subject_information method """

# Get test files
test_file = join(Configuration()['directories']['test_data'], 'pipelines', 'events.tsv')

bunch = PipelineTeam98BT.get_subject_information(test_file, 1)

# Compare bunches to expected
assert isinstance(bunch, Bunch)
assert bunch.conditions == ['gamble_run1']
helpers.compare_float_2d_arrays(bunch.onsets, [
[4.071, 11.834, 19.535, 27.535, 36.435]])
helpers.compare_float_2d_arrays(bunch.durations, [
[4.0, 4.0, 4.0, 4.0, 4.0]])
assert bunch.amplitudes is None
assert bunch.tmod is None
assert bunch.regressor_names is None
assert bunch.regressors is None
pmod = bunch.pmod[0]
assert isinstance(pmod, Bunch)
assert pmod.name == ['gain_run1', 'loss_run1', 'answers_run1']
assert pmod.poly == [1, 1, 1]
helpers.compare_float_2d_arrays(pmod.param, [
[14.0, 34.0, 38.0, 10.0, 16.0],
[6.0, 14.0, 19.0, 15.0, 17.0],
[1, 1, 0, 0, 0]
])

@staticmethod
@mark.pipeline_test
def test_execution():
""" Test the execution of a PipelineTeam98BT and compare results """
helpers.test_pipeline_evaluation('98BT')
1 change: 1 addition & 0 deletions tests/test_data/pipelines/phasediff_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"EchoTime1": 0.00492, "EchoTime2": 0.00738, "IntendedFor": ["func/sub-001_task-MGT_run-01_bold.nii.gz", "func/sub-001_task-MGT_run-02_bold.nii.gz", "func/sub-001_task-MGT_run-03_bold.nii.gz", "func/sub-001_task-MGT_run-04_bold.nii.gz"]}
1 change: 1 addition & 0 deletions tests/test_data/pipelines/phasediff_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"EchoTime1": 0.00738, "EchoTime2": 0.00492, "IntendedFor": ["func/sub-001_task-MGT_run-01_bold.nii.gz", "func/sub-001_task-MGT_run-02_bold.nii.gz", "func/sub-001_task-MGT_run-03_bold.nii.gz", "func/sub-001_task-MGT_run-04_bold.nii.gz"]}
4 changes: 4 additions & 0 deletions tests/test_data/pipelines/team_98BT/parameters_file.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"CSF WhiteMatter GlobalSignal stdDVARS non-stdDVARS vx-wisestdDVARS FramewiseDisplacement tCompCor00 tCompCor01 tCompCor02 tCompCor03 tCompCor04 tCompCor05 aCompCor00 aCompCor01 aCompCor02 aCompCor03 aCompCor04 aCompCor05 Cosine00 Cosine01 Cosine02 Cosine03 Cosine04 Cosine05 NonSteadyStateOutlier00 X Y Z RotX RotY RotZ" 261.948061726888
"6551.281999999999 6476.4653 9874.576 n/a n/a n/a n/a 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 -0.0 0.0" 241.43458658854166
"6484.7285 6473.4890000000005 9830.212 1.09046686 52.78273392 1.05943739 0.13527900930999998 0.0263099209 -0.0673065879 0.0934882554 -0.0079328884 0.0338007737 -0.011491083999999999 -0.042411347099999996 0.027736422900000002 0.0453303087 -0.07022609490000001 0.0963618709 -0.0200867957 0.0665186088 0.0665174038 0.0665153954 0.0665125838 0.0665089688 0.06650455059999999 0.0 -0.00996895 -0.0313444 -3.00931e-06 0.00132687 -0.000384193 -0.00016819" 246.2539803059896
"6441.5337 6485.7256 9821.212 1.07520139 52.04382706 1.03821933 0.12437666391 -0.0404820317 0.034150583 0.13661184210000002 0.0745358691 -0.0054829985999999995 -0.0217322686 0.046214115199999996 0.005774624 -0.043909359800000006 -0.075619539 0.17546891539999998 -0.0345256763 0.0665153954 0.06650455059999999 0.06648647719999999 0.0664611772 0.0664286533 0.0663889091 0.0 -2.56954e-05 -0.00923735 0.0549667 0.000997278 -0.00019745 -0.000398988" 246.21754170735676
Binary file not shown.
Binary file not shown.
Loading