junifer 0.0.5.dev62__py3-none-any.whl → 0.0.5.dev68__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 CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.0.5.dev62'
16
- __version_tuple__ = version_tuple = (0, 0, 5, 'dev62')
15
+ __version__ = version = '0.0.5.dev68'
16
+ __version_tuple__ = version_tuple = (0, 0, 5, 'dev68')
junifer/api/cli.py CHANGED
@@ -588,3 +588,29 @@ def ants_docker() -> None: # pragma: no cover
588
588
  export PATH="$PATH:{ants_wrappers_path}"
589
589
  """
590
590
  click.secho(msg, fg="blue")
591
+
592
+
593
+ @setup.command("freesurfer-docker")
594
+ def freesurfer_docker() -> None: # pragma: no cover
595
+ """Configure FreeSurfer-Docker wrappers."""
596
+ import junifer
597
+
598
+ pkg_path = Path(junifer.__path__[0]) # type: ignore
599
+ fs_wrappers_path = pkg_path / "api" / "res" / "freesurfer"
600
+ msg = f"""
601
+ Installation instructions for FreeSurfer-Docker wrappers:
602
+
603
+ 1. Install Docker: https://docs.docker.com/get-docker/
604
+
605
+ 2. Get the FreeSurfer-Docker image by running this on the command line:
606
+
607
+ docker pull freesurfer/freesurfer
608
+
609
+ 3. Get license from: https://surfer.nmr.mgh.harvard.edu/registration.html .
610
+ You can skip this step if you already have one.
611
+
612
+ 4. Add this line to the ~/.bashrc or ~/.zshrc file:
613
+
614
+ export PATH="$PATH:{fs_wrappers_path}"
615
+ """
616
+ click.secho(msg, fg="blue")
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ run_freesurfer_docker.sh mri_binarize "$@"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ run_freesurfer_docker.sh mri_mc "$@"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ run_freesurfer_docker.sh mri_pretess "$@"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ run_freesurfer_docker.sh mris_convert "$@"
@@ -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
junifer/pipeline/utils.py CHANGED
@@ -37,7 +37,7 @@ def check_ext_dependencies(
37
37
  If ``name`` is mandatory and is not found.
38
38
 
39
39
  """
40
- valid_ext_dependencies = ("afni", "fsl", "ants")
40
+ valid_ext_dependencies = ("afni", "fsl", "ants", "freesurfer")
41
41
  if name not in valid_ext_dependencies:
