-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[INFRA] Run anat non regression tests with GitHub actions (#987)
* refactor anat pipelines tests * update jenkins files * Add a ghaction workflow (runs on PR for now but will make it a cron) * increase timeout and make cron
- Loading branch information
1 parent
15511a9
commit 54876f1
Showing
7 changed files
with
640 additions
and
646 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: Anat Pipelines Tests | ||
|
||
on: | ||
schedule: | ||
- cron: 0 20 * * 4 # every thursday at 8pm | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
test-pipelines-anat-MacOS: | ||
runs-on: | ||
- self-hosted | ||
- macOS | ||
timeout-minutes: 720 | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: snok/install-poetry@v1 | ||
- name: Run tests for anat pipelines | ||
run: | | ||
make env.conda | ||
source ~/miniconda3/etc/profile.d/conda.sh | ||
conda activate "${{ github.workspace }}"/env | ||
source "$(brew --prefix)/opt/modules/init/bash" | ||
module load clinica.all | ||
make install | ||
cd test | ||
poetry run pytest --verbose \ | ||
--working_directory=/Volumes/data/working_dir_mac \ | ||
--input_data_directory=/Volumes/data_ci \ | ||
--basetemp=/Volumes/data/tmp \ | ||
--junitxml=./test-reports/non_regression_anat_mac.xml \ | ||
--disable-warnings \ | ||
./nonregression/pipelines/anat | ||
test-pipelines-anat-Linux: | ||
runs-on: | ||
- self-hosted | ||
- Linux | ||
timeout-minutes: 720 | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: snok/install-poetry@v1 | ||
- name: Run tests for anat pipelines | ||
run: | | ||
make env.conda | ||
source /builds/miniconda/etc/profile.d/conda.sh | ||
conda activate "${{ github.workspace }}"/env | ||
source /usr/local/Modules/init/profile.sh | ||
module load clinica.all | ||
make install | ||
cd test | ||
poetry run pytest --verbose \ | ||
--working_directory=/mnt/data/ci/working_dir_linux \ | ||
--input_data_directory=/mnt/data_ci \ | ||
--basetemp=/mnt/data/ci/tmp \ | ||
--junitxml=./test-reports/non_regression_anat_linux.xml \ | ||
--disable-warnings \ | ||
./nonregression/pipelines/anat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
191 changes: 191 additions & 0 deletions
191
test/nonregression/pipelines/anat/test_t1_freesurfer.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
import shutil | ||
from os import fspath | ||
from pathlib import Path | ||
from test.nonregression.testing_tools import compare_folders, configure_paths | ||
|
||
import pytest | ||
|
||
|
||
@pytest.mark.slow | ||
def test_t1_freesurfer_cross_sectional(cmdopt, tmp_path): | ||
base_dir = Path(cmdopt["input"]) | ||
working_dir = Path(cmdopt["wd"]) | ||
input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "T1FreeSurfer") | ||
run_t1_freesurfer_cross_sectional(input_dir, tmp_dir, ref_dir, working_dir) | ||
|
||
|
||
def run_t1_freesurfer_cross_sectional( | ||
input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path | ||
) -> None: | ||
"""Run the T1FreeSurfer pipeline on test data. | ||
Notes | ||
----- | ||
Data for this functional test comes from https://openneuro.org/datasets/ds000204 | ||
We only check that folders are the same meaning that FreeSurfer finished without error. | ||
surf/ folder is ignored because it contains symlinks that makes hard to check with ref data | ||
(symlinks of ref data are ignored after rsync on CI machines). | ||
""" | ||
from clinica.pipelines.t1_freesurfer.t1_freesurfer_pipeline import T1FreeSurfer | ||
|
||
parameters = {"recon_all_args": "-qcache", "skip_question": False} | ||
|
||
pipeline = T1FreeSurfer( | ||
bids_directory=fspath(input_dir / "bids"), | ||
caps_directory=fspath(output_dir / "caps"), | ||
tsv_file=fspath(input_dir / "subjects.tsv"), | ||
parameters=parameters, | ||
base_dir=fspath(working_dir), | ||
) | ||
pipeline.run(bypass_check=True) | ||
|
||
folder = _get_path_to_caps_freesurfer_cross_sectional("sub-01", "ses-2011") | ||
compare_folders( | ||
output_dir / folder / "regional_measures", | ||
ref_dir / folder / "regional_measures", | ||
output_dir, | ||
) | ||
for sub_folder in ("label", "mri", "stats"): | ||
compare_folders( | ||
output_dir / folder / "sub-01_ses-2011" / sub_folder, | ||
ref_dir / folder / "sub-01_ses-2011" / sub_folder, | ||
output_dir, | ||
) | ||
|
||
|
||
def _get_path_to_caps_freesurfer_cross_sectional(part_id: str, session_id: str) -> Path: | ||
return ( | ||
Path("caps") | ||
/ "subjects" | ||
/ part_id | ||
/ session_id | ||
/ "t1" | ||
/ "freesurfer_cross_sectional" | ||
) | ||
|
||
|
||
@pytest.mark.slow | ||
def test_t1_freesurfer_template(cmdopt, tmp_path): | ||
base_dir = Path(cmdopt["input"]) | ||
working_dir = Path(cmdopt["wd"]) | ||
input_dir, tmp_dir, ref_dir = configure_paths( | ||
base_dir, tmp_path, "T1FreeSurferTemplate" | ||
) | ||
run_t1_freesurfer_template(input_dir, tmp_dir, ref_dir, working_dir) | ||
|
||
|
||
def run_t1_freesurfer_template( | ||
input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path | ||
) -> None: | ||
"""Run the T1FreeSurferTemplate pipeline on test data. | ||
Notes | ||
----- | ||
Data for this functional test comes from https://openneuro.org/datasets/ds000204 | ||
sub-01 was duplicated into to sub-02 with one session in order to test the "one time point" case. | ||
We only check that folders are the same meaning that FreeSurfer finished without error. | ||
surf/ folder is ignored because it contains symlinks that makes hard to check with ref data | ||
(symlinks of ref data are ignored after rsync on CI machines). | ||
""" | ||
from clinica.pipelines.t1_freesurfer_longitudinal.t1_freesurfer_template_pipeline import ( | ||
T1FreeSurferTemplate, | ||
) | ||
|
||
shutil.copytree(input_dir / "caps", output_dir / "caps", copy_function=shutil.copy) | ||
|
||
pipeline = T1FreeSurferTemplate( | ||
caps_directory=fspath(output_dir / "caps"), | ||
tsv_file=fspath(input_dir / "subjects.tsv"), | ||
base_dir=fspath(working_dir), | ||
) | ||
pipeline.run(plugin="MultiProc", plugin_args={"n_procs": 2}, bypass_check=True) | ||
|
||
for part_id, long_id in zip(["sub-01", "sub-02"], ["long-20112015", "long-2011"]): | ||
folder = ( | ||
_get_path_to_caps_freesurfer_template(part_id, long_id) | ||
/ f"{part_id}_{long_id}" | ||
) | ||
for sub_folder in ("label", "mri", "stats"): | ||
compare_folders( | ||
output_dir / folder / sub_folder, | ||
ref_dir / folder / sub_folder, | ||
output_dir, | ||
) | ||
|
||
|
||
def _get_path_to_caps_freesurfer_template(part_id: str, long_id: str) -> Path: | ||
return ( | ||
Path("caps") / "subjects" / part_id / long_id / "freesurfer_unbiased_template" | ||
) | ||
|
||
|
||
@pytest.mark.slow | ||
def test_t1_freesurfer_longitudinal_correction(cmdopt, tmp_path): | ||
base_dir = Path(cmdopt["input"]) | ||
working_dir = Path(cmdopt["wd"]) | ||
input_dir, tmp_dir, ref_dir = configure_paths( | ||
base_dir, tmp_path, "T1FreeSurferLongitudinalCorrection" | ||
) | ||
run_t1_freesurfer_longitudinal_correction(input_dir, tmp_dir, ref_dir, working_dir) | ||
|
||
|
||
def run_t1_freesurfer_longitudinal_correction( | ||
input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path | ||
) -> None: | ||
"""Run the T1FreeSurferLongitudinalCorrection pipeline on test data. | ||
Notes | ||
----- | ||
Data for this functional test comes from https://openneuro.org/datasets/ds000204 | ||
We only check that folders are the same meaning that FreeSurfer finished without error. | ||
surf/ folder is ignored because it contains symlinks that makes hard to check with ref data | ||
(symlinks of ref data are ignored after rsync on CI machines). | ||
""" | ||
from clinica.pipelines.t1_freesurfer_longitudinal.t1_freesurfer_longitudinal_correction_pipeline import ( | ||
T1FreeSurferLongitudinalCorrection, | ||
) | ||
|
||
shutil.copytree(input_dir / "caps", output_dir / "caps", copy_function=shutil.copy) | ||
|
||
pipeline = T1FreeSurferLongitudinalCorrection( | ||
caps_directory=fspath(output_dir / "caps"), | ||
tsv_file=fspath(input_dir / "subjects.tsv"), | ||
base_dir=fspath(working_dir), | ||
) | ||
pipeline.run(bypass_check=True) | ||
|
||
folder = _get_path_to_caps_freesurfer_longitudinal( | ||
"sub-01", "ses-2011", "long-20112015" | ||
) | ||
compare_folders( | ||
output_dir / folder / "regional_measures", | ||
ref_dir / folder / "regional_measures", | ||
output_dir, | ||
) | ||
for sub_folder in ("label", "mri", "stats"): | ||
compare_folders( | ||
output_dir | ||
/ folder | ||
/ "sub-01_ses-2011.long.sub-01_long-20112015" | ||
/ sub_folder, | ||
ref_dir / folder / "sub-01_ses-2011.long.sub-01_long-20112015" / sub_folder, | ||
output_dir, | ||
) | ||
|
||
|
||
def _get_path_to_caps_freesurfer_longitudinal( | ||
part_id: str, session_id: str, long_id: str | ||
) -> Path: | ||
return ( | ||
Path("caps") | ||
/ "subjects" | ||
/ part_id | ||
/ session_id | ||
/ "t1" | ||
/ long_id | ||
/ "freesurfer_longitudinal" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from os import fspath | ||
from pathlib import Path | ||
from test.nonregression.testing_tools import compare_folders, configure_paths | ||
|
||
import pytest | ||
|
||
|
||
@pytest.mark.fast | ||
def test_t1_linear(cmdopt, tmp_path): | ||
base_dir = Path(cmdopt["input"]) | ||
working_dir = Path(cmdopt["wd"]) | ||
input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "T1Linear") | ||
run_t1_linear(input_dir, tmp_dir, ref_dir, working_dir) | ||
|
||
|
||
@pytest.mark.fast | ||
def test_flair_linear(cmdopt, tmp_path): | ||
base_dir = Path(cmdopt["input"]) | ||
working_dir = Path(cmdopt["wd"]) | ||
input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "FlairLinear") | ||
run_flair_linear(input_dir, tmp_dir, ref_dir, working_dir) | ||
|
||
|
||
def run_t1_linear( | ||
input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path | ||
) -> None: | ||
from clinica.pipelines.t1_linear.anat_linear_pipeline import AnatLinear | ||
|
||
pipeline = AnatLinear( | ||
bids_directory=fspath(input_dir / "bids"), | ||
caps_directory=fspath(output_dir / "caps"), | ||
tsv_file=fspath(input_dir / "subjects.tsv"), | ||
base_dir=fspath(working_dir), | ||
parameters={"uncropped_image": False}, | ||
name="t1-linear", | ||
) | ||
pipeline.run(plugin="MultiProc", plugin_args={"n_procs": 4}, bypass_check=True) | ||
|
||
compare_folders(output_dir / "caps", ref_dir / "caps", output_dir) | ||
|
||
|
||
def run_flair_linear( | ||
input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path | ||
) -> None: | ||
from clinica.pipelines.t1_linear.anat_linear_pipeline import AnatLinear | ||
|
||
pipeline = AnatLinear( | ||
bids_directory=fspath(input_dir / "bids"), | ||
caps_directory=fspath(output_dir / "caps"), | ||
base_dir=fspath(working_dir), | ||
parameters={"uncropped_image": False}, | ||
name="flair-linear", | ||
) | ||
pipeline.run(plugin="MultiProc", plugin_args={"n_procs": 4}, bypass_check=True) | ||
|
||
compare_folders(output_dir / "caps", ref_dir / "caps", output_dir) |
Oops, something went wrong.