Skip to content

Commit d670ebd

Browse files
Merge pull request #2 from smoia/fix/lmap-option
Code reorganisation to use lag maps
2 parents 249ff21 + dbf88a4 commit d670ebd

1 file changed

Lines changed: 54 additions & 48 deletions

File tree

phys2cvr/workflows.py

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ def phys2cvr(
311311
f'R^2 model {r2model} not supported. Supported models are {stats.R2MODEL}'
312312
)
313313

314+
LGR.info('Load functional data')
314315
if func_is_1d:
315316
if tr:
316317
func_avg = io.load_array(fname_func)
@@ -345,6 +346,7 @@ def phys2cvr(
345346

346347
# Read mask (and mask func) if provided
347348
if fname_mask:
349+
LGR.info('Load mask to restrict operations on functional data')
348350
_, mask, _ = io.load_nifti_get_mask(fname_mask, is_mask=True)
349351
if func.shape[:3] != mask.shape:
350352
raise ValueError(f'{fname_mask} and {fname_func} have different sizes!')
@@ -364,6 +366,7 @@ def phys2cvr(
364366

365367
# Read roi if provided
366368
if fname_roi:
369+
LGR.info('Load ROI to obtain a reference from functional data')
367370
_, roi, _ = io.load_nifti_get_mask(fname_roi, is_mask=True)
368371
if func.shape[:3] != roi.shape:
369372
raise ValueError(f'{fname_roi} and {fname_func} have different sizes!')
@@ -382,6 +385,7 @@ def phys2cvr(
382385
LGR.info(f'Obtaining filtered average signal in {roiref}')
383386
func_avg = signal.filter_signal(func_avg, tr, lowcut, highcut, butter_order)
384387

388+
LGR.info('Load physiological data')
385389
if fname_co2 is None:
386390
LGR.info(f'Computing "CVR" (approximation) maps using {fname_func} only')
387391
if func_is_1d:
@@ -462,6 +466,39 @@ def phys2cvr(
462466
else:
463467
petco2hrf = co2
464468

469+
# If the user provided a lag map, read it and extract information from it
470+
if lag_map:
471+
LGR.info('Load lag map')
472+
lag, _, _ = io.load_nifti_get_mask(lag_map)
473+
if func.shape[:3] != lag.shape:
474+
raise ValueError(f'{lag_map} and {fname_func} have different sizes!')
475+
476+
# Read lag_step and lag_max from file (or try to)
477+
lag = lag * mask
478+
479+
lag_list = np.unique(lag[mask])
480+
481+
if lag_step is None:
482+
# np.unique sorts results already
483+
lag_step = np.unique(np.round(lag_list[1:] - lag_list[:-1], 3))
484+
if lag_step.size > 1:
485+
# Check if extra steps found are multiple of the first within numerical tolerance
486+
if not np.isclose(np.mod(lag_step, lag_step[0]), 0).all():
487+
raise ValueError(
488+
f'phys2cvr found different delta lags in {lag_map}: {lag_step}'
489+
)
490+
491+
lag_step = lag_step[0]
492+
LGR.warning(f'phys2cvr detected a delta lag of {lag_step} seconds')
493+
else:
494+
LGR.warning(f'Forcing delta lag to be {lag_step}')
495+
496+
if lag_max is None:
497+
lag_max = np.abs(lag_list).max()
498+
LGR.warning(f'phys2cvr detected a max lag of {lag_max} seconds')
499+
else:
500+
LGR.warning(f'Forcing max lag to be {lag_max}')
501+
465502
# If a regressor dir is specified, try load the data,
466503
# If failing or otherwise, compute the regressors.
467504
if run_regression and regr_dir is not None:
@@ -476,35 +513,6 @@ def phys2cvr(
476513
regr_dir = None
477514

478515
if regr_dir is None:
479-
if lag_map:
480-
lag, _, _ = io.load_nifti_get_mask(lag_map)
481-
if func.shape[:3] != lag.shape:
482-
raise ValueError(f'{lag_map} and {fname_func} have different sizes!')
483-
484-
# Read lag_step and lag_max from file (or try to)
485-
lag = lag * mask
486-
487-
lag_list = np.unique(lag[mask > 0])
488-
489-
if lag_step is None:
490-
lag_step = np.unique(np.round(lag_list[1:] - lag_list[:-1], 3))
491-
if lag_step.size > 1:
492-
raise ValueError(
493-
f'phys2cvr found different delta lags in {lag_map}'
494-
)
495-
else:
496-
lag_step = lag_step[0]
497-
LGR.warning(f'phys2cvr detected a delta lag of {lag_step} seconds')
498-
else:
499-
LGR.warning(f'Forcing delta lag to be {lag_step}')
500-
501-
step = int(lag_step * freq)
502-
503-
if lag_max is None:
504-
lag_max = np.abs(lag_list).max()
505-
LGR.warning(f'phys2cvr detected a max lag of {lag_max} seconds')
506-
else:
507-
LGR.warning(f'Forcing max lag to be {lag_max}')
508516
regr, regr_shifts = create_physio_regressor(
509517
func_avg,
510518
petco2hrf,
@@ -608,37 +616,25 @@ def phys2cvr(
608616
r_square, oimg, f'{fname_out_func}_r_square_simple{fname_ext}'
609617
)
610618

611-
if (
612-
lagged_regression
613-
and regr_shifts is not None
614-
and ((lag_max and lag_step) or lag_map)
615-
):
616-
if lag_max:
617-
LGR.info(
618-
f'Running lagged CVR estimation with max lag = {lag_max}! '
619-
'(might take a while...)'
620-
)
621-
elif lag_map is not None:
619+
if lagged_regression and regr_shifts is not None and (lag_max and lag_step):
620+
# If user specified a lag map, run regression based on it (see "Load lag map")
621+
if lag_map is not None:
622622
LGR.info(
623623
f'Running lagged CVR estimation with lag map {lag_map}! '
624624
'(might take a while...)'
625625
)
626-
if legacy:
627-
nrep = int(lag_max * freq * 2)
628-
else:
629-
nrep = int(lag_max * freq * 2) + 1
630626

631-
# If user specified a lag map, use that one to regress things
632-
if lag_map:
627+
step = int(lag_step * freq)
628+
633629
lag_idx = np.round((lag + lag_max) * freq / step).astype(int)
634630
lag_idx_list = np.unique(lag_idx)
635631

636632
# Prepare empty matrices
637633
beta = np.empty_like(lag, dtype='float32')
638634
tstat = np.empty_like(lag, dtype='float32')
639635

640-
for index, i in enumerate(lag_idx_list):
641-
LGR.info(f'Perform L-GLM number {index + 1} of {len(lag_idx_list)}')
636+
for n, i in enumerate(lag_idx_list):
637+
LGR.info(f'Perform L-GLM number {n + 1} of {len(lag_idx_list)}')
642638
regr = regr_shifts[(i * step), :, np.newaxis]
643639

644640
x1D = os.path.join(outdir, 'mat', f'mat_{i:04g}.1D')
@@ -656,6 +652,16 @@ def phys2cvr(
656652
)
657653

658654
else:
655+
LGR.info(
656+
f'Running lagged CVR estimation with max lag = {lag_max}! '
657+
'(might take a while...)'
658+
)
659+
660+
if legacy:
661+
nrep = int(lag_max * freq * 2)
662+
else:
663+
nrep = int(lag_max * freq * 2) + 1
664+
659665
# Check the number of repetitions first
660666
if lag_step:
661667
step = int(lag_step * freq)

0 commit comments

Comments
 (0)