oceanproc 1.3.0__tar.gz → 1.3.2__tar.gz

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.
Files changed (21) hide show
  1. {oceanproc-1.3.0 → oceanproc-1.3.2}/PKG-INFO +1 -1
  2. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/ocean_proc.py +7 -8
  3. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/preprocessing_wrapper.py +17 -8
  4. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/segmentation_wrapper.py +7 -6
  5. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/utils.py +7 -4
  6. {oceanproc-1.3.0 → oceanproc-1.3.2}/pyproject.toml +1 -1
  7. {oceanproc-1.3.0 → oceanproc-1.3.2}/README.md +0 -0
  8. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/__init__.py +0 -0
  9. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/bids_wrapper.py +0 -0
  10. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/events_long.py +0 -0
  11. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/firstlevel/__init__.py +0 -0
  12. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/firstlevel/run_glm.py +0 -0
  13. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/firstlevel/tests/__init__.py +0 -0
  14. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/firstlevel/tests/test_run_glm.py +0 -0
  15. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/group_series.py +0 -0
  16. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/grouplevel/__init__.py +0 -0
  17. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/grouplevel/computations.py +0 -0
  18. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/grouplevel/design_mat_utils.py +0 -0
  19. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/grouplevel/dscalar_utils.py +0 -0
  20. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/grouplevel/utils.py +0 -0
  21. {oceanproc-1.3.0 → oceanproc-1.3.2}/oceanproc/oceanparse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oceanproc
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: MRI preprocessing for WUSTL Ocean labs
5
5
  Author-Email: Ramone Agard <rhagard@wustl.edu>, Joey Scanga <joeyscanga92@gmail.com>
6
6
  Requires-Python: <3.13,>=3.10
@@ -103,10 +103,9 @@ def main():
103
103
  epilog="An arguments file can be accepted with @FILEPATH.\nAny additional arguments not listed in the help message will be passed to the preprocessing subprocess.",
104
104
  allow_abbrev=False
105
105
  )
106
- parser.add_argument("--version", action="version", version='%(prog)s v1.3.0')
106
+ parser.add_argument("--version", action="version", version='%(prog)s v1.3.2')
107
107
  session_args = parser.add_argument_group("Session Specific")
108
108
  config_args = parser.add_argument_group("Configuration Arguments", "These arguments are saved to a file if the '--export_args' option is used")
109
- parser.register("type", "Full-Path", lambda p: Path(p).resolve())
110
109
 
111
110
  session_args.add_argument("--subject", "-su", required=True,
112
111
  help="The identifier of the subject to preprocess")
@@ -158,20 +157,20 @@ def main():
158
157
  help="framewise displacement threshold (in mm) to determine outlier framee (Default is 0.9).")
159
158
  config_args.add_argument("--skip_bids_validation", action=argparse.BooleanOptionalAction,
160
159
  help="Specifies skipping BIDS validation (only enabled for fMRIprep step)")
