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

C88N refactoring #116

Merged
merged 39 commits into from
Jan 4, 2024
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
40abccc
[REFAC] make C88N conform with the Pipeline class + PEP8 clean
bclenet Mar 27, 2023
eabf700
[BUG] typo in dir names
bclenet Apr 7, 2023
d019195
[TEST] making paths consistent in pipeline test execution [skip ci]
bclenet Apr 7, 2023
9903f35
Using the right contrast ids
bclenet Apr 12, 2023
8db2006
Using the right contrast ids
bclenet Apr 12, 2023
7c6e160
[BUG] in ci script for pipeline changes
bclenet Mar 27, 2023
af995cb
[BUG] correctly forming results download link
bclenet Apr 7, 2023
6a74494
Allowing to tweak the number of processes the runner uses
bclenet Apr 12, 2023
da8a9fa
[ENH] Allowing to run group and subject level independantly
bclenet Apr 12, 2023
45a64c2
[TEST] test the runner launching first level or second level only
bclenet Apr 17, 2023
b705960
[DOC] runner : allow to run levels separately
bclenet Apr 18, 2023
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
1a34af5
Merge branch 'main' into c88n_refac
bclenet Sep 29, 2023
25f881c
Pipeline refac after merge
bclenet Sep 29, 2023
64127b9
Refac pipeline
bclenet Oct 2, 2023
9b9b646
[TEST] rewrite test file + bugs in pipeline file
bclenet Oct 3, 2023
e513308
Codespell
bclenet Oct 3, 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
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
f557d8e
Merge branch 'main' into c88n_refac [skip ci]
bclenet Jan 2, 2024
8aed13e
[REFAC] C88N [skip ci]
bclenet Jan 2, 2024
bc08911
[REFAC] using narps_open.core for contrast files selection [TEST] upd…
bclenet Jan 3, 2024
9645b7b
Issue with base directory [skip ci]
bclenet Jan 3, 2024
b607dc1
Back to the right order of contrasts [skip ci]
bclenet Jan 3, 2024
a79126c
[REFAC] naming [skip ci]
bclenet Jan 3, 2024
ac87fd9
Issue with groupComp [skip ci]
bclenet Jan 4, 2024
6bf8336
[BUG] subject ids in search patterns [skip ci]
bclenet Jan 4, 2024
4ec7dfe
Remove unwanted graphs[skip ci]
bclenet Jan 4, 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
Prev Previous commit
Next Next commit
[TEST] test the runner launching first level or second level only
bclenet committed Apr 25, 2023
commit 45a64c28e6deaf872a0508e22dd4190047b82f58
10 changes: 5 additions & 5 deletions narps_open/runner.py
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ def start(self, first_level_only: bool = False, group_level_only: bool = False)
for sub_workflow in workflow:
if not isinstance(sub_workflow, Workflow):
raise AttributeError('Workflow must be of type nipype.Workflow')

if nb_procs > 1:
sub_workflow.run('MultiProc', plugin_args={'n_procs': nb_procs})
else:
@@ -126,10 +126,10 @@ def start(self, first_level_only: bool = False, group_level_only: bool = False)
if not isinstance(workflow, Workflow):
raise AttributeError('Workflow must be of type nipype.Workflow')

if nb_procs > 1:
workflow.run('MultiProc', plugin_args={'n_procs': nb_procs})
else:
workflow.run()
if nb_procs > 1:
workflow.run('MultiProc', plugin_args={'n_procs': nb_procs})
else:
workflow.run()

if __name__ == '__main__':

1 change: 1 addition & 0 deletions narps_open/utils/configuration/testing_config.toml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ dataset = "tests/data/original/ds001734/"
reproduced_results = "tests/data/reproduced/"
narps_results = "tests/data/results/"
test_data = "tests/test_data/"
test_runs = "run/"

