junifer 0.0.3.dev188__py3-none-any.whl → 0.0.4__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/_version.py +14 -2
- junifer/api/cli.py +162 -17
- junifer/api/functions.py +87 -419
- junifer/api/parser.py +24 -0
- junifer/api/queue_context/__init__.py +8 -0
- junifer/api/queue_context/gnu_parallel_local_adapter.py +258 -0
- junifer/api/queue_context/htcondor_adapter.py +365 -0
- junifer/api/queue_context/queue_context_adapter.py +60 -0
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +192 -0
- junifer/api/queue_context/tests/test_htcondor_adapter.py +257 -0
- junifer/api/res/afni/run_afni_docker.sh +6 -6
- junifer/api/res/ants/ResampleImage +3 -0
- junifer/api/res/ants/antsApplyTransforms +3 -0
- junifer/api/res/ants/antsApplyTransformsToPoints +3 -0
- junifer/api/res/ants/run_ants_docker.sh +39 -0
- junifer/api/res/fsl/applywarp +3 -0
- junifer/api/res/fsl/flirt +3 -0
- junifer/api/res/fsl/img2imgcoord +3 -0
- junifer/api/res/fsl/run_fsl_docker.sh +39 -0
- junifer/api/res/fsl/std2imgcoord +3 -0
- junifer/api/res/run_conda.sh +4 -4
- junifer/api/res/run_venv.sh +22 -0
- junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
- junifer/api/tests/test_api_utils.py +21 -3
- junifer/api/tests/test_cli.py +232 -9
- junifer/api/tests/test_functions.py +211 -439
- junifer/api/tests/test_parser.py +1 -1
- junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/camcan_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +8 -8
- junifer/configs/juseless/datagrabbers/ucla.py +44 -26
- junifer/configs/juseless/datagrabbers/ukb_vbm.py +6 -1
- junifer/data/VOIs/meta/AutobiographicalMemory_VOIs.txt +23 -0
- junifer/data/VOIs/meta/Power2013_MNI_VOIs.tsv +264 -0
- junifer/data/__init__.py +4 -0
- junifer/data/coordinates.py +298 -31
- junifer/data/masks.py +360 -28
- junifer/data/parcellations.py +621 -188
- junifer/data/template_spaces.py +190 -0
- junifer/data/tests/test_coordinates.py +34 -3
- junifer/data/tests/test_data_utils.py +1 -0
- junifer/data/tests/test_masks.py +202 -86
- junifer/data/tests/test_parcellations.py +266 -55
- junifer/data/tests/test_template_spaces.py +104 -0
- junifer/data/utils.py +4 -2
- junifer/datagrabber/__init__.py +1 -0
- junifer/datagrabber/aomic/id1000.py +111 -70
- junifer/datagrabber/aomic/piop1.py +116 -53
- junifer/datagrabber/aomic/piop2.py +116 -53
- junifer/datagrabber/aomic/tests/test_id1000.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop1.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop2.py +27 -27
- junifer/datagrabber/base.py +62 -10
- junifer/datagrabber/datalad_base.py +0 -2
- junifer/datagrabber/dmcc13_benchmark.py +372 -0
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +5 -0
- junifer/datagrabber/hcp1200/hcp1200.py +30 -13
- junifer/datagrabber/pattern.py +133 -27
- junifer/datagrabber/pattern_datalad.py +111 -13
- junifer/datagrabber/tests/test_base.py +57 -6
- junifer/datagrabber/tests/test_datagrabber_utils.py +204 -76
- junifer/datagrabber/tests/test_datalad_base.py +0 -6
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +256 -0
- junifer/datagrabber/tests/test_multiple.py +43 -10
- junifer/datagrabber/tests/test_pattern.py +125 -178
- junifer/datagrabber/tests/test_pattern_datalad.py +44 -25
- junifer/datagrabber/utils.py +151 -16
- junifer/datareader/default.py +36 -10
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +6 -0
- junifer/markers/base.py +25 -16
- junifer/markers/collection.py +35 -16
- junifer/markers/complexity/__init__.py +27 -0
- junifer/markers/complexity/complexity_base.py +149 -0
- junifer/markers/complexity/hurst_exponent.py +136 -0
- junifer/markers/complexity/multiscale_entropy_auc.py +140 -0
- junifer/markers/complexity/perm_entropy.py +132 -0
- junifer/markers/complexity/range_entropy.py +136 -0
- junifer/markers/complexity/range_entropy_auc.py +145 -0
- junifer/markers/complexity/sample_entropy.py +134 -0
- junifer/markers/complexity/tests/test_complexity_base.py +19 -0
- junifer/markers/complexity/tests/test_hurst_exponent.py +69 -0
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +68 -0
- junifer/markers/complexity/tests/test_perm_entropy.py +68 -0
- junifer/markers/complexity/tests/test_range_entropy.py +69 -0
- junifer/markers/complexity/tests/test_range_entropy_auc.py +69 -0
- junifer/markers/complexity/tests/test_sample_entropy.py +68 -0
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +68 -0
- junifer/markers/complexity/weighted_perm_entropy.py +133 -0
- junifer/markers/falff/_afni_falff.py +153 -0
- junifer/markers/falff/_junifer_falff.py +142 -0
- junifer/markers/falff/falff_base.py +91 -84
- junifer/markers/falff/falff_parcels.py +61 -45
- junifer/markers/falff/falff_spheres.py +64 -48
- junifer/markers/falff/tests/test_falff_parcels.py +89 -121
- junifer/markers/falff/tests/test_falff_spheres.py +92 -127
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +1 -0
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -0
- junifer/markers/functional_connectivity/functional_connectivity_base.py +1 -0
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -44
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -39
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -52
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -70
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -85
- junifer/markers/parcel_aggregation.py +60 -38
- junifer/markers/reho/_afni_reho.py +192 -0
- junifer/markers/reho/_junifer_reho.py +281 -0
- junifer/markers/reho/reho_base.py +69 -34
- junifer/markers/reho/reho_parcels.py +26 -16
- junifer/markers/reho/reho_spheres.py +23 -9
- junifer/markers/reho/tests/test_reho_parcels.py +93 -92
- junifer/markers/reho/tests/test_reho_spheres.py +88 -86
- junifer/markers/sphere_aggregation.py +54 -9
- junifer/markers/temporal_snr/temporal_snr_base.py +1 -0
- junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +38 -37
- junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +34 -38
- junifer/markers/tests/test_collection.py +43 -42
- junifer/markers/tests/test_ets_rss.py +29 -37
- junifer/markers/tests/test_parcel_aggregation.py +587 -468
- junifer/markers/tests/test_sphere_aggregation.py +209 -157
- junifer/markers/utils.py +2 -40
- junifer/onthefly/read_transform.py +13 -6
- junifer/pipeline/__init__.py +1 -0
- junifer/pipeline/pipeline_step_mixin.py +105 -41
- junifer/pipeline/registry.py +17 -0
- junifer/pipeline/singleton.py +45 -0
- junifer/pipeline/tests/test_pipeline_step_mixin.py +139 -51
- junifer/pipeline/tests/test_update_meta_mixin.py +1 -0
- junifer/pipeline/tests/test_workdir_manager.py +104 -0
- junifer/pipeline/update_meta_mixin.py +8 -2
- junifer/pipeline/utils.py +154 -15
- junifer/pipeline/workdir_manager.py +246 -0
- junifer/preprocess/__init__.py +3 -0
- junifer/preprocess/ants/__init__.py +4 -0
- junifer/preprocess/ants/ants_apply_transforms_warper.py +185 -0
- junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +56 -0
- junifer/preprocess/base.py +96 -69
- junifer/preprocess/bold_warper.py +265 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +91 -134
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +106 -111
- junifer/preprocess/fsl/__init__.py +4 -0
- junifer/preprocess/fsl/apply_warper.py +179 -0
- junifer/preprocess/fsl/tests/test_apply_warper.py +45 -0
- junifer/preprocess/tests/test_bold_warper.py +159 -0
- junifer/preprocess/tests/test_preprocess_base.py +6 -6
- junifer/preprocess/warping/__init__.py +6 -0
- junifer/preprocess/warping/_ants_warper.py +167 -0
- junifer/preprocess/warping/_fsl_warper.py +109 -0
- junifer/preprocess/warping/space_warper.py +213 -0
- junifer/preprocess/warping/tests/test_space_warper.py +198 -0
- junifer/stats.py +18 -4
- junifer/storage/base.py +9 -1
- junifer/storage/hdf5.py +8 -3
- junifer/storage/pandas_base.py +2 -1
- junifer/storage/sqlite.py +1 -0
- junifer/storage/tests/test_hdf5.py +2 -1
- junifer/storage/tests/test_sqlite.py +8 -8
- junifer/storage/tests/test_utils.py +6 -6
- junifer/storage/utils.py +1 -0
- junifer/testing/datagrabbers.py +11 -7
- junifer/testing/utils.py +1 -0
- junifer/tests/test_stats.py +2 -0
- junifer/utils/__init__.py +1 -0
- junifer/utils/helpers.py +53 -0
- junifer/utils/logging.py +14 -3
- junifer/utils/tests/test_helpers.py +35 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/METADATA +59 -28
- junifer-0.0.4.dist-info/RECORD +257 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/WHEEL +1 -1
- junifer/markers/falff/falff_estimator.py +0 -334
- junifer/markers/falff/tests/test_falff_estimator.py +0 -238
- junifer/markers/reho/reho_estimator.py +0 -515
- junifer/markers/reho/tests/test_reho_estimator.py +0 -260
- junifer-0.0.3.dev188.dist-info/RECORD +0 -199
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/top_level.txt +0 -0
junifer/_version.py
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
# file generated by setuptools_scm
|
2
2
|
# don't change, don't track in version control
|
3
|
-
|
4
|
-
|
3
|
+
TYPE_CHECKING = False
|
4
|
+
if TYPE_CHECKING:
|
5
|
+
from typing import Tuple, Union
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
7
|
+
else:
|
8
|
+
VERSION_TUPLE = object
|
9
|
+
|
10
|
+
version: str
|
11
|
+
__version__: str
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
13
|
+
version_tuple: VERSION_TUPLE
|
14
|
+
|
15
|
+
__version__ = version = '0.0.4'
|
16
|
+
__version_tuple__ = version_tuple = (0, 0, 4)
|
junifer/api/cli.py
CHANGED
@@ -8,9 +8,10 @@ import pathlib
|
|
8
8
|
import subprocess
|
9
9
|
import sys
|
10
10
|
from pathlib import Path
|
11
|
-
from typing import Dict, List, Union
|
11
|
+
from typing import Dict, List, Tuple, Union
|
12
12
|
|
13
13
|
import click
|
14
|
+
import pandas as pd
|
14
15
|
|
15
16
|
from ..utils.logging import (
|
16
17
|
configure_logging,
|
@@ -20,6 +21,7 @@ from ..utils.logging import (
|
|
20
21
|
)
|
21
22
|
from .functions import collect as api_collect
|
22
23
|
from .functions import queue as api_queue
|
24
|
+
from .functions import reset as api_reset
|
23
25
|
from .functions import run as api_run
|
24
26
|
from .parser import parse_yaml
|
25
27
|
from .utils import (
|
@@ -32,27 +34,45 @@ from .utils import (
|
|
32
34
|
)
|
33
35
|
|
34
36
|
|
35
|
-
def _parse_elements(element: str, config: Dict) -> Union[List, None]:
|
37
|
+
def _parse_elements(element: Tuple[str], config: Dict) -> Union[List, None]:
|
36
38
|
"""Parse elements from cli.
|
37
39
|
|
38
40
|
Parameters
|
39
41
|
----------
|
40
|
-
element : str
|
41
|
-
The element to operate on.
|
42
|
+
element : tuple of str
|
43
|
+
The element(s) to operate on.
|
42
44
|
config : dict
|
43
45
|
The configuration to operate using.
|
44
46
|
|
45
47
|
Returns
|
46
48
|
-------
|
47
|
-
list
|
48
|
-
The element(s) as list.
|
49
|
+
list or None
|
50
|
+
The element(s) as list or None.
|
51
|
+
|
52
|
+
Raises
|
53
|
+
------
|
54
|
+
ValueError
|
55
|
+
If no element is found either in the command-line options or
|
56
|
+
the configuration file.
|
57
|
+
|
58
|
+
Warns
|
59
|
+
-----
|
60
|
+
RuntimeWarning
|
61
|
+
If elements are specified both via the command-line options and
|
62
|
+
the configuration file.
|
49
63
|
|
50
64
|
"""
|
51
65
|
logger.debug(f"Parsing elements: {element}")
|
66
|
+
# Early return None to continue with all elements
|
52
67
|
if len(element) == 0:
|
53
68
|
return None
|
54
|
-
#
|
55
|
-
|
69
|
+
# Check if the element is a file for single element;
|
70
|
+
# if yes, then parse elements from it
|
71
|
+
if len(element) == 1 and Path(element[0]).resolve().is_file():
|
72
|
+
elements = _parse_elements_file(Path(element[0]).resolve())
|
73
|
+
else:
|
74
|
+
# Process multi-keyed elements
|
75
|
+
elements = [tuple(x.split(",")) if "," in x else x for x in element]
|
56
76
|
logger.debug(f"Parsed elements: {elements}")
|
57
77
|
if elements is not None and "elements" in config:
|
58
78
|
warn_with_log(
|
@@ -61,19 +81,48 @@ def _parse_elements(element: str, config: Dict) -> Union[List, None]:
|
|
61
81
|
"over the configuration file. That is, the elements specified "
|
62
82
|
"in the command line will be used. The elements specified in "
|
63
83
|
"the configuration file will be ignored. To remove this warning, "
|
64
|
-
|
84
|
+
"please remove the `elements` item from the configuration file."
|
65
85
|
)
|
66
86
|
elif elements is None:
|
87
|
+
# Check in config
|
67
88
|
elements = config.get("elements", None)
|
68
89
|
if elements is None:
|
69
90
|
raise_error(
|
70
|
-
"The
|
71
|
-
" is
|
91
|
+
"The `elements` key is set in the configuration, but its value"
|
92
|
+
" is `None`. It is likely that there is an empty `elements` "
|
72
93
|
"section in the yaml configuration file."
|
73
94
|
)
|
74
95
|
return elements
|
75
96
|
|
76
97
|
|
98
|
+
def _parse_elements_file(filepath: Path) -> List[Tuple[str, ...]]:
|
99
|
+
"""Parse elements from file.
|
100
|
+
|
101
|
+
Parameters
|
102
|
+
----------
|
103
|
+
filepath : pathlib.Path
|
104
|
+
The path to the element file.
|
105
|
+
|
106
|
+
Returns
|
107
|
+
-------
|
108
|
+
list of tuple of str
|
109
|
+
The element(s) as list.
|
110
|
+
|
111
|
+
"""
|
112
|
+
# Read CSV into dataframe
|
113
|
+
csv_df = pd.read_csv(
|
114
|
+
filepath,
|
115
|
+
header=None, # no header # type: ignore
|
116
|
+
index_col=False, # no index column
|
117
|
+
dtype=str,
|
118
|
+
skipinitialspace=True, # no leading space after delimiter
|
119
|
+
)
|
120
|
+
# Remove trailing whitespace in cell entries
|
121
|
+
csv_df_trimmed = csv_df.apply(lambda x: x.str.strip())
|
122
|
+
# Convert to list of tuple of str
|
123
|
+
return list(map(tuple, csv_df_trimmed.to_numpy()))
|
124
|
+
|
125
|
+
|
77
126
|
def _validate_verbose(
|
78
127
|
ctx: click.Context, param: str, value: str
|
79
128
|
) -> Union[str, int]:
|
@@ -92,6 +141,7 @@ def _validate_verbose(
|
|
92
141
|
-------
|
93
142
|
str or int
|
94
143
|
The validated value.
|
144
|
+
|
95
145
|
"""
|
96
146
|
if isinstance(value, int):
|
97
147
|
return value
|
@@ -133,7 +183,9 @@ def cli() -> None: # pragma: no cover
|
|
133
183
|
callback=_validate_verbose,
|
134
184
|
default="info",
|
135
185
|
)
|
136
|
-
def run(
|
186
|
+
def run(
|
187
|
+
filepath: click.Path, element: Tuple[str], verbose: Union[str, int]
|
188
|
+
) -> None:
|
137
189
|
"""Run command for CLI.
|
138
190
|
|
139
191
|
\f
|
@@ -142,20 +194,30 @@ def run(filepath: click.Path, element: str, verbose: Union[str, int]) -> None:
|
|
142
194
|
----------
|
143
195
|
filepath : click.Path
|
144
196
|
The filepath to the configuration file.
|
145
|
-
element : str
|
146
|
-
The element to operate
|
197
|
+
element : tuple of str
|
198
|
+
The element to operate on.
|
147
199
|
verbose : click.Choice
|
148
200
|
The verbosity level: warning, info or debug (default "info").
|
149
201
|
|
150
202
|
"""
|
151
203
|
configure_logging(level=verbose)
|
152
|
-
# TODO: add validation
|
204
|
+
# TODO(synchon): add validation
|
205
|
+
# Parse YAML
|
153
206
|
config = parse_yaml(filepath) # type: ignore
|
207
|
+
# Retrieve working directory
|
154
208
|
workdir = config["workdir"]
|
209
|
+
# Fetch datagrabber
|
155
210
|
datagrabber = config["datagrabber"]
|
211
|
+
# Fetch markers
|
156
212
|
markers = config["markers"]
|
213
|
+
# Fetch storage
|
157
214
|
storage = config["storage"]
|
158
|
-
|
215
|
+
# Fetch preprocessors
|
216
|
+
preprocessors = config.get("preprocess")
|
217
|
+
# Convert to list if single preprocessor
|
218
|
+
if preprocessors is not None and not isinstance(preprocessors, list):
|
219
|
+
preprocessors = [preprocessors]
|
220
|
+
# Parse elements
|
159
221
|
elements = _parse_elements(element, config)
|
160
222
|
# Perform operation
|
161
223
|
api_run(
|
@@ -163,7 +225,7 @@ def run(filepath: click.Path, element: str, verbose: Union[str, int]) -> None:
|
|
163
225
|
datagrabber=datagrabber,
|
164
226
|
markers=markers,
|
165
227
|
storage=storage,
|
166
|
-
|
228
|
+
preprocessors=preprocessors,
|
167
229
|
elements=elements,
|
168
230
|
)
|
169
231
|
|
@@ -352,6 +414,43 @@ def selftest(subpkg: str) -> None:
|
|
352
414
|
click.secho("Failure.", fg="red")
|
353
415
|
|
354
416
|
|
417
|
+
@cli.command()
|
418
|
+
@click.argument(
|
419
|
+
"filepath",
|
420
|
+
type=click.Path(
|
421
|
+
exists=True, readable=True, dir_okay=False, path_type=pathlib.Path
|
422
|
+
),
|
423
|
+
)
|
424
|
+
@click.option(
|
425
|
+
"-v",
|
426
|
+
"--verbose",
|
427
|
+
type=click.UNPROCESSED,
|
428
|
+
callback=_validate_verbose,
|
429
|
+
default="info",
|
430
|
+
)
|
431
|
+
def reset(
|
432
|
+
filepath: click.Path,
|
433
|
+
verbose: Union[str, int],
|
434
|
+
) -> None:
|
435
|
+
"""Reset command for CLI.
|
436
|
+
|
437
|
+
\f
|
438
|
+
|
439
|
+
Parameters
|
440
|
+
----------
|
441
|
+
filepath : click.Path
|
442
|
+
The filepath to the configuration file.
|
443
|
+
verbose : click.Choice
|
444
|
+
The verbosity level: warning, info or debug (default "info").
|
445
|
+
|
446
|
+
"""
|
447
|
+
configure_logging(level=verbose)
|
448
|
+
# Parse YAML
|
449
|
+
config = parse_yaml(filepath)
|
450
|
+
# Perform operation
|
451
|
+
api_reset(config)
|
452
|
+
|
453
|
+
|
355
454
|
@cli.group()
|
356
455
|
def setup() -> None: # pragma: no cover
|
357
456
|
"""Configure commands for Junifer."""
|
@@ -379,3 +478,49 @@ def afni_docker() -> None: # pragma: no cover
|
|
379
478
|
export PATH="$PATH:{afni_wrappers_path}"
|
380
479
|
"""
|
381
480
|
click.secho(msg, fg="blue")
|
481
|
+
|
482
|
+
|
483
|
+
@setup.command("fsl-docker")
|
484
|
+
def fsl_docker() -> None: # pragma: no cover
|
485
|
+
"""Configure FSL-Docker wrappers."""
|
486
|
+
import junifer
|
487
|
+
|
488
|
+
pkg_path = Path(junifer.__path__[0]) # type: ignore
|
489
|
+
fsl_wrappers_path = pkg_path / "api" / "res" / "fsl"
|
490
|
+
msg = f"""
|
491
|
+
Installation instructions for FSL-Docker wrappers:
|
492
|
+
|
493
|
+
1. Install Docker: https://docs.docker.com/get-docker/
|
494
|
+
|
495
|
+
2. Get the FSL-Docker image by running this on the command line:
|
496
|
+
|
497
|
+
docker pull brainlife/fsl
|
498
|
+
|
499
|
+
3. Add this line to the ~/.bashrc or ~/.zshrc file:
|
500
|
+
|
501
|
+
export PATH="$PATH:{fsl_wrappers_path}"
|
502
|
+
"""
|
503
|
+
click.secho(msg, fg="blue")
|
504
|
+
|
505
|
+
|
506
|
+
@setup.command("ants-docker")
|
507
|
+
def ants_docker() -> None: # pragma: no cover
|
508
|
+
"""Configure ANTs-Docker wrappers."""
|
509
|
+
import junifer
|
510
|
+
|
511
|
+
pkg_path = Path(junifer.__path__[0]) # type: ignore
|
512
|
+
ants_wrappers_path = pkg_path / "api" / "res" / "ants"
|
513
|
+
msg = f"""
|
514
|
+
Installation instructions for ANTs-Docker wrappers:
|
515
|
+
|
516
|
+
1. Install Docker: https://docs.docker.com/get-docker/
|
517
|
+
|
518
|
+
2. Get the ANTs-Docker image by running this on the command line:
|
519
|
+
|
520
|
+
docker pull antsx/ants
|
521
|
+
|
522
|
+
3. Add this line to the ~/.bashrc or ~/.zshrc file:
|
523
|
+
|
524
|
+
export PATH="$PATH:{ants_wrappers_path}"
|
525
|
+
"""
|
526
|
+
click.secho(msg, fg="blue")
|