oceanproc 1.3.2__tar.gz → 1.3.4__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.2 → oceanproc-1.3.4}/PKG-INFO +1 -1
  2. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/bids_wrapper.py +23 -18
  3. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/group_series.py +1 -1
  4. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/ocean_proc.py +15 -13
  5. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/preprocessing_wrapper.py +56 -41
  6. {oceanproc-1.3.2 → oceanproc-1.3.4}/pyproject.toml +1 -1
  7. {oceanproc-1.3.2 → oceanproc-1.3.4}/README.md +0 -0
  8. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/__init__.py +0 -0
  9. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/events_long.py +0 -0
  10. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/firstlevel/__init__.py +0 -0
  11. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/firstlevel/run_glm.py +0 -0
  12. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/firstlevel/tests/__init__.py +0 -0
  13. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/firstlevel/tests/test_run_glm.py +0 -0
  14. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/grouplevel/__init__.py +0 -0
  15. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/grouplevel/computations.py +0 -0
  16. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/grouplevel/design_mat_utils.py +0 -0
  17. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/grouplevel/dscalar_utils.py +0 -0
  18. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/grouplevel/utils.py +0 -0
  19. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/oceanparse.py +0 -0
  20. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/segmentation_wrapper.py +0 -0
  21. {oceanproc-1.3.2 → oceanproc-1.3.4}/oceanproc/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oceanproc
3
- Version: 1.3.2
3
+ Version: 1.3.4
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
@@ -74,7 +74,8 @@ def run_dcm2bids(subject:str,
74
74
  bids_output_dir:Path,
75
75
  config_file:Path,
76
76
  nordic_config:Path = None,
77
- skip_validate:bool = False):
77
+ skip_validate:bool = False,
78
+ keep_part_files: bool = False):
78
79
  """
79
80
  Run dcm2bids with a given set of parameters.
80
81
 
@@ -128,11 +129,12 @@ def run_dcm2bids(subject:str,
128
129
  run_subprocess(nordic_run_command, title=title)
129
130
 
130
131
  # Clean up NORDIC files
131
- separate_nordic_files = bids_output_dir.glob(f"sub-{subject}/ses-{session}/func/*_part-*")
132
- logger.debug("removing the old nordic files that are not needed after mag-phase combination :")
133
- for f in separate_nordic_files:
134
- logger.debug(f"deleting file: {f}")
135
- os.remove(f)
132
+ if not keep_part_files:
133
+ separate_nordic_files = bids_output_dir.glob(f"sub-{subject}/ses-{session}/func/*_part-*")
134
+ logger.debug("removing the old nordic files that are not needed after mag-phase combination :")
135
+ for f in separate_nordic_files:
136
+ logger.debug(f"deleting file: {f}")
137
+ os.remove(f)
136
138
 
137
139
  except (Exception, KeyboardInterrupt) as e:
138
140
  prepare_subprocess_logging(logger, stop=True)
@@ -141,6 +143,7 @@ def run_dcm2bids(subject:str,
141
143
 
142
144
  return True
143
145
 
146
+
144
147
  @debug_logging
145
148
  def run_dcm2niix(source_dir:Path,
146
149
  tmp_nifti_dir:Path):
@@ -178,7 +181,7 @@ def run_dcm2niix(source_dir:Path,
178
181
  prepare_subprocess_logging(logger, stop=True)
179
182
  logger.exception(e, stack_info=True)
180
183
  return False
181
-
184
+
182
185
  return True
183
186
 
184
187
 
@@ -271,7 +274,7 @@ def extend_session(subject:str,
271
274
  continue
272
275
  run_nums = [f.entities['run'] for f in similar_files if 'run' in f.entities]
273
276
  max_bids_run = 1 if len(run_nums) == 0 else int(max(run_nums))
274
- tmp_ent['run'] = f"{(max_bids_run+tmp_run_num):02d}"
277
+ tmp_ent['run'] = f"{(max_bids_run + tmp_run_num):02d}"
275
278
  tmp_new_path = bids_layout.build_path(tmp_ent)
276
279
  logger.info(f"moving file: {tmp_file.path} to: {tmp_new_path}")
277
280
  shutil.move(tmp_file.path, tmp_new_path)
@@ -297,7 +300,8 @@ def dicom_to_bids(subject:str,
297
300
  skip_validate:bool = False,
298
301
  skip_prompt:bool = False,
299
302
  session_index:int = 0,
300
- keep_all_niftis:bool = False):
303
+ keep_all_niftis:bool = False,
304
+ keep_part_files:bool = False):
301
305
  """