[runner]
nb_procs = 8 # Maximum number of threads executed by the runner
119 changes: 103 additions & 16 deletions tests/test_runner.py
Original file line number Diff line number Diff line change
@@ -11,11 +11,17 @@
pytest -q test_runner.py -k <selected_test>
"""

from os import remove
from os.path import join, isfile, abspath

from datetime import datetime

from pytest import raises, mark

from nipype import Node, Workflow
from nipype.interfaces.utility import Split, Merge
from nipype.interfaces.utility import Function

from narps_open.utils.configuration import Configuration
from narps_open.runner import PipelineRunner
from narps_open.pipelines import Pipeline
from narps_open.pipelines.team_2T6S import PipelineTeam2T6S
@@ -25,35 +31,67 @@ class MockupPipeline(Pipeline):

def __init__(self):
super().__init__()

def get_preprocessing(self):
node_1 = Node(
Split(),
self.test_file = abspath(
join(Configuration()['directories']['test_runs'], 'test_runner.txt'))
if isfile(self.test_file):
remove(self.test_file)

def __del__(self):
if isfile(self.test_file):
remove(self.test_file)

def write_to_file(_, text_to_write: str, file_path: str):
""" Method used inside a nipype Node, to write a line in a test file """
with open(file_path, 'a', encoding = 'utf-8') as file:
file.write(text_to_write)

def create_workflow(self, workflow_name: str):
""" Return a nipype worflow with two nodes writing in a file """
node_1 = Node(Function(
input_names = ['_', 'text_to_write', 'file_path'],
output_names = ['_'],
function = self.write_to_file),
name = 'node_1'
)
node_1.inputs.inlist = [1, 2, 3] # the list to split
node_1.inputs.splits = [1, 2] # the number of elements per output lists

node_2 = Node(
Merge(2),
# this input is set to now(), so that it changes at every run, thus preventing
# nipype's cache to work
node_1.inputs._ = datetime.now()
node_1.inputs.text_to_write = 'MockupPipeline : '+workflow_name+' node_1\n'
node_1.inputs.file_path = self.test_file

node_2 = Node(Function(
input_names = ['_', 'text_to_write', 'file_path'],
output_names = [],
function = self.write_to_file),
name = 'node_2'
)
node_2.inputs.text_to_write = 'MockupPipeline : '+workflow_name+' node_2\n'
node_2.inputs.file_path = self.test_file

workflow = Workflow(base_dir = 'run', name = 'TestPipelineRunner_preprocessing_workflow')
workflow = Workflow(
base_dir = Configuration()['directories']['test_runs'],
name = workflow_name
)
workflow.add_nodes([node_1, node_2])
workflow.connect(node_1, 'out1', node_2, 'in1')
workflow.connect(node_1, 'out2', node_2, 'in2')
workflow.connect(node_1, '_', node_2, '_')

return workflow

def get_preprocessing(self):
""" Return a fake preprocessing workflow """
return self.create_workflow('TestPipelineRunner_preprocessing_workflow')

def get_run_level_analysis(self):
return None
""" Return a fake run level workflow """
return self.create_workflow('TestPipelineRunner_run_level_workflow')

def get_subject_level_analysis(self):
return None
""" Return a fake subject level workflow """
return self.create_workflow('TestPipelineRunner_subject_level_workflow')

def get_group_level_analysis(self):
return None
""" Return a fake subject level workflow """
return self.create_workflow('TestPipelineRunner_group_level_workflow')

class MockupWrongPipeline(Pipeline):
""" A simple Pipeline class for test purposes """
@@ -182,6 +220,13 @@ def test_start_nok():
with raises(AttributeError):
runner.start()

# 2b - test starting a pipeline with wrong options (fist_level_only + group_level_only)
runner = PipelineRunner('2T6S')
runner._pipeline = MockupPipeline() # hack the runner by setting a test Pipeline

with raises(AttributeError):
runner.start(True, True)

@staticmethod
@mark.unit_test
def test_start_ok():
@@ -190,3 +235,45 @@ def test_start_ok():
runner = PipelineRunner('2T6S')
runner._pipeline = MockupPipeline() # hack the runner by setting a test Pipeline
runner.start()

# 1 - read results of the pipeline
with open(
join(Configuration()['directories']['test_runs'], 'test_runner.txt'),
'r', encoding = 'utf-8') as file:
for workflow in [
'TestPipelineRunner_preprocessing_workflow',
'TestPipelineRunner_run_level_workflow',
'TestPipelineRunner_subject_level_workflow',
'TestPipelineRunner_group_level_workflow']:
assert file.readline() == 'MockupPipeline : '+workflow+' node_1\n'
assert file.readline() == 'MockupPipeline : '+workflow+' node_2\n'

# 2 - test starting a pipeline partly (group_level_only)
runner = PipelineRunner('2T6S')
runner._pipeline = MockupPipeline() # hack the runner by setting a test Pipeline
runner.start(False, True)

# 2 - read results of the pipeline
with open(
join(Configuration()['directories']['test_runs'], 'test_runner.txt'),
'r', encoding = 'utf-8') as file:
assert file.readline() == \
'MockupPipeline : TestPipelineRunner_group_level_workflow node_1\n'
assert file.readline() == \
'MockupPipeline : TestPipelineRunner_group_level_workflow node_2\n'

# 3 - test starting a pipeline partly (first_level_only)
runner = PipelineRunner('2T6S')
runner._pipeline = MockupPipeline() # hack the runner by setting a test Pipeline
runner.start(True, False)

# 3 - read results of the pipeline
with open(
join(Configuration()['directories']['test_runs'], 'test_runner.txt'),
'r', encoding = 'utf-8') as file:
for workflow in [
'TestPipelineRunner_preprocessing_workflow',
'TestPipelineRunner_run_level_workflow',
'TestPipelineRunner_subject_level_workflow']:
assert file.readline() == 'MockupPipeline : '+workflow+' node_1\n'
assert file.readline() == 'MockupPipeline : '+workflow+' node_2\n'