junifer 0.0.4.dev831__py3-none-any.whl → 0.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- junifer/__init__.py +17 -0
- junifer/_version.py +2 -2
- junifer/api/__init__.py +4 -1
- junifer/api/cli.py +91 -1
- junifer/api/decorators.py +9 -0
- junifer/api/functions.py +56 -10
- junifer/api/parser.py +3 -0
- junifer/api/queue_context/__init__.py +4 -1
- junifer/api/queue_context/gnu_parallel_local_adapter.py +16 -6
- junifer/api/queue_context/htcondor_adapter.py +16 -5
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +41 -12
- junifer/api/queue_context/tests/test_htcondor_adapter.py +48 -15
- junifer/api/res/afni/run_afni_docker.sh +1 -1
- junifer/api/res/ants/run_ants_docker.sh +1 -1
- junifer/api/res/freesurfer/mri_binarize +3 -0
- junifer/api/res/freesurfer/mri_mc +3 -0
- junifer/api/res/freesurfer/mri_pretess +3 -0
- junifer/api/res/freesurfer/mris_convert +3 -0
- junifer/api/res/freesurfer/run_freesurfer_docker.sh +61 -0
- junifer/api/res/fsl/run_fsl_docker.sh +1 -1
- junifer/api/res/{run_conda.sh → run_conda.bash} +1 -1
- junifer/api/res/run_conda.zsh +23 -0
- junifer/api/res/run_venv.bash +22 -0
- junifer/api/res/{run_venv.sh → run_venv.zsh} +1 -1
- junifer/api/tests/test_api_utils.py +4 -2
- junifer/api/tests/test_cli.py +83 -0
- junifer/api/tests/test_functions.py +27 -2
- junifer/configs/__init__.py +1 -1
- junifer/configs/juseless/__init__.py +4 -1
- junifer/configs/juseless/datagrabbers/__init__.py +10 -1
- junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +4 -3
- junifer/configs/juseless/datagrabbers/camcan_vbm.py +3 -0
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +4 -3
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +1 -3
- junifer/configs/juseless/datagrabbers/ucla.py +12 -9
- junifer/configs/juseless/datagrabbers/ukb_vbm.py +3 -0
- junifer/data/__init__.py +21 -1
- junifer/data/coordinates.py +10 -19
- junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz +0 -0
- junifer/data/masks.py +58 -87
- junifer/data/parcellations.py +14 -3
- junifer/data/template_spaces.py +4 -1
- junifer/data/tests/test_masks.py +26 -37
- junifer/data/utils.py +3 -0
- junifer/datagrabber/__init__.py +18 -1
- junifer/datagrabber/aomic/__init__.py +3 -0
- junifer/datagrabber/aomic/id1000.py +70 -37
- junifer/datagrabber/aomic/piop1.py +69 -36
- junifer/datagrabber/aomic/piop2.py +71 -38
- junifer/datagrabber/aomic/tests/test_id1000.py +44 -100
- junifer/datagrabber/aomic/tests/test_piop1.py +65 -108
- junifer/datagrabber/aomic/tests/test_piop2.py +45 -102
- junifer/datagrabber/base.py +13 -6
- junifer/datagrabber/datalad_base.py +13 -1
- junifer/datagrabber/dmcc13_benchmark.py +36 -53
- junifer/datagrabber/hcp1200/__init__.py +3 -0
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +3 -0
- junifer/datagrabber/hcp1200/hcp1200.py +4 -1
- junifer/datagrabber/multiple.py +45 -6
- junifer/datagrabber/pattern.py +170 -62
- junifer/datagrabber/pattern_datalad.py +25 -12
- junifer/datagrabber/pattern_validation_mixin.py +388 -0
- junifer/datagrabber/tests/test_datalad_base.py +4 -4
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +46 -19
- junifer/datagrabber/tests/test_multiple.py +161 -84
- junifer/datagrabber/tests/test_pattern.py +45 -0
- junifer/datagrabber/tests/test_pattern_datalad.py +4 -4
- junifer/datagrabber/tests/test_pattern_validation_mixin.py +249 -0
- junifer/datareader/__init__.py +4 -1
- junifer/datareader/default.py +95 -43
- junifer/external/BrainPrint/brainprint/__init__.py +4 -0
- junifer/external/BrainPrint/brainprint/_version.py +3 -0
- junifer/external/BrainPrint/brainprint/asymmetry.py +91 -0
- junifer/external/BrainPrint/brainprint/brainprint.py +441 -0
- junifer/external/BrainPrint/brainprint/surfaces.py +258 -0
- junifer/external/BrainPrint/brainprint/utils/__init__.py +1 -0
- junifer/external/BrainPrint/brainprint/utils/_config.py +112 -0
- junifer/external/BrainPrint/brainprint/utils/utils.py +188 -0
- junifer/external/__init__.py +1 -1
- junifer/external/nilearn/__init__.py +5 -1
- junifer/external/nilearn/junifer_connectivity_measure.py +483 -0
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +23 -9
- junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +1089 -0
- junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +76 -1
- junifer/markers/__init__.py +23 -1
- junifer/markers/base.py +68 -28
- junifer/markers/brainprint.py +459 -0
- junifer/markers/collection.py +10 -2
- junifer/markers/complexity/__init__.py +10 -0
- junifer/markers/complexity/complexity_base.py +26 -43
- junifer/markers/complexity/hurst_exponent.py +3 -0
- junifer/markers/complexity/multiscale_entropy_auc.py +3 -0
- junifer/markers/complexity/perm_entropy.py +3 -0
- junifer/markers/complexity/range_entropy.py +3 -0
- junifer/markers/complexity/range_entropy_auc.py +3 -0
- junifer/markers/complexity/sample_entropy.py +3 -0
- junifer/markers/complexity/tests/test_hurst_exponent.py +11 -3
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +11 -3
- junifer/markers/complexity/tests/test_perm_entropy.py +11 -3
- junifer/markers/complexity/tests/test_range_entropy.py +11 -3
- junifer/markers/complexity/tests/test_range_entropy_auc.py +11 -3
- junifer/markers/complexity/tests/test_sample_entropy.py +11 -3
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +11 -3
- junifer/markers/complexity/weighted_perm_entropy.py +3 -0
- junifer/markers/ets_rss.py +27 -42
- junifer/markers/falff/__init__.py +3 -0
- junifer/markers/falff/_afni_falff.py +5 -2
- junifer/markers/falff/_junifer_falff.py +3 -0
- junifer/markers/falff/falff_base.py +20 -46
- junifer/markers/falff/falff_parcels.py +56 -27
- junifer/markers/falff/falff_spheres.py +60 -29
- junifer/markers/falff/tests/test_falff_parcels.py +39 -23
- junifer/markers/falff/tests/test_falff_spheres.py +39 -23
- junifer/markers/functional_connectivity/__init__.py +9 -0
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +63 -60
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +45 -32
- junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +49 -36
- junifer/markers/functional_connectivity/functional_connectivity_base.py +71 -70
- junifer/markers/functional_connectivity/functional_connectivity_parcels.py +34 -25
- junifer/markers/functional_connectivity/functional_connectivity_spheres.py +40 -30
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +11 -7
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +27 -7
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +28 -12
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +35 -11
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +36 -62
- junifer/markers/parcel_aggregation.py +47 -61
- junifer/markers/reho/__init__.py +3 -0
- junifer/markers/reho/_afni_reho.py +5 -2
- junifer/markers/reho/_junifer_reho.py +4 -1
- junifer/markers/reho/reho_base.py +8 -27
- junifer/markers/reho/reho_parcels.py +28 -17
- junifer/markers/reho/reho_spheres.py +27 -18
- junifer/markers/reho/tests/test_reho_parcels.py +8 -3
- junifer/markers/reho/tests/test_reho_spheres.py +8 -3
- junifer/markers/sphere_aggregation.py +43 -59
- junifer/markers/temporal_snr/__init__.py +3 -0
- junifer/markers/temporal_snr/temporal_snr_base.py +23 -32
- junifer/markers/temporal_snr/temporal_snr_parcels.py +9 -6
- junifer/markers/temporal_snr/temporal_snr_spheres.py +9 -6
- junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +6 -3
- junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +6 -3
- junifer/markers/tests/test_brainprint.py +58 -0
- junifer/markers/tests/test_collection.py +9 -8
- junifer/markers/tests/test_ets_rss.py +15 -9
- junifer/markers/tests/test_markers_base.py +17 -18
- junifer/markers/tests/test_parcel_aggregation.py +93 -32
- junifer/markers/tests/test_sphere_aggregation.py +72 -19
- junifer/onthefly/__init__.py +4 -1
- junifer/onthefly/read_transform.py +3 -0
- junifer/pipeline/__init__.py +9 -1
- junifer/pipeline/pipeline_step_mixin.py +21 -4
- junifer/pipeline/registry.py +3 -0
- junifer/pipeline/singleton.py +3 -0
- junifer/pipeline/tests/test_registry.py +1 -1
- junifer/pipeline/update_meta_mixin.py +3 -0
- junifer/pipeline/utils.py +67 -1
- junifer/pipeline/workdir_manager.py +3 -0
- junifer/preprocess/__init__.py +10 -2
- junifer/preprocess/base.py +6 -3
- junifer/preprocess/confounds/__init__.py +3 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +47 -60
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +72 -113
- junifer/preprocess/smoothing/__init__.py +9 -0
- junifer/preprocess/smoothing/_afni_smoothing.py +119 -0
- junifer/preprocess/smoothing/_fsl_smoothing.py +116 -0
- junifer/preprocess/smoothing/_nilearn_smoothing.py +69 -0
- junifer/preprocess/smoothing/smoothing.py +174 -0
- junifer/preprocess/smoothing/tests/test_smoothing.py +94 -0
- junifer/preprocess/warping/__init__.py +3 -0
- junifer/preprocess/warping/_ants_warper.py +3 -0
- junifer/preprocess/warping/_fsl_warper.py +3 -0
- junifer/stats.py +4 -1
- junifer/storage/__init__.py +9 -1
- junifer/storage/base.py +40 -1
- junifer/storage/hdf5.py +71 -9
- junifer/storage/pandas_base.py +3 -0
- junifer/storage/sqlite.py +3 -0
- junifer/storage/tests/test_hdf5.py +82 -10
- junifer/storage/utils.py +9 -0
- junifer/testing/__init__.py +4 -1
- junifer/testing/datagrabbers.py +13 -6
- junifer/testing/tests/test_partlycloudytesting_datagrabber.py +7 -7
- junifer/testing/utils.py +3 -0
- junifer/utils/__init__.py +13 -2
- junifer/utils/fs.py +3 -0
- junifer/utils/helpers.py +32 -1
- junifer/utils/logging.py +33 -4
- junifer/utils/tests/test_logging.py +8 -0
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/METADATA +17 -16
- junifer-0.0.5.dist-info/RECORD +275 -0
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/WHEEL +1 -1
- junifer/datagrabber/tests/test_datagrabber_utils.py +0 -218
- junifer/datagrabber/utils.py +0 -230
- junifer/preprocess/ants/__init__.py +0 -4
- junifer/preprocess/ants/ants_apply_transforms_warper.py +0 -185
- junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +0 -56
- junifer/preprocess/bold_warper.py +0 -265
- junifer/preprocess/fsl/__init__.py +0 -4
- junifer/preprocess/fsl/apply_warper.py +0 -179
- junifer/preprocess/fsl/tests/test_apply_warper.py +0 -45
- junifer/preprocess/tests/test_bold_warper.py +0 -159
- junifer-0.0.4.dev831.dist-info/RECORD +0 -257
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/top_level.txt +0 -0
@@ -12,11 +12,11 @@ import pytest
|
|
12
12
|
from junifer.api.queue_context import HTCondorAdapter
|
13
13
|
|
14
14
|
|
15
|
-
def
|
15
|
+
def test_HTCondorAdapter_env_kind_error() -> None:
|
16
16
|
"""Test error for invalid env kind."""
|
17
17
|
with pytest.raises(ValueError, match="Invalid value for `env.kind`"):
|
18
18
|
HTCondorAdapter(
|
19
|
-
job_name="
|
19
|
+
job_name="check_env_kind",
|
20
20
|
job_dir=Path("."),
|
21
21
|
yaml_config_path=Path("."),
|
22
22
|
elements=["sub01"],
|
@@ -24,6 +24,18 @@ def test_HTCondorAdapter_env_error() -> None:
|
|
24
24
|
)
|
25
25
|
|
26
26
|
|
27
|
+
def test_HTCondorAdapter_env_shell_error() -> None:
|
28
|
+
"""Test error for invalid env shell."""
|
29
|
+
with pytest.raises(ValueError, match="Invalid value for `env.shell`"):
|
30
|
+
HTCondorAdapter(
|
31
|
+
job_name="check_env_shell",
|
32
|
+
job_dir=Path("."),
|
33
|
+
yaml_config_path=Path("."),
|
34
|
+
elements=["sub01"],
|
35
|
+
env={"kind": "conda", "shell": "fish"},
|
36
|
+
)
|
37
|
+
|
38
|
+
|
27
39
|
def test_HTCondorAdapter_collect_error() -> None:
|
28
40
|
"""Test error for invalid collect option."""
|
29
41
|
with pytest.raises(ValueError, match="Invalid value for `collect`"):
|
@@ -37,14 +49,18 @@ def test_HTCondorAdapter_collect_error() -> None:
|
|
37
49
|
|
38
50
|
|
39
51
|
@pytest.mark.parametrize(
|
40
|
-
"pre_run, expected_text",
|
52
|
+
"pre_run, expected_text, shell",
|
41
53
|
[
|
42
|
-
(None, "# Force datalad"),
|
43
|
-
("#
|
54
|
+
(None, "# Force datalad", "bash"),
|
55
|
+
(None, "# Force datalad", "zsh"),
|
56
|
+
("# Check this out\n", "# Check this out", "bash"),
|
57
|
+
("# Check this out\n", "# Check this out", "zsh"),
|
44
58
|
],
|
45
59
|
)
|
46
60
|
def test_HTCondorAdapter_pre_run(
|
47
|
-
pre_run: Optional[str],
|
61
|
+
pre_run: Optional[str],
|
62
|
+
expected_text: str,
|
63
|
+
shell: str,
|
48
64
|
) -> None:
|
49
65
|
"""Test HTCondorAdapter pre_run().
|
50
66
|
|
@@ -54,6 +70,8 @@ def test_HTCondorAdapter_pre_run(
|
|
54
70
|
The parametrized pre run text.
|
55
71
|
expected_text : str
|
56
72
|
The parametrized expected text.
|
73
|
+
shell : str
|
74
|
+
The parametrized expected shell.
|
57
75
|
|
58
76
|
"""
|
59
77
|
adapter = HTCondorAdapter(
|
@@ -61,22 +79,31 @@ def test_HTCondorAdapter_pre_run(
|
|
61
79
|
job_dir=Path("."),
|
62
80
|
yaml_config_path=Path("."),
|
63
81
|
elements=["sub01"],
|
82
|
+
env={"kind": "conda", "name": "junifer", "shell": shell},
|
64
83
|
pre_run=pre_run,
|
65
84
|
)
|
85
|
+
assert shell in adapter.pre_run()
|
66
86
|
assert expected_text in adapter.pre_run()
|
67
87
|
|
68
88
|
|
69
89
|
@pytest.mark.parametrize(
|
70
|
-
"pre_collect, expected_text, collect",
|
90
|
+
"pre_collect, expected_text, collect, shell",
|
71
91
|
[
|
72
|
-
(None, "exit 1", "yes"),
|
73
|
-
(None, "
|
74
|
-
("#
|
75
|
-
("#
|
92
|
+
(None, "exit 1", "yes", "bash"),
|
93
|
+
(None, "exit 1", "yes", "zsh"),
|
94
|
+
(None, "# This script", "on_success_only", "bash"),
|
95
|
+
(None, "# This script", "on_success_only", "zsh"),
|
96
|
+
("# Check this out\n", "# Check this out", "yes", "bash"),
|
97
|
+
("# Check this out\n", "# Check this out", "yes", "zsh"),
|
98
|
+
("# Check this out\n", "# Check this out", "on_success_only", "bash"),
|
99
|
+
("# Check this out\n", "# Check this out", "on_success_only", "zsh"),
|
76
100
|
],
|
77
101
|
)
|
78
102
|
def test_HTCondorAdapter_pre_collect(
|
79
|
-
pre_collect: Optional[str],
|
103
|
+
pre_collect: Optional[str],
|
104
|
+
expected_text: str,
|
105
|
+
collect: str,
|
106
|
+
shell: str,
|
80
107
|
) -> None:
|
81
108
|
"""Test HTCondorAdapter pre_collect().
|
82
109
|
|
@@ -88,6 +115,8 @@ def test_HTCondorAdapter_pre_collect(
|
|
88
115
|
The parametrized expected text.
|
89
116
|
collect : str
|
90
117
|
The parametrized collect parameter.
|
118
|
+
shell : str
|
119
|
+
The parametrized expected shell.
|
91
120
|
|
92
121
|
"""
|
93
122
|
adapter = HTCondorAdapter(
|
@@ -95,9 +124,11 @@ def test_HTCondorAdapter_pre_collect(
|
|
95
124
|
job_dir=Path("."),
|
96
125
|
yaml_config_path=Path("."),
|
97
126
|
elements=["sub01"],
|
127
|
+
env={"kind": "venv", "name": "junifer", "shell": shell},
|
98
128
|
pre_collect=pre_collect,
|
99
129
|
collect=collect,
|
100
130
|
)
|
131
|
+
assert shell in adapter.pre_collect()
|
101
132
|
assert expected_text in adapter.pre_collect()
|
102
133
|
|
103
134
|
|
@@ -177,8 +208,10 @@ def test_HTCondor_dag(
|
|
177
208
|
@pytest.mark.parametrize(
|
178
209
|
"env",
|
179
210
|
[
|
180
|
-
{"kind": "conda", "name": "junifer"},
|
181
|
-
{"kind": "
|
211
|
+
{"kind": "conda", "name": "junifer", "shell": "bash"},
|
212
|
+
{"kind": "conda", "name": "junifer", "shell": "zsh"},
|
213
|
+
{"kind": "venv", "name": "./junifer", "shell": "bash"},
|
214
|
+
{"kind": "venv", "name": "./junifer", "shell": "zsh"},
|
182
215
|
],
|
183
216
|
)
|
184
217
|
def test_HTCondorAdapter_prepare(
|
@@ -215,7 +248,7 @@ def test_HTCondorAdapter_prepare(
|
|
215
248
|
|
216
249
|
assert "Creating HTCondor job" in caplog.text
|
217
250
|
assert "Creating logs directory" in caplog.text
|
218
|
-
assert f"Copying run_{env['kind']}" in caplog.text
|
251
|
+
assert f"Copying run_{env['kind']}.{env['shell']}" in caplog.text
|
219
252
|
assert "Writing pre_run.sh" in caplog.text
|
220
253
|
assert "Writing run_test_prepare.submit" in caplog.text
|
221
254
|
assert "Writing pre_collect.sh" in caplog.text
|
@@ -31,7 +31,7 @@ if [ -d "${var}" ]; then
|
|
31
31
|
done
|
32
32
|
|
33
33
|
echo "Docker args: ${docker_args[*]}" >&2
|
34
|
-
echo "Corrected args for
|
34
|
+
echo "Corrected args for AFNI: ${corrected_args[*]}" >&2
|
35
35
|
|
36
36
|
cwd=$(pwd)
|
37
37
|
cmd="docker run --rm ${docker_args[*]} -v ${cwd}:${cwd} -w ${cwd} afni/afni_make_build ${corrected_args[*]}"
|
@@ -31,7 +31,7 @@ if [ -d "${var}" ]; then
|
|
31
31
|
done
|
32
32
|
|
33
33
|
echo "Docker args: ${docker_args[*]}" >&2
|
34
|
-
echo "Corrected args for
|
34
|
+
echo "Corrected args for ANTs: ${corrected_args[*]}" >&2
|
35
35
|
|
36
36
|
cwd=$(pwd)
|
37
37
|
cmd="docker run --rm ${docker_args[*]} -v ${cwd}:${cwd} -w ${cwd} antsx/ants ${corrected_args[*]}"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
corrected_args=()
|
4
|
+
docker_args=()
|
5
|
+
mounts=0
|
6
|
+
|
7
|
+
FS_LICENSE="${FS_LICENSE:=$HOME/freesurfer_license.txt}"
|
8
|
+
|
9
|
+
if [ -f "${FS_LICENSE}" ]; then
|
10
|
+
>&2 echo "Using freesurfer license from ${FS_LICENSE}"
|
11
|
+
else
|
12
|
+
>&2 echo "Freesurfer license not found at ${FS_LICENSE}. You can either set FS_LICENSE to the path of the license file or place the license file at
|
13
|
+
${FS_LICENSE}"
|
14
|
+
exit 1
|
15
|
+
fi
|
16
|
+
|
17
|
+
# Map the license path to the container by binding
|
18
|
+
license_path=$(realpath "${FS_LICENSE}")
|
19
|
+
license_path_fname=$(basename "${FS_LICENSE}")
|
20
|
+
host_dir=$(dirname "${license_path}")
|
21
|
+
((mounts+=1))
|
22
|
+
container_dir="/data/mount_${mounts}"
|
23
|
+
docker_args+=("-v ${host_dir}:${container_dir}")
|
24
|
+
export DOCKERENV_FS_LICENSE=${container_dir}/${license_path_fname}
|
25
|
+
|
26
|
+
for var in "$@"
|
27
|
+
do
|
28
|
+
if [ -d "${var}" ]; then
|
29
|
+
echo "$var is a directory" >&2
|
30
|
+
var=$(realpath "${var}")
|
31
|
+
host_dir=$(dirname "${var}")
|
32
|
+
((mounts+=1))
|
33
|
+
container_dir="/data/mount_${mounts}"
|
34
|
+
docker_args+=("-v ${host_dir}:${container_dir}")
|
35
|
+
var=${container_dir}
|
36
|
+
elif [ -f "${var}" ] || [[ "${var}" == /* ]]; then
|
37
|
+
if [ -f "${var}" ]; then
|
38
|
+
echo "$var is a file" >&2
|
39
|
+
var=$(realpath "${var}")
|
40
|
+
else
|
41
|
+
echo "$var is a prefix" >&2
|
42
|
+
fi
|
43
|
+
fname=$(basename "${var}")
|
44
|
+
host_dir=$(dirname "${var}")
|
45
|
+
((mounts+=1))
|
46
|
+
container_dir="/data/mount_${mounts}"
|
47
|
+
docker_args+=("-v ${host_dir}:${container_dir}")
|
48
|
+
var=${container_dir}/${fname}
|
49
|
+
fi
|
50
|
+
corrected_args+=("${var}")
|
51
|
+
done
|
52
|
+
|
53
|
+
echo "Docker args: ${docker_args[*]}" >&2
|
54
|
+
echo "Corrected args for FreeSurfer: ${corrected_args[*]}" >&2
|
55
|
+
|
56
|
+
cwd=$(pwd)
|
57
|
+
cmd="docker run --rm ${docker_args[*]} -v ${cwd}:${cwd} -w ${cwd} freesurfer/freesurfer ${corrected_args[*]}"
|
58
|
+
echo "Running command: ${cmd}" >&2
|
59
|
+
${cmd}
|
60
|
+
|
61
|
+
unset DOCKERENV_FS_LICENSE
|
@@ -31,7 +31,7 @@ if [ -d "${var}" ]; then
|
|
31
31
|
done
|
32
32
|
|
33
33
|
echo "Docker args: ${docker_args[*]}" >&2
|
34
|
-
echo "Corrected args for
|
34
|
+
echo "Corrected args for FSL: ${corrected_args[*]}" >&2
|
35
35
|
|
36
36
|
cwd=$(pwd)
|
37
37
|
cmd="docker run --rm ${docker_args[*]} -v ${cwd}:${cwd} -w ${cwd} brainlife/fsl ${corrected_args[*]}"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env zsh
|
2
|
+
|
3
|
+
if [ $# -lt 2 ]; then
|
4
|
+
echo "This script is meant to run a command within a conda environment."
|
5
|
+
echo "It needs at least 2 parameters."
|
6
|
+
echo "The first one must be the environment name."
|
7
|
+
echo "The rest will be the command."
|
8
|
+
exit 255
|
9
|
+
fi
|
10
|
+
|
11
|
+
eval "$(conda shell.zsh hook)"
|
12
|
+
env_name=$1
|
13
|
+
echo "Activating ${env_name}"
|
14
|
+
conda activate "${env_name}"
|
15
|
+
shift 1
|
16
|
+
|
17
|
+
if [ -f "pre_run.sh" ]; then
|
18
|
+
echo "Sourcing pre_run.sh"
|
19
|
+
. ./pre_run.sh
|
20
|
+
fi
|
21
|
+
|
22
|
+
echo "Running ${*} in conda environment"
|
23
|
+
"$@"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
if [ $# -lt 2 ]; then
|
4
|
+
echo "This script is meant to run a command within a Python virtual environment."
|
5
|
+
echo "It needs at least 2 parameters."
|
6
|
+
echo "The first one must be the virtualenv path."
|
7
|
+
echo "The rest will be the command."
|
8
|
+
exit 255
|
9
|
+
fi
|
10
|
+
|
11
|
+
env_path=$1
|
12
|
+
echo "Activating ${env_path}"
|
13
|
+
source "${env_path}"/bin/activate
|
14
|
+
shift 1
|
15
|
+
|
16
|
+
if [ -f "pre_run.sh" ]; then
|
17
|
+
echo "Sourcing pre_run.sh"
|
18
|
+
. ./pre_run.sh
|
19
|
+
fi
|
20
|
+
|
21
|
+
echo "Running ${*} in Python virtual environment"
|
22
|
+
"$@"
|
@@ -4,6 +4,7 @@
|
|
4
4
|
# License: AGPL
|
5
5
|
|
6
6
|
import platform as pl
|
7
|
+
import sys
|
7
8
|
|
8
9
|
import pytest
|
9
10
|
|
@@ -45,11 +46,11 @@ def test_get_dependency_information_short() -> None:
|
|
45
46
|
"httpx",
|
46
47
|
"tqdm",
|
47
48
|
"templateflow",
|
49
|
+
"lapy",
|
48
50
|
"looseversion",
|
49
51
|
]
|
50
52
|
|
51
|
-
|
52
|
-
if python_minor_version < 10:
|
53
|
+
if sys.version_info < (3, 11):
|
53
54
|
dependency_list.append("importlib_metadata")
|
54
55
|
|
55
56
|
assert frozenset(dependency_information.keys()) == frozenset(
|
@@ -74,6 +75,7 @@ def test_get_dependency_information_long() -> None:
|
|
74
75
|
"httpx",
|
75
76
|
"tqdm",
|
76
77
|
"templateflow",
|
78
|
+
"lapy",
|
77
79
|
]
|
78
80
|
for key in dependency_list:
|
79
81
|
assert key in dependency_information_keys
|
junifer/api/tests/test_cli.py
CHANGED
@@ -14,6 +14,7 @@ from ruamel.yaml import YAML
|
|
14
14
|
from junifer.api.cli import (
|
15
15
|
_parse_elements_file,
|
16
16
|
collect,
|
17
|
+
list_elements,
|
17
18
|
queue,
|
18
19
|
reset,
|
19
20
|
run,
|
@@ -297,6 +298,88 @@ def test_reset(
|
|
297
298
|
assert reset_result.exit_code == 0
|
298
299
|
|
299
300
|
|
301
|
+
@pytest.mark.parametrize(
|
302
|
+
"elements",
|
303
|
+
[
|
304
|
+
("sub-01", "sub-02"),
|
305
|
+
("sub-03", "sub-04"),
|
306
|
+
],
|
307
|
+
)
|
308
|
+
def test_list_elements_stdout(
|
309
|
+
elements: Tuple[str, ...],
|
310
|
+
) -> None:
|
311
|
+
"""Test elements listing to stdout.
|
312
|
+
|
313
|
+
Parameters
|
314
|
+
----------
|
315
|
+
elements : tuple of str
|
316
|
+
The parametrized elements for filtering.
|
317
|
+
|
318
|
+
"""
|
319
|
+
# Get test config
|
320
|
+
infile = Path(__file__).parent / "data" / "partly_cloudy_agg_mean_tian.yml"
|
321
|
+
# List elements command arguments
|
322
|
+
list_elements_args = [
|
323
|
+
str(infile.absolute()),
|
324
|
+
"--verbose",
|
325
|
+
"debug",
|
326
|
+
"--element",
|
327
|
+
elements[0],
|
328
|
+
"--element",
|
329
|
+
elements[1],
|
330
|
+
]
|
331
|
+
# Invoke list elements command
|
332
|
+
list_elements_result = runner.invoke(list_elements, list_elements_args)
|
333
|
+
# Check
|
334
|
+
assert list_elements_result.exit_code == 0
|
335
|
+
assert f"{elements[0]}\n{elements[1]}" in list_elements_result.stdout
|
336
|
+
|
337
|
+
|
338
|
+
@pytest.mark.parametrize(
|
339
|
+
"elements",
|
340
|
+
[
|
341
|
+
("sub-01", "sub-02"),
|
342
|
+
("sub-03", "sub-04"),
|
343
|
+
],
|
344
|
+
)
|
345
|
+
def test_list_elements_output_file(
|
346
|
+
tmp_path: Path,
|
347
|
+
elements: Tuple[str, ...],
|
348
|
+
) -> None:
|
349
|
+
"""Test elements listing to output file.
|
350
|
+
|
351
|
+
Parameters
|
352
|
+
----------
|
353
|
+
tmp_path : pathlib.Path
|
354
|
+
The path to the test directory.
|
355
|
+
elements : tuple of str
|
356
|
+
The parametrized elements for filtering.
|
357
|
+
|
358
|
+
"""
|
359
|
+
# Get test config
|
360
|
+
infile = Path(__file__).parent / "data" / "partly_cloudy_agg_mean_tian.yml"
|
361
|
+
# Output file
|
362
|
+
output_file = tmp_path / "elements.txt"
|
363
|
+
# List elements command arguments
|
364
|
+
list_elements_args = [
|
365
|
+
str(infile.absolute()),
|
366
|
+
"--verbose",
|
367
|
+
"debug",
|
368
|
+
"--element",
|
369
|
+
elements[0],
|
370
|
+
"--element",
|
371
|
+
elements[1],
|
372
|
+
"--output-file",
|
373
|
+
str(output_file.resolve()),
|
374
|
+
]
|
375
|
+
# Invoke list elements command
|
376
|
+
list_elements_result = runner.invoke(list_elements, list_elements_args)
|
377
|
+
# Check
|
378
|
+
assert list_elements_result.exit_code == 0
|
379
|
+
with open(output_file) as f:
|
380
|
+
assert f"{elements[0]}\n{elements[1]}" == f.read()
|
381
|
+
|
382
|
+
|
300
383
|
def test_wtf_short() -> None:
|
301
384
|
"""Test short version of wtf command."""
|
302
385
|
# Invoke wtf command
|
@@ -7,13 +7,13 @@
|
|
7
7
|
|
8
8
|
import logging
|
9
9
|
from pathlib import Path
|
10
|
-
from typing import Dict, List, Tuple, Union
|
10
|
+
from typing import Dict, List, Optional, Tuple, Union
|
11
11
|
|
12
12
|
import pytest
|
13
13
|
from ruamel.yaml import YAML
|
14
14
|
|
15
15
|
import junifer.testing.registry # noqa: F401
|
16
|
-
from junifer.api.functions import collect, queue, reset, run
|
16
|
+
from junifer.api.functions import collect, list_elements, queue, reset, run
|
17
17
|
from junifer.datagrabber.base import BaseDataGrabber
|
18
18
|
from junifer.pipeline.registry import build
|
19
19
|
|
@@ -637,3 +637,28 @@ def test_reset_queue(
|
|
637
637
|
|
638
638
|
assert not Path(storage["uri"]).exists()
|
639
639
|
assert not (tmp_path / "junifer_jobs" / job_name).exists()
|
640
|
+
|
641
|
+
|
642
|
+
@pytest.mark.parametrize(
|
643
|
+
"elements",
|
644
|
+
[
|
645
|
+
["sub-01"],
|
646
|
+
None,
|
647
|
+
],
|
648
|
+
)
|
649
|
+
def test_list_elements(
|
650
|
+
datagrabber: Dict[str, str],
|
651
|
+
elements: Optional[List[str]],
|
652
|
+
) -> None:
|
653
|
+
"""Test elements listing.
|
654
|
+
|
655
|
+
Parameters
|
656
|
+
----------
|
657
|
+
datagrabber : dict
|
658
|
+
Testing datagrabber as dictionary.
|
659
|
+
elements : str of list of str
|
660
|
+
The parametrized elements for filtering.
|
661
|
+
|
662
|
+
"""
|
663
|
+
listed_elements = list_elements(datagrabber, elements)
|
664
|
+
assert "sub-01" in listed_elements
|
junifer/configs/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""Custom DataGrabbers for FZJ INM-7's beloved juseless."""
|
2
2
|
|
3
3
|
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
4
|
# Leonard Sasse <l.sasse@fz-juelich.de>
|
@@ -10,3 +10,12 @@ from .camcan_vbm import JuselessDataladCamCANVBM
|
|
10
10
|
from .ixi_vbm import JuselessDataladIXIVBM
|
11
11
|
from .ucla import JuselessUCLA
|
12
12
|
from .ukb_vbm import JuselessDataladUKBVBM
|
13
|
+
|
14
|
+
|
15
|
+
__all__ = [
|
16
|
+
"JuselessDataladAOMICID1000VBM",
|
17
|
+
"JuselessDataladCamCANVBM",
|
18
|
+
"JuselessDataladIXIVBM",
|
19
|
+
"JuselessUCLA",
|
20
|
+
"JuselessDataladUKBVBM",
|
21
|
+
]
|
@@ -11,6 +11,9 @@ from ....api.decorators import register_datagrabber
|
|
11
11
|
from ....datagrabber import PatternDataladDataGrabber
|
12
12
|
|
13
13
|
|
14
|
+
__all__ = ["JuselessDataladAOMICID1000VBM"]
|
15
|
+
|
16
|
+
|
14
17
|
@register_datagrabber
|
15
18
|
class JuselessDataladAOMICID1000VBM(PatternDataladDataGrabber):
|
16
19
|
"""Concrete implementation for Juseless AOMIC ID1000 VBM data fetching.
|
@@ -32,9 +35,7 @@ class JuselessDataladAOMICID1000VBM(PatternDataladDataGrabber):
|
|
32
35
|
replacements = ["subject"]
|
33
36
|
patterns = {
|
34
37
|
"VBM_GM": {
|
35
|
-
"pattern": (
|
36
|
-
"{subject}/mri/mwp1{subject}_run-2_T1w.nii.gz"
|
37
|
-
),
|
38
|
+
"pattern": ("{subject}/mri/mwp1{subject}_run-2_T1w.nii.gz"),
|
38
39
|
"space": "IXI549Space",
|
39
40
|
},
|
40
41
|
}
|
@@ -12,6 +12,9 @@ from ....api.decorators import register_datagrabber
|
|
12
12
|
from ....datagrabber import PatternDataladDataGrabber
|
13
13
|
|
14
14
|
|
15
|
+
__all__ = ["JuselessDataladCamCANVBM"]
|
16
|
+
|
17
|
+
|
15
18
|
@register_datagrabber
|
16
19
|
class JuselessDataladCamCANVBM(PatternDataladDataGrabber):
|
17
20
|
"""Concrete implementation for Juseless CamCAN VBM data fetching.
|
@@ -13,6 +13,9 @@ from ....datagrabber import PatternDataladDataGrabber
|
|
13
13
|
from ....utils import raise_error
|
14
14
|
|
15
15
|
|
16
|
+
__all__ = ["JuselessDataladIXIVBM"]
|
17
|
+
|
18
|
+
|
16
19
|
@register_datagrabber
|
17
20
|
class JuselessDataladIXIVBM(PatternDataladDataGrabber):
|
18
21
|
"""Concrete implementation for Juseless IXI VBM data fetching.
|
@@ -44,9 +47,7 @@ class JuselessDataladIXIVBM(PatternDataladDataGrabber):
|
|
44
47
|
replacements = ["site", "subject"]
|
45
48
|
patterns = {
|
46
49
|
"VBM_GM": {
|
47
|
-
"pattern": (
|
48
|
-
"{site}/{subject}/mri/m0wp1{subject}.nii.gz"
|
49
|
-
),
|
50
|
+
"pattern": ("{site}/{subject}/mri/m0wp1{subject}.nii.gz"),
|
50
51
|
"space": "IXI549Space",
|
51
52
|
},
|
52
53
|
}
|
@@ -27,7 +27,6 @@ def test_JuselessUCLA() -> None:
|
|
27
27
|
|
28
28
|
types = [
|
29
29
|
"BOLD",
|
30
|
-
"BOLD_confounds",
|
31
30
|
"T1w",
|
32
31
|
"VBM_CSF",
|
33
32
|
"VBM_GM",
|
@@ -43,12 +42,11 @@ def test_JuselessUCLA() -> None:
|
|
43
42
|
"types",
|
44
43
|
[
|
45
44
|
"BOLD",
|
46
|
-
"BOLD_confounds",
|
47
45
|
"T1w",
|
48
46
|
"VBM_CSF",
|
49
47
|
"VBM_GM",
|
50
48
|
"VBM_WM",
|
51
|
-
["BOLD", "
|
49
|
+
["BOLD", "VBM_CSF"],
|
52
50
|
["T1w", "VBM_CSF"],
|
53
51
|
["VBM_GM", "VBM_WM"],
|
54
52
|
["BOLD", "T1w"],
|
@@ -12,6 +12,9 @@ from ....datagrabber import PatternDataGrabber
|
|
12
12
|
from ....utils import raise_error
|
13
13
|
|
14
14
|
|
15
|
+
__all__ = ["JuselessUCLA"]
|
16
|
+
|
17
|
+
|
15
18
|
@register_datagrabber
|
16
19
|
class JuselessUCLA(PatternDataGrabber):
|
17
20
|
"""Concrete implementation for Juseless UCLA data fetching.
|
@@ -23,8 +26,8 @@ class JuselessUCLA(PatternDataGrabber):
|
|
23
26
|
datadir : str or Path, optional
|
24
27
|
The directory where the dataset is stored.
|
25
28
|
(default "/data/project/psychosis_thalamus/data/fmriprep").
|
26
|
-
types: {"BOLD", "
|
27
|
-
|
29
|
+
types: {"BOLD", "T1w", "VBM_CSF", "VBM_GM", "VBM_WM"} or \
|
30
|
+
list of the options, optional
|
28
31
|
UCLA data types. If None, all available data types are selected.
|
29
32
|
(default None).
|
30
33
|
tasks : {"rest", "bart", "bht", "pamenc", "pamret", \
|
@@ -76,13 +79,13 @@ class JuselessUCLA(PatternDataGrabber):
|
|
76
79
|
"MNI152NLin2009cAsym_preproc.nii.gz"
|
77
80
|
),
|
78
81
|
"space": "MNI152NLin2009cAsym",
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
"confounds": {
|
83
|
+
"pattern": (
|
84
|
+
"{subject}/func/{subject}_"
|
85
|
+
"task-{task}_bold_confounds.tsv"
|
86
|
+
),
|
87
|
+
"space": "fmriprep",
|
88
|
+
},
|
86
89
|
},
|
87
90
|
"T1w": {
|
88
91
|
"pattern": (
|
@@ -12,6 +12,9 @@ from ....api.decorators import register_datagrabber
|
|
12
12
|
from ....datagrabber import PatternDataladDataGrabber
|
13
13
|
|
14
14
|
|
15
|
+
__all__ = ["JuselessDataladUKBVBM"]
|
16
|
+
|
17
|
+
|
15
18
|
@register_datagrabber
|
16
19
|
class JuselessDataladUKBVBM(PatternDataladDataGrabber):
|
17
20
|
"""Concrete implementation for Juseless UKB VBM data fetching.
|