161
- config_args.add_argument("--fs_subjects_dir", "-fs", type=ExistingDir,
160
+ config_args.add_argument("--fs_subjects_dir", "--fs-subjects-dir", "-fs", type=ExistingDir, dest="fs_subjects_dir",
162
161
  help="The path to the directory that contains previous FreeSurfer outputs/derivatives to use for fMRIPrep. If empty, this is the path where new FreeSurfer outputs will be stored.")
163
162
  config_args.add_argument("--allow_uneven_fmap_groups", action="store_true",
164
163
  help="Flag to allow for automated fieldmap pairing when there's more AP- than PA-encoded fieldmaps, or vice versa (will still error out if at least one of each is not present.)")
165
- config_args.add_argument("--extract_best_fmap", action="store_true",
164
+ config_args.add_argument("--extract_best_fmap", action=argparse.BooleanOptionalAction,
166
165
  help="Flag to specify that the lowest variance fieldmap volume should be extracted from each fieldmap, and used for distortion correction (opposed to all volumes being used)")
167
166
  config_args.add_argument("--dscans_path", type=ExistingDir,
168
167
  help="""The path to the directory containing 'dscans' files for inserting dummy scans into bold runs. Must be named exactly as corresponding bold image except with 'dscans' as
169
168
  the suffix and '.tsv' as the extension. Contents of the file must be a column, titled 'dummy_scan', with ones and zeros. Ones denote which frames should be dummy scans.""")
170
- config_args.add_argument("--precomputed_derivatives", "-pd", type="Full-Path", dest="derivatives", nargs="*",
169
+ config_args.add_argument("--precomputed_derivatives", "-pd", type=ExistingDir, dest="derivatives", nargs="+",
171
170
  help="A list of paths to any BIDS-style precomputed derivatives that should be used in preprocessing. (Ex. /path/to/bibsnet)")
172
171
  config_args.add_argument("--work_dir", "-w", type=ExistingDir, required=True,
173
172
  help="The path to the working directory used to store intermediate files")
174
- config_args.add_argument("--fs_license", "-l", type=ExistingFile, required=True,
173
+ config_args.add_argument("--fs_license", "--fs-license-file", "-l", type=ExistingFile, dest="fs_license", required=True,
175
174
  help="The path to the license file for the local installation of FreeSurfer")
176
175
  config_args.add_argument("--image_version", "-iv", default=None,
177
176
  help=f"""The version of fmriprep to use; It is reccomended that an entire study use the same version.
@@ -185,9 +184,9 @@ def main():
185
184
  config_args.add_argument("--bibsnet_work", "-bw", type=ExistingDir,
186
185
  help="The path to the working directory used to store intermediate files for BIBSnet")
187
186
  config_args.add_argument("--permissions_group", "-g", type=ValidGroup, default=default_user_group,
188
- help=f"The user group that should own all of the created files. (Default is for the current user is '{default_user_group}'")
187
+ help=f"The user group that should own all of the created files. (Default for the current user is '{default_user_group}')")
189
188
  config_args.add_argument("--file_permissions", "-fp", type=ValidPermissions, default=default_file_permissions,
190
- help=f"The file permissions that all output files should have, represented in numeric format. (Default permissions is '{default_file_permissions}'")
189
+ help=f"The file permissions that all output files should have, represented in numeric format. (Default permissions is '{default_file_permissions}')")
191
190
  args, unknown_args = parser.parse_known_args()
192
191
 
193
192
  if args.infant:
@@ -13,6 +13,7 @@ import nibabel as nib
13
13
  import json
14
14
  import os
15
15
  import copy
16
+ import subprocess
16
17
  from types import SimpleNamespace
17
18
 
18
19
  logger = logging.getLogger(__name__)
@@ -86,6 +87,13 @@ def run_preprocessing(subject:str,
86
87
  mount_flag = "-B"
87
88
  else:
88
89
  cmd_prelude = f"docker run --rm -i -u {flags.uid}:{flags.gid}"
90
+ import grp
91
+ mygids = (
92
+ grp.getgrnam(groupname).gr_gid for groupname in
93
+ subprocess.run('groups', capture_output=True).stdout.decode().strip().split()
94
+ )
95
+ for mygid in mygids:
96
+ cmd_prelude += f" --group-add {mygid} "
89
97
  mount_flag = "-v"
90
98
 
91
99
  additional_mount_paths = []
@@ -377,13 +385,14 @@ def process_data(subject:str,
377
385
  paths_to_update.extend(sorted(derivs_path.glob(f"sub-{subject}*")))
378
386
  paths_to_update.extend(sorted(derivs_path.glob(f"sourcedata/*/sub-{subject}*")))
379
387
  for out_path in paths_to_update:
380
- # update file permissions for preprocessing outputs
381
- update_permissions(
382
- permissions=flags.file_permissions,
383
- path=out_path,
384
- recursive=True,
385
- group=flags.permissions_group
386
- )
388
+ if out_path.exists():
389
+ # update file permissions for preprocessing outputs
390
+ update_permissions(
391
+ permissions=flags.file_permissions,
392
+ path=out_path,
393
+ recursive=True,
394
+ group=flags.permissions_group
395
+ )
387
396
 
388
397
  # check other top-level files
389
398
  other_paths = [derivs_path/"dataset_description.json", derivs_path/"logs"]
@@ -406,4 +415,4 @@ def process_data(subject:str,
406
415
  )
407
416
 
408
417
  if not preproc_success:
409
- exit_program_early(f"Program '{preproc_title}' has run into an error.")
418
+ exit_program_early(f"Program '{preproc_title}' has run into an error.")
@@ -128,12 +128,13 @@ def segment_anatomical(subject:str,
128
128
  paths_to_update = sorted(derivs_path.glob(f"bibsnet/sub-{subject}*"))
129
129
  paths_to_update.extend(sorted(work_path.glob(f"*/sub-{subject}*")))
130
130
  for out_path in paths_to_update:
131
- # update file permissions for segmentation outputs and working files
132
- update_permissions(
133
- permissions=flags.file_permissions,
134
- path=out_path,
135
- recursive=True,
136
- group=flags.permissions_group)
131
+ if out_path.exists():
132
+ # update file permissions for segmentation outputs and working files
133
+ update_permissions(
134
+ permissions=flags.file_permissions,
135
+ path=out_path,
136
+ recursive=True,
137
+ group=flags.permissions_group)
137
138
 
138
139
  # check other top-level files
139
140
  other_paths = [derivs_path/"dataset_description.json"]
@@ -239,10 +239,11 @@ def prepare_subprocess_logging(this_logger,
239
239
 
240
240
 
241
241
  @debug_logging
242
- def run_subprocess(cmd: str, title: str, log_output=True):
242
+ def run_subprocess(cmd: str, title: str, log_output=True, quiet=False):
243
243
  split_cmd = shlex.split(cmd)
244
244
  logger.info(f"running '{title}' with the following command: \n{' '.join(split_cmd)}\n")
245
245
  prepare_subprocess_logging(logger)
246
+ ecode = 0
246
247
  with Popen(split_cmd, stdout=PIPE, stderr=PIPE) as p:
247
248
  while p.poll() == None:
248
249
  if log_output:
@@ -251,9 +252,11 @@ def run_subprocess(cmd: str, title: str, log_output=True):
251
252
  for line in p.stderr:
252
253
  logger.info(line.decode("utf-8", "ignore"))
253
254
  prepare_subprocess_logging(logger, stop=True)
255
+ ecode = p.poll()
254
256
  p.kill()
255
- if (ecode:=p.poll()) != 0:
257
+ if (ecode != 0) and (not quiet):
256
258
  raise RuntimeError(f"process -'{title}'- has ended with a non-zero exit code <{ecode}>.")
259
+ return ecode
257
260
 
258
261
 
259
262
  def log_linebreak():
@@ -412,8 +415,8 @@ def update_permissions(permissions:str, path:Path, recursive=False, group=None,
412
415
  raise ValueError(f"Did not receive a valid path: <{path}>")
413
416
 
414
417
  chmod_cmd = f"chmod {'-R' if recursive else ''} {permissions} {path.resolve()}"
415
- run_subprocess(cmd=chmod_cmd, title="chmod", log_output=False)
418
+ run_subprocess(cmd=chmod_cmd, title="chmod", log_output=False, quiet=True)
416
419
 
417
420
  if group is not None:
418
421
  chgrp_cmd = f"chgrp {'-R' if recursive else ''} {group} {path.resolve()}"
419
- run_subprocess(cmd=chgrp_cmd, title="chgrp", log_output=False)
422
+ run_subprocess(cmd=chgrp_cmd, title="chgrp", log_output=False, quiet=True)
@@ -34,7 +34,7 @@ dependencies = [
34
34
  "pybids>=0.16.3",
35
35
  ]
36
36
  name = "oceanproc"
37
- version = "1.3.0"
37
+ version = "1.3.2"
38
38
  description = "MRI preprocessing for WUSTL Ocean labs"
39
39
  readme = "README.md"
40
40
 
File without changes