oceanproc 1.3.1__tar.gz → 1.3.3__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.
- {oceanproc-1.3.1 → oceanproc-1.3.3}/PKG-INFO +1 -1
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/ocean_proc.py +7 -5
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/preprocessing_wrapper.py +50 -37
- {oceanproc-1.3.1 → oceanproc-1.3.3}/pyproject.toml +1 -1
- {oceanproc-1.3.1 → oceanproc-1.3.3}/README.md +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/__init__.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/bids_wrapper.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/events_long.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/firstlevel/__init__.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/firstlevel/run_glm.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/firstlevel/tests/__init__.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/firstlevel/tests/test_run_glm.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/group_series.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/grouplevel/__init__.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/grouplevel/computations.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/grouplevel/design_mat_utils.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/grouplevel/dscalar_utils.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/grouplevel/utils.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/oceanparse.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/segmentation_wrapper.py +0 -0
- {oceanproc-1.3.1 → oceanproc-1.3.3}/oceanproc/utils.py +0 -0
|
@@ -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.
|
|
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
|
|
|
@@ -157,11 +157,13 @@ def main():
|
|
|
157
157
|
help="framewise displacement threshold (in mm) to determine outlier framee (Default is 0.9).")
|
|
158
158
|
config_args.add_argument("--skip_bids_validation", action=argparse.BooleanOptionalAction,
|
|
159
159
|
help="Specifies skipping BIDS validation (only enabled for fMRIprep step)")
|
|
160
|
-
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",
|
|
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
|
-
config_args.add_argument("--extract_best_fmap", action=
|
|
166
|
+
config_args.add_argument("--extract_best_fmap", action=argparse.BooleanOptionalAction,
|
|
165
167
|
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)")
|
|
166
168
|
config_args.add_argument("--dscans_path", type=ExistingDir,
|
|
167
169
|
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
|
|
@@ -170,7 +172,7 @@ def main():
|
|
|
170
172
|
help="A list of paths to any BIDS-style precomputed derivatives that should be used in preprocessing. (Ex. /path/to/bibsnet)")
|
|
171
173
|
config_args.add_argument("--work_dir", "-w", type=ExistingDir, required=True,
|
|
172
174
|
help="The path to the working directory used to store intermediate files")
|
|
173
|
-
config_args.add_argument("--fs_license", "-l", type=ExistingFile, required=True,
|
|
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")
|
|
175
177
|
config_args.add_argument("--image_version", "-iv", default=None,
|
|
176
178
|
help=f"""The version of fmriprep to use; It is reccomended that an entire study use the same version.
|
|
@@ -296,7 +298,7 @@ def main():
|
|
|
296
298
|
ignore_list = ["tmp_dcm2bids"]
|
|
297
299
|
if (bids_path / ".bidsignore").is_file():
|
|
298
300
|
with open(bids_path / ".bidsignore", "r") as f:
|
|
299
|
-
ignore_list.extend(f.readlines())
|
|
301
|
+
ignore_list.extend([l.strip() for l in f.readlines()])
|
|
300
302
|
ignore_list = list(set(ignore_list))
|
|
301
303
|
other_sub_paths = [
|
|
302
304
|
p.name for p in bids_path.glob("sub-*")
|
|
@@ -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__)
|
|
@@ -31,8 +32,12 @@ infant_defaults = SimpleNamespace(
|
|
|
31
32
|
)
|
|
32
33
|
|
|
33
34
|
# Preprocessing arguments that need to have their paths binded when running docker
|
|
34
|
-
mount_opts = {
|
|
35
|
-
|
|
35
|
+
mount_opts = {
|
|
36
|
+
"fs_subjects_dir",
|
|
37
|
+
"derivatives",
|
|
38
|
+
"topup_config"
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
|
|
37
42
|
@debug_logging
|
|
38
43
|
def run_preprocessing(subject:str,
|
|
@@ -68,7 +73,7 @@ def run_preprocessing(subject:str,
|
|
|
68
73
|
:raise RuntimeError: If preprocessing throws an error, or exits with a non-zero exit code.
|
|
69
74
|
"""
|
|
70
75
|
def clean_up(): return shutil.rmtree(work_path) if remove_work_folder else None
|
|
71
|
-
|
|
76
|
+
|
|
72
77
|
log_linebreak()
|
|
73
78
|
logger.info(f"####### Starting {title} #######\n")
|
|
74
79
|
if not bids_path.exists():
|
|
@@ -80,12 +85,19 @@ def run_preprocessing(subject:str,
|
|
|
80
85
|
bids_mount = "/data"
|
|
81
86
|
derivs_mount = "/out"
|
|
82
87
|
work_mount = "/work"
|
|
83
|
-
|
|
88
|
+
|
|
84
89
|
if flags.apptainer:
|
|
85
90
|
cmd_prelude = f"apptainer run --nv --cleanenv --no-mount cwd --pwd {work_mount}"
|
|
86
91
|
mount_flag = "-B"
|
|
87
|
-
else:
|
|
92
|
+
else:
|
|
88
93
|
cmd_prelude = f"docker run --rm -i -u {flags.uid}:{flags.gid}"
|
|
94
|
+
import grp
|
|
95
|
+
mygids = (
|
|
96
|
+
grp.getgrnam(groupname).gr_gid for groupname in
|
|
97
|
+
subprocess.run('groups', capture_output=True).stdout.decode().strip().split()
|
|
98
|
+
)
|
|
99
|
+
for mygid in mygids:
|
|
100
|
+
cmd_prelude += f" --group-add {mygid} "
|
|
89
101
|
mount_flag = "-v"
|
|
90
102
|
|
|
91
103
|
additional_mount_paths = []
|
|
@@ -118,7 +130,7 @@ def run_preprocessing(subject:str,
|
|
|
118
130
|
-w {work_mount} --verbose
|
|
119
131
|
{additional_mount_args}
|
|
120
132
|
{option_chain}"""
|
|
121
|
-
|
|
133
|
+
|
|
122
134
|
success = True
|
|
123
135
|
try:
|
|
124
136
|
run_subprocess(preproc_command, title=title)
|
|
@@ -132,6 +144,7 @@ def run_preprocessing(subject:str,
|
|
|
132
144
|
|
|
133
145
|
return success
|
|
134
146
|
|
|
147
|
+
|
|
135
148
|
@debug_logging
|
|
136
149
|
def add_fd_plot_to_report(subject:str,
|
|
137
150
|
session:str,
|
|
@@ -222,7 +235,7 @@ def add_fd_plot_to_report(subject:str,
|
|
|
222
235
|
# Add the new elements into the file
|
|
223
236
|
logger.debug(f" inserting the new html elements into the {title} report")
|
|
224
237
|
confounds_plot_div.insert_after(fd_plot_div)
|
|
225
|
-
else:
|
|
238
|
+
else:
|
|
226
239
|
confounds_plot_reference_div = confounds_plot_div.find_next_sibling("div", class_="elem-filename")
|
|
227
240
|
fd_plot_reference_div = copy.copy(confounds_plot_reference_div)
|
|
228
241
|
fd_plot_reference_div.a["href"] = "./" + rel_path
|
|
@@ -244,9 +257,9 @@ def insert_dummy_frames(subject:str,
|
|
|
244
257
|
session:str,
|
|
245
258
|
dscan_dir:Path,
|
|
246
259
|
bids_layout:BIDSLayout):
|
|
247
|
-
|
|
260
|
+
|
|
248
261
|
dscans_suffix = "dscans"
|
|
249
|
-
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}"
|
|
262
|
+
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}"
|
|
250
263
|
|
|
251
264
|
log_linebreak()
|
|
252
265
|
logger.info(f"####### Inserting Dummy Scans #######\n")
|
|
@@ -298,27 +311,27 @@ def insert_dummy_frames(subject:str,
|
|
|
298
311
|
frame_list = []
|
|
299
312
|
dscans_index = 0
|
|
300
313
|
for f in range(num_bold_frames):
|
|
301
|
-
copy_dex = f-1 if f > 0 else f
|
|
314
|
+
copy_dex = f - 1 if f > 0 else f
|
|
302
315
|
while dscans_list[dscans_index] != 0:
|
|
303
316
|
frame_list.append(bold_data[:,:,:,copy_dex])
|
|
304
317
|
dscans_index += 1
|
|
305
318
|
frame_list.append(bold_data[:,:,:,f])
|
|
306
319
|
dscans_index += 1
|
|
307
320
|
# check if end of run needs to be extended
|
|
308
|
-
if (f == num_bold_frames-1) and (dscans_index < len(dscans_list)):
|
|
321
|
+
if (f == num_bold_frames - 1) and (dscans_index < len(dscans_list)):
|
|
309
322
|
while dscans_index < len(dscans_list):
|
|
310
323
|
frame_list.append(bold_data[:,:,:,f])
|
|
311
324
|
dscans_index += 1
|
|
312
325
|
|
|
313
326
|
if len(frame_list) != len(dscans_list):
|
|
314
327
|
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)}")
|
|
315
|
-
|
|
328
|
+
|
|
316
329
|
# save new image
|
|
317
330
|
extended_bold_data = np.stack(frame_list, axis=3)
|
|
318
331
|
extended_bold_img = bold_img.__class__(extended_bold_data, header=bold_img.header, affine=bold_img.affine)
|
|
319
332
|
logger.info(f" saving extended bold image")
|
|
320
333
|
nib.save(extended_bold_img, bfile.path)
|
|
321
|
-
|
|
334
|
+
|
|
322
335
|
|
|
323
336
|
@debug_logging
|
|
324
337
|
def process_data(subject:str,
|
|
@@ -356,23 +369,23 @@ def process_data(subject:str,
|
|
|
356
369
|
preproc_title = "NiBabies" if flags.infant else "fMRIPrep"
|
|
357
370
|
|
|
358
371
|
preproc_success = run_preprocessing(subject=subject,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
372
|
+
session=session if flags.infant else None,
|
|
373
|
+
bids_path=bids_path,
|
|
374
|
+
derivs_path=derivs_path,
|
|
375
|
+
work_path=work_path,
|
|
376
|
+
license_file=license_file,
|
|
377
|
+
image_name=image_name,
|
|
378
|
+
title=preproc_title,
|
|
379
|
+
option_chain=option_chain,
|
|
380
|
+
additional_mounts=additional_mounts,
|
|
381
|
+
remove_work_folder=remove_work_folder)
|
|
382
|
+
|
|
370
383
|
if preproc_success:
|
|
371
384
|
add_fd_plot_to_report(subject=subject,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
385
|
+
session=session,
|
|
386
|
+
derivs_path=derivs_path,
|
|
387
|
+
title=preproc_title)
|
|
388
|
+
|
|
376
389
|
paths_to_update = []
|
|
377
390
|
paths_to_update.extend(sorted(derivs_path.glob(f"sub-{subject}*")))
|
|
378
391
|
paths_to_update.extend(sorted(derivs_path.glob(f"sourcedata/*/sub-{subject}*")))
|
|
@@ -380,14 +393,14 @@ def process_data(subject:str,
|
|
|
380
393
|
if out_path.exists():
|
|
381
394
|
# update file permissions for preprocessing outputs
|
|
382
395
|
update_permissions(
|
|
383
|
-
permissions=flags.file_permissions,
|
|
384
|
-
path=out_path,
|
|
396
|
+
permissions=flags.file_permissions,
|
|
397
|
+
path=out_path,
|
|
385
398
|
recursive=True,
|
|
386
399
|
group=flags.permissions_group
|
|
387
400
|
)
|
|
388
|
-
|
|
401
|
+
|
|
389
402
|
# check other top-level files
|
|
390
|
-
other_paths = [derivs_path/"dataset_description.json", derivs_path/"logs"]
|
|
403
|
+
other_paths = [derivs_path / "dataset_description.json", derivs_path / "logs"]
|
|
391
404
|
for op in other_paths:
|
|
392
405
|
if op.exists() and (op.stat().st_uid == flags.uid):
|
|
393
406
|
update_permissions(
|
|
@@ -396,15 +409,15 @@ def process_data(subject:str,
|
|
|
396
409
|
recursive=True,
|
|
397
410
|
group=flags.permissions_group
|
|
398
411
|
)
|
|
399
|
-
|
|
412
|
+
|
|
400
413
|
# update file permisions for working directory files
|
|
401
414
|
update_permissions(
|
|
402
|
-
permissions=flags.file_permissions,
|
|
403
|
-
path=work_path,
|
|
415
|
+
permissions=flags.file_permissions,
|
|
416
|
+
path=work_path,
|
|
404
417
|
recursive=True,
|
|
405
418
|
group=flags.permissions_group,
|
|
406
419
|
quiet=True
|
|
407
420
|
)
|
|
408
|
-
|
|
421
|
+
|
|
409
422
|
if not preproc_success:
|
|
410
|
-
exit_program_early(f"Program '{preproc_title}' has run into an error.")
|
|
423
|
+
exit_program_early(f"Program '{preproc_title}' has run into an error.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|