42
42
  raise_error(
43
43
  "Invalid value for `name`, should be one of: "
@@ -52,6 +52,9 @@ def check_ext_dependencies(
52
52
  # Check for ants
53
53
  elif name == "ants":
54
54
  found = _check_ants(**kwargs)
55
+ # Check for freesurfer
56
+ elif name == "freesurfer":
57
+ found = _check_freesurfer(**kwargs)
55
58
 
56
59
  # Check if the dependency is mandatory in case it's not found
57
60
  if not found and not optional:
@@ -245,3 +248,63 @@ def _check_ants(commands: Optional[List[str]] = None) -> bool:
245
248
  f"{commands_found_results}"
246
249
  )
247
250
  return ants_found
251
+
252
+
253
+ def _check_freesurfer(commands: Optional[List[str]] = None) -> bool:
254
+ """Check if FreeSurfer is present in the system.
255
+
256
+ Parameters
257
+ ----------
258
+ commands : list of str, optional
259
+ The commands to specifically check for from FreeSurfer. If None, only
260
+ the basic FreeSurfer help would be looked up, else, would also
261
+ check for specific commands (default None).
262
+
263
+ Returns
264
+ -------
265
+ bool
266
+ Whether FreeSurfer is found or not.
267
+
268
+ """
269
+ completed_process = subprocess.run(
270
+ "recon-all -help",
271
+ stdin=subprocess.DEVNULL,
272
+ stdout=subprocess.DEVNULL,
273
+ stderr=subprocess.STDOUT,
274
+ shell=True, # is unsafe but kept for resolution via PATH
275
+ check=False,
276
+ )
277
+ fs_found = completed_process.returncode == 0
278
+
279
+ # Check for specific commands
280
+ if fs_found and commands is not None:
281
+ if not isinstance(commands, list):
282
+ commands = [commands]
283
+ # Store command found results
284
+ commands_found_results = {}
285
+ # Set all commands found flag to True
286
+ all_commands_found = True
287
+ # Check commands' existence
288
+ for command in commands:
289
+ command_process = subprocess.run(
290
+ [command],
291
+ stdin=subprocess.DEVNULL,
292
+ stdout=subprocess.DEVNULL,
293
+ stderr=subprocess.STDOUT,
294
+ shell=True, # is unsafe but kept for resolution via PATH
295
+ check=False,
296
+ )
297
+ command_found = command_process.returncode == 0
298
+ commands_found_results[command] = (
299
+ "found" if command_found else "not found"
300
+ )
301
+ # Set flag to trigger warning
302
+ all_commands_found = all_commands_found and command_found
303
+ # One or more commands were missing
304
+ if not all_commands_found:
305
+ warn_with_log(
306
+ "FreeSurfer is installed but some of the required commands "
307
+ "were not found. These are the results: "
308
+ f"{commands_found_results}"
309
+ )
310
+ return fs_found
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: junifer
3
- Version: 0.0.5.dev62
3
+ Version: 0.0.5.dev68
4
4
  Summary: JUelich NeuroImaging FEature extractoR
5
5
  Author-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  Maintainer-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
@@ -1,8 +1,8 @@
1
1
  junifer/__init__.py,sha256=x1UR2jUcrUdm2HNl-3Qvyi4UUrU6ms5qm2qcmNY7zZk,391
2
- junifer/_version.py,sha256=hgHhCEpD3JpS1CgIK8NxTVb-Oy5VWX6RF9_cs92ZylU,426
2
+ junifer/_version.py,sha256=PBqSCqCS6ZvtB0pHoCsVMEJ5SO6mMY2-aeQleSYHyog,426
3
3
  junifer/stats.py,sha256=jN22_qFvWYBU9ZIMnCSzN4iOscWnWrcrUPIdLeDkV64,6163
4
4
  junifer/api/__init__.py,sha256=pSj8V8tmwOAQ3sshWJfRfB-n3z5bcJj3pHOBX4-8ONc,251
5
- junifer/api/cli.py,sha256=wtU7Rv9tDIT-4KQAkG6WxiE6mop3cuz6XxGDewceHPs,15329
5
+ junifer/api/cli.py,sha256=53pews3mXkJ7DUDSkV51PbitYnuVAdQRkWG-gjO08Uw,16142
6
6
  junifer/api/decorators.py,sha256=8bnwHPAe7VgzKxl--M_e0umdAlTVSzaJQHEJZ5kof5k,2580
7
7
  junifer/api/functions.py,sha256=zCWLXDZ_cAqRZ5bFeky0KeqBztuoa6L3-djI65tqtpY,13055
8
8
  junifer/api/parser.py,sha256=a3SSC2xO-PF1pqXZXFq8Sh9aVd-dmHolJbCkGyOUTAM,4416
@@ -26,6 +26,11 @@ junifer/api/res/ants/ResampleImage,sha256=oJKZ31rBAW20ETozB8Ub5SbXMuhmZfrerpJTnR
26
26
  junifer/api/res/ants/antsApplyTransforms,sha256=SqlQEJ2RMMw_qGyDaNTXKzQqO7Bvrm6y5SEPmyqHiYc,57
27
27
  junifer/api/res/ants/antsApplyTransformsToPoints,sha256=lqyvQGo8oI-RNpNlRqz-BvLHh7Th5HQgsDZjHF6nEeI,65
28
28
  junifer/api/res/ants/run_ants_docker.sh,sha256=d6lZ9CCPP3nsCALhW4T4tI67gyUSiM4AuXj5JPKTLtA,1119
29
+ junifer/api/res/freesurfer/mri_binarize,sha256=d6tjwyOTvLxaMcmUMaeYdR6gE0aI0Bj7ITnDLO3eNdk,56
30
+ junifer/api/res/freesurfer/mri_mc,sha256=sTVbj27M_rjs1RIj6dyp_OTSN4ZB3Q_7f2A5z-ri1QA,50
31
+ junifer/api/res/freesurfer/mri_pretess,sha256=BxhyeD8M3jxIpA_1i6sMAHcsaBQQtvfPu2i1u_nGFBg,55
32
+ junifer/api/res/freesurfer/mris_convert,sha256=7r6L2nQlBNUMJwtsRiIicU_LvKi5GQ9pQUkbDP__p_Q,56
33
+ junifer/api/res/freesurfer/run_freesurfer_docker.sh,sha256=zn6fa0lNAMx3KNZqLcjUYhabpCmcqSETBtqqiqiRQAY,1848
29
34
  junifer/api/res/fsl/applywarp,sha256=DBgHfsn1yXWq0t-P7J0YvrjjJNgiblwDsh9L1hF9v_w,46
30
35
  junifer/api/res/fsl/flirt,sha256=tSjiUco8ui8AbHD7mTzChEwbR0Rf_4iJTgzYTPF_WuQ,42
31
36
  junifer/api/res/fsl/img2imgcoord,sha256=Zmaw3oJYrEltcXiPyEubXry9ppAq3SND52tdDWGgeZk,49
@@ -196,7 +201,7 @@ junifer/pipeline/pipeline_step_mixin.py,sha256=kU0Wut_chlT-iTUb8NP72c7YEoHAECbp7
196
201
  junifer/pipeline/registry.py,sha256=12tRsFeDz_kj9D1nzy9SAkBpchu5IyRH7U2h7eqPDZA,4260
197
202
  junifer/pipeline/singleton.py,sha256=-BiiyFiEO1EItztBcAWI_eyApR-oJTAGVRXkV706rQ4,985
198
203
  junifer/pipeline/update_meta_mixin.py,sha256=WJhLdeIZQ3BjiEcPJM01wlH70ZNj0z5ZS2FfRTJG5oo,1532
199
- junifer/pipeline/utils.py,sha256=qlDUPOFfAq53EDtyHK-klliUwgQBiFDsFghAJO2iHUQ,8039
204
+ junifer/pipeline/utils.py,sha256=70LPMyitmr4d1IiboajI6mo6zPQg6oolYWJIvenYtnA,10252
200
205
  junifer/pipeline/workdir_manager.py,sha256=s2I1I4vjxxqAVAT12ZrZx9KW0WxNMtxRTozB4Xcnh9M,8019
201
206
  junifer/pipeline/tests/test_pipeline_step_mixin.py,sha256=_ykZzyNzREXy-r_yv1gY_jquLZzVBl8qwYrVORCKY_k,7807
202
207
  junifer/pipeline/tests/test_registry.py,sha256=rYN0pO3gSueQ6XsasEM9VU5BkLyaNl8WaCZiaO8Rno0,4105
@@ -248,10 +253,10 @@ junifer/utils/logging.py,sha256=furcU3XIUpUvnpe4PEwzWWIWgmH4j2ZA4MQdvSGWjj0,9216
248
253
  junifer/utils/tests/test_fs.py,sha256=WQS7cKlKEZ742CIuiOYYpueeAhY9PqlastfDVpVVtvE,923
249
254
  junifer/utils/tests/test_helpers.py,sha256=k5qqfxK8dFyuewTJyR1Qn6-nFaYNuVr0ysc18bfPjyU,929
250
255
  junifer/utils/tests/test_logging.py,sha256=l8oo-AiBV7H6_IzlsNcj__cLeZBUvgIGoaMszD9VaJg,7754
251
- junifer-0.0.5.dev62.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
252
- junifer-0.0.5.dev62.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
253
- junifer-0.0.5.dev62.dist-info/METADATA,sha256=iK9h-P28t4ysBf_C97-FNWO5jaU8uFIFE6nyEN5aiiw,8234
254
- junifer-0.0.5.dev62.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
255
- junifer-0.0.5.dev62.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
256
- junifer-0.0.5.dev62.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
257
- junifer-0.0.5.dev62.dist-info/RECORD,,
256
+ junifer-0.0.5.dev68.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
257
+ junifer-0.0.5.dev68.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
258
+ junifer-0.0.5.dev68.dist-info/METADATA,sha256=2B8FVputNlxRR-ehtPjaLIxf9zzOnQh0UqDe-sbTndI,8234
259
+ junifer-0.0.5.dev68.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
260
+ junifer-0.0.5.dev68.dist-info/entry_points.txt,sha256=DxFvKq0pOqRunAK0FxwJcoDfV1-dZvsFDpD5HRqSDhw,48
261
+ junifer-0.0.5.dev68.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
262
+ junifer-0.0.5.dev68.dist-info/RECORD,,