302
306
  Facilitates the conversion of DICOM data into NIFTI data in BIDS format, and the removal of data marked 'unusable'.
303
307
 
@@ -350,7 +354,7 @@ def dicom_to_bids(subject:str,
350
354
  nii_success = run_dcm2niix(source_dir=source_dir,
351
355
  tmp_nifti_dir=tmp_nifti_path)
352
356
  else:
353
- # copy current niftis to tmp_nifti_path
357
+ # copy current niftis to tmp_nifti_path
354
358
  logger.info(f"copying the source NIFTI files to tmp directory, {tmp_nifti_path}")
355
359
  shutil.copytree(source_dir.resolve(), tmp_nifti_path.resolve())
356
360
 
@@ -361,7 +365,7 @@ def dicom_to_bids(subject:str,
361
365
  recursive=True,
362
366
  group=flags.permissions_group
363
367
  )
364
-
368
+
365
369
  if not nii_success:
366
370
  exit_program_early(f"Problem running 'dcm2niix'")
367
371
 
@@ -408,13 +412,14 @@ def dicom_to_bids(subject:str,
408
412
  session_number=session_index)
409
413
 
410
414
  dcm2bids_success = run_dcm2bids(subject=subject,
411
- session=session,
412
- nifti_dir=tmp_nifti_path,
413
- bids_output_dir=bids_dir,
414
- config_file=bids_config,
415
- nordic_config=nordic_config,
416
- skip_validate=skip_validate)
417
-
415
+ session=session,
416
+ nifti_dir=tmp_nifti_path,
417
+ bids_output_dir=bids_dir,
418
+ config_file=bids_config,
419
+ nordic_config=nordic_config,
420
+ skip_validate=skip_validate,
421
+ keep_part_files=keep_part_files)
422
+
418
423
  update_permissions(
419
424
  permissions=flags.file_permissions,
420
425
  path=sub_ses_bids_dir,
@@ -50,7 +50,7 @@ def get_func_from_bids(bids_layout: BIDSLayout,
50
50
  session:str,
51
51
  groupings: list[dict[str:set]]):
52
52
 
53
- func_files = bids_layout.get(subject=subject, session=session, suffix="bold", datatype="func", extension="nii.gz")
53
+ func_files = bids_layout.get(subject=subject, session=session, suffix="bold", datatype="func", extension=["nii.gz","nii"])
54
54
  if len(func_files) == 0:
55
55
  exit_program_early("Could not find any functional BOLD files for this subject and session.")
56
56
 
@@ -94,7 +94,7 @@ def main():
94
94
 
95
95
  default_user_group = grp.getgrgid(os.getgid()).gr_name
96
96
  default_file_permissions = "771"
97
-
97
+
98
98
  parser = OceanParser(
99
99
  prog="oceanproc",
100
100
  description="Ocean Labs adult MRI preprocessing",
@@ -103,7 +103,7 @@ 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.2')
106
+ parser.add_argument("--version", action="version", version='%(prog)s v1.3.3')
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
109
 
@@ -141,7 +141,7 @@ def main():
141
141
  config_args.add_argument("--derivs_path", "-d", type=ExistingDir, required=True,
142
142
  help="The path to the BIDS formated derivatives directory for this subject")
143
143
  config_args.add_argument("--derivs_subfolder", "-ds", default=None,
144
- help=f"""The subfolder in the derivatives directory where bids style outputs should be stored.
144
+ help=f"""The subfolder in the derivatives directory where bids style outputs should be stored.
145
145
  The default is {adult_defaults.derivs_subfolder} or {infant_defaults.derivs_subfolder} if the '--infant' flag is set.""")
146
146
  config_args.add_argument("--bids_config", "-c", type=ExistingFile, required=True,
147
147
  help="The path to the dcm2bids config file to use for this subject and session")
@@ -159,6 +159,8 @@ def main():
159
159
  help="Specifies skipping BIDS validation (only enabled for fMRIprep step)")
160
160
  config_args.add_argument("--fs_subjects_dir", "--fs-subjects-dir", "-fs", type=ExistingDir, dest="fs_subjects_dir",
161
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.")
162
+ config_args.add_argument("--topup_config", "--topup-config", "-tc", type=ExistingFile, dest="topup_config",
163
+ help="Path to a TOPUP config file.")
162
164
  config_args.add_argument("--allow_uneven_fmap_groups", action="store_true",
163
165
  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.)")
164
166
  config_args.add_argument("--extract_best_fmap", action=argparse.BooleanOptionalAction,
@@ -172,8 +174,10 @@ def main():
172
174
  help="The path to the working directory used to store intermediate files")
173
175
  config_args.add_argument("--fs_license", "--fs-license-file", "-l", type=ExistingFile, dest="fs_license", required=True,
174
176
  help="The path to the license file for the local installation of FreeSurfer")
177
+ config_args.add_argument("--keep_part_files", action=argparse.BooleanOptionalAction,
178
+ help="Don't automatically remove 'part-mag' and 'part-phase' files after running dcm2bids.")
175
179
  config_args.add_argument("--image_version", "-iv", default=None,
176
- help=f"""The version of fmriprep to use; It is reccomended that an entire study use the same version.
180
+ help=f"""The version of fmriprep to use; It is reccomended that an entire study use the same version.
177
181
  The default is {adult_defaults.image_version} or {infant_defaults.image_version} if the '--infant' flag is set.""")
178
182
  config_args.add_argument("--infant", "-I", action=argparse.BooleanOptionalAction,
179
183
  help="Flag to specify that NiBabies should be used instead of fMRIPrep")
@@ -233,7 +237,7 @@ def main():
233
237
  if args.debug_mode:
234
238
  flags.debug = True
235
239
  logger.setLevel(logging.DEBUG)
236
-
240
+
237
241
  flags.file_permissions = args.file_permissions
238
242
  flags.permissions_group = args.permissions_group
239
243
  flags.gid = grp.getgrnam(flags.permissions_group).gr_gid
@@ -253,7 +257,6 @@ def main():
253
257
  logger.exception(e)
254
258
  exit_program_early(e)
255
259
 
256
-
257
260
  # log the input arguments
258
261
  for k,v in (dict(args._get_kwargs())).items():
259
262
  logger.info(f" {k} : {v}")
@@ -284,23 +287,24 @@ def main():
284
287
  skip_validate=args.skip_bids_validation,
285
288
  skip_prompt=index > 0,
286
289
  session_index=index,
287
- keep_all_niftis=args.keep_all_niftis
290
+ keep_all_niftis=args.keep_all_niftis,
291
+ keep_part_files=args.keep_part_files
288
292
  )
289
293
  if index > 0:
290
294
  extend_session(subject=args.subject,
291
295
  session=args.session,
292
296
  tmp_dir=bids_path,
293
297
  bids_dir=args.bids_path)
294
-
298
+
295
299
  # create a bids layout object
296
300
  ignore_list = ["tmp_dcm2bids"]
297
301
  if (bids_path / ".bidsignore").is_file():
298
302
  with open(bids_path / ".bidsignore", "r") as f:
299
- ignore_list.extend(f.readlines())
303
+ ignore_list.extend([l.strip() for l in f.readlines()])
300
304
  ignore_list = list(set(ignore_list))
301
305
  other_sub_paths = [
302
- p.name for p in bids_path.glob("sub-*")
303
- if not f"sub-{args.subject}".startswith(p.name) and p.is_dir() # 'startswith' to account for pybids regexifying after the end of subject name
306
+ p.name for p in bids_path.glob("sub-*")
307
+ if not f"sub-{args.subject}".startswith(p.name) and p.is_dir() # 'startswith' to account for pybids regexifying after the end of subject name
304
308
  ]
305
309
  ignore_list.extend(other_sub_paths)
306
310
  bids_layout = BIDSLayout(args.bids_path, validate=False, indexer=BIDSLayoutIndexer(ignore=ignore_list, validate=False))
@@ -352,7 +356,6 @@ def main():
352
356
  if not bibsnet_path.exists():
353
357
  exit_program_early(f"Cannot find the outputs for BIBSnet at the path {bibsnet_path}")
354
358
 
355
-
356
359
  ##### Insert dummy scans in requested #####
357
360
  if args.dscans_path:
358
361
  insert_dummy_frames(
@@ -362,7 +365,6 @@ def main():
362
365
  bids_layout=bids_layout
363
366
  )
364
367
 
365
-
366
368
  ##### Run fMRIPrep or NiBabies #####
367
369
  all_opts = dict(args._get_kwargs())
368
370
 
@@ -32,8 +32,12 @@ infant_defaults = SimpleNamespace(
32
32
  )
33
33
 
34
34
  # Preprocessing arguments that need to have their paths binded when running docker
35
- mount_opts = {"fs_subjects_dir",
36
- "derivatives"}
35
+ mount_opts = {
36
+ "fs_subjects_dir",
37
+ "derivatives",
38
+ "topup_config"
39
+ }
40
+
37
41
 
38
42
  @debug_logging
39
43
  def run_preprocessing(subject:str,
@@ -69,7 +73,15 @@ def run_preprocessing(subject:str,
69
73
  :raise RuntimeError: If preprocessing throws an error, or exits with a non-zero exit code.
70
74
  """
71
75
  def clean_up(): return shutil.rmtree(work_path) if remove_work_folder else None
72
-
76
+
77
+ def make_mount_path(path_to_mount:str|Path, mount_key:int):
78
+ mount_path = f"/deriv{mount_key}"
79
+ path_to_mount = Path(path_to_mount)
80
+ if path_to_mount.is_file():
81
+ suffix = "".join(path_to_mount.suffixes)
82
+ mount_path += suffix
83
+ return mount_path
84
+
73
85
  log_linebreak()
74
86
  logger.info(f"####### Starting {title} #######\n")
75
87
  if not bids_path.exists():
@@ -81,15 +93,15 @@ def run_preprocessing(subject:str,
81
93
  bids_mount = "/data"
82
94
  derivs_mount = "/out"
83
95
  work_mount = "/work"
84
-
96
+
85
97
  if flags.apptainer:
86
98
  cmd_prelude = f"apptainer run --nv --cleanenv --no-mount cwd --pwd {work_mount}"
87
99
  mount_flag = "-B"
88
- else:
100
+ else:
89
101
  cmd_prelude = f"docker run --rm -i -u {flags.uid}:{flags.gid}"
90
102
  import grp
91
103
  mygids = (
92
- grp.getgrnam(groupname).gr_gid for groupname in
104
+ grp.getgrnam(groupname).gr_gid for groupname in
93
105
  subprocess.run('groups', capture_output=True).stdout.decode().strip().split()
94
106
  )
95
107
  for mygid in mygids:
@@ -103,12 +115,14 @@ def run_preprocessing(subject:str,
103
115
  arg_vals = [k]
104
116
  if isinstance(v, list):
105
117
  for sub_v in v:
106
- additional_mount_paths.append(f"{mount_flag} {sub_v.resolve()}:/deriv{mount_dex}")
107
- arg_vals.append(f"/deriv{mount_dex}")
118
+ mount_path = make_mount_path(sub_v, mount_dex)
119
+ additional_mount_paths.append(f"{mount_flag} {sub_v.resolve()}:{mount_path}")
120
+ arg_vals.append(mount_path)
108
121
  mount_dex += 1
109
122
  else:
110
- additional_mount_paths.append(f"{mount_flag} {v.resolve()}:/deriv{mount_dex}")
111
- arg_vals.append(f"/deriv{mount_dex}")
123
+ mount_path = make_mount_path(v, mount_dex)
124
+ additional_mount_paths.append(f"{mount_flag} {v.resolve()}:{mount_path}")
125
+ arg_vals.append(mount_path)
112
126
  mount_dex += 1
113
127
  additional_mount_args.append(" ".join(arg_vals))
114
128
  additional_mount_paths = " ".join(additional_mount_paths)
@@ -126,7 +140,7 @@ def run_preprocessing(subject:str,
126
140
  -w {work_mount} --verbose
127
141
  {additional_mount_args}
128
142
  {option_chain}"""
129
-
143
+
130
144
  success = True
131
145
  try:
132
146
  run_subprocess(preproc_command, title=title)
@@ -140,6 +154,7 @@ def run_preprocessing(subject:str,
140
154
 
141
155
  return success
142
156
 
157
+
143
158
  @debug_logging
144
159
  def add_fd_plot_to_report(subject:str,
145
160
  session:str,
@@ -230,7 +245,7 @@ def add_fd_plot_to_report(subject:str,
230
245
  # Add the new elements into the file
231
246
  logger.debug(f" inserting the new html elements into the {title} report")
232
247
  confounds_plot_div.insert_after(fd_plot_div)
233
- else:
248
+ else:
234
249
  confounds_plot_reference_div = confounds_plot_div.find_next_sibling("div", class_="elem-filename")
235
250
  fd_plot_reference_div = copy.copy(confounds_plot_reference_div)
236
251
  fd_plot_reference_div.a["href"] = "./" + rel_path
@@ -252,9 +267,9 @@ def insert_dummy_frames(subject:str,
252
267
  session:str,
253
268
  dscan_dir:Path,
254
269
  bids_layout:BIDSLayout):
255
-
270
+
256
271
  dscans_suffix = "dscans"
257
- dscans_path_pattern = "sub-{subject}[/ses-{session}]/{datatype<func|meg|beh>|func}/sub-{subject}[_ses-{session}]_task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<"+dscans_suffix+">}{extension<.tsv|.json>|.tsv}"
272
+ dscans_path_pattern = "sub-{subject}[/ses-{session}]/{datatype<func|meg|beh>|func}/sub-{subject}[_ses-{session}]_task-{task}[_acq-{acquisition}][_rec-{reconstruction}][_run-{run}][_echo-{echo}][_recording-{recording}]_{suffix<" + dscans_suffix + ">}{extension<.tsv|.json>|.tsv}"
258
273
 
259
274
  log_linebreak()
260
275
  logger.info(f"####### Inserting Dummy Scans #######\n")
@@ -306,27 +321,27 @@ def insert_dummy_frames(subject:str,
306
321
  frame_list = []
307
322
  dscans_index = 0
308
323
  for f in range(num_bold_frames):
309
- copy_dex = f-1 if f > 0 else f
324
+ copy_dex = f - 1 if f > 0 else f
310
325
  while dscans_list[dscans_index] != 0:
311
326
  frame_list.append(bold_data[:,:,:,copy_dex])
312
327
  dscans_index += 1
313
328
  frame_list.append(bold_data[:,:,:,f])
314
329
  dscans_index += 1
315
330
  # check if end of run needs to be extended
316
- if (f == num_bold_frames-1) and (dscans_index < len(dscans_list)):
331
+ if (f == num_bold_frames - 1) and (dscans_index < len(dscans_list)):
317
332
  while dscans_index < len(dscans_list):
318
333
  frame_list.append(bold_data[:,:,:,f])
319
334
  dscans_index += 1
320
335
 
321
336
  if len(frame_list) != len(dscans_list):
322
337
  exit_program_early(f"Something went wrong when creating dummy scans, lengths do not match. bold frames: {len(frame_list)}, dscan length: {len(dscans_list)}")
323
-
338
+
324
339
  # save new image
325
340
  extended_bold_data = np.stack(frame_list, axis=3)
326
341
  extended_bold_img = bold_img.__class__(extended_bold_data, header=bold_img.header, affine=bold_img.affine)
327
342
  logger.info(f" saving extended bold image")
328
343
  nib.save(extended_bold_img, bfile.path)
329
-
344
+
330
345
 
331
346
  @debug_logging
332
347
  def process_data(subject:str,
@@ -364,23 +379,23 @@ def process_data(subject:str,
364
379
  preproc_title = "NiBabies" if flags.infant else "fMRIPrep"
365
380
 
366
381
  preproc_success = run_preprocessing(subject=subject,
367
- session=session if flags.infant else None,
368
- bids_path=bids_path,
369
- derivs_path=derivs_path,
370
- work_path=work_path,
371
- license_file=license_file,
372
- image_name=image_name,
373
- title=preproc_title,
374
- option_chain=option_chain,
375
- additional_mounts=additional_mounts,
376
- remove_work_folder=remove_work_folder)
377
-
382
+ session=session if flags.infant else None,
383
+ bids_path=bids_path,
384
+ derivs_path=derivs_path,
385
+ work_path=work_path,
386
+ license_file=license_file,
387
+ image_name=image_name,
388
+ title=preproc_title,
389
+ option_chain=option_chain,
390
+ additional_mounts=additional_mounts,
391
+ remove_work_folder=remove_work_folder)
392
+
378
393
  if preproc_success:
379
394
  add_fd_plot_to_report(subject=subject,
380
- session=session,
381
- derivs_path=derivs_path,
382
- title=preproc_title)
383
-
395
+ session=session,
396
+ derivs_path=derivs_path,
397
+ title=preproc_title)
398
+
384
399
  paths_to_update = []
385
400
  paths_to_update.extend(sorted(derivs_path.glob(f"sub-{subject}*")))
386
401
  paths_to_update.extend(sorted(derivs_path.glob(f"sourcedata/*/sub-{subject}*")))
@@ -388,14 +403,14 @@ def process_data(subject:str,
388
403
  if out_path.exists():
389
404
  # update file permissions for preprocessing outputs
390
405
  update_permissions(
391
- permissions=flags.file_permissions,
392
- path=out_path,
406
+ permissions=flags.file_permissions,
407
+ path=out_path,
393
408
  recursive=True,
394
409
  group=flags.permissions_group
395
410
  )
396
-
411
+
397
412
  # check other top-level files
398
- other_paths = [derivs_path/"dataset_description.json", derivs_path/"logs"]
413
+ other_paths = [derivs_path / "dataset_description.json", derivs_path / "logs"]
399
414
  for op in other_paths:
400
415
  if op.exists() and (op.stat().st_uid == flags.uid):
401
416
  update_permissions(
@@ -404,15 +419,15 @@ def process_data(subject:str,
404
419
  recursive=True,
405
420
  group=flags.permissions_group
406
421
  )
407
-
422
+
408
423
  # update file permisions for working directory files
409
424
  update_permissions(
410
- permissions=flags.file_permissions,
411
- path=work_path,
425
+ permissions=flags.file_permissions,
426
+ path=work_path,
412
427
  recursive=True,
413
428
  group=flags.permissions_group,
414
429
  quiet=True
415
430
  )
416
-
431
+
417
432
  if not preproc_success:
418
433
  exit_program_early(f"Program '{preproc_title}' has run into an error.")
@@ -34,7 +34,7 @@ dependencies = [
34
34
  "pybids>=0.16.3",
35
35
  ]
36
36
  name = "oceanproc"
37
- version = "1.3.2"
37
+ version = "1.3.4"
38
38
  description = "MRI preprocessing for WUSTL Ocean labs"
39
39
  readme = "README.md"
40
40
 
File without changes
File without changes