Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docstrings #14

Merged
merged 2 commits into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion phys2cvr/cli/run.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
Parser for phys2cvr
Parser for phys2cvr.
"""

import argparse
Expand Down
8 changes: 8 additions & 0 deletions phys2cvr/io.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#!/usr/bin/env python3
"""
I/O and related utils.

Attributes
----------
LGR :
logger
"""

import logging

Expand Down
150 changes: 138 additions & 12 deletions phys2cvr/phys2cvr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
#!/usr/bin/env python3
"""
Main file for phys2cvr.

Attributes
----------
EXT_1D : list
List of supported TXT/1D file extensions, in lower case.
EXT_NIFTI : list
List of supported nifti file extensions, in lower case.
FIGSIZE : tuple
Figure size
LGR :
Logger
SET_DPI : int
DPI of the figure
"""

import datetime
import logging
Expand All @@ -24,14 +40,11 @@
def save_bash_call(outdir):
"""
Save the bash call into file `p2d_call.sh`.

Parameters
----------
metric : function
Metric function to retrieve arguments for
metric_args : dict
Dictionary containing all arguments for all functions requested by the
user
outdir : str or path, optional
output directory
"""
arg_str = ' '.join(sys.argv[1:])
call_str = f'phys2cvr {arg_str}'
Expand All @@ -44,14 +57,127 @@ def save_bash_call(outdir):
f.close()


def phys2cvr(fname_func, fname_co2='', fname_pidx='', fname_mask='', outdir='',
freq='', tr='', trial_len='', n_trials='', highcut='', lowcut='',
apply_filter=False, run_regression=False, lagged_regression=False,
lag_max=9, lag_step=0.3, l_degree=0, denoise_matrix=[],
scale_factor='', lag_map='', regr_dir='', skip_conv=False,
quiet=False, debug=False):
def phys2cvr(fname_func, fname_co2=None, fname_pidx=None, fname_mask=None,
outdir=None, freq=None, tr=None, trial_len=None, n_trials=None,
highcut=None, lowcut=None, apply_filter=False,
run_regression=False, lagged_regression=True, lag_max=9,
lag_step=0.3, l_degree=0, denoise_matrix=[], scale_factor=None,
lag_map=None, regr_dir=None, skip_conv=False, quiet=False, debug=False):
"""
Run main workflow of phys2cvr.

Parameters
----------
fname_func : str or path
Filename of the functional input (nifti or txt)
fname_co2 : str or path, optional
Filename of the CO2 (physiological regressor) timeseries.
Can be either peakdet's output or a txt file.
If not declared, phys2cvr will consider the average temporal value
from the input.
Default: empty
fname_pidx : str or path, optional
Filename of the CO2 (physiological regressor) timeseries' PEAKS.
Required if CO2 file is a txt AND the convolution step is not skipped.
If not declared AND the convolution step is not skipped, raises an exception.
Default: empty
fname_mask : str or path, optional
Filename of the mask for nifti volume.
If declared, phys2cvr will run only on these voxels.
If not, phys2cvr will estimate a mask from the functional input.
Ignored if input is a txt file.
Default: empty
outdir : str or path, optional
Output directory
Default: the directory where `fname_func` is.
freq : str, int, or float, optional
Sample frequency of the CO2 regressor. Required if CO2 input is TXT file.
If declared with peakdet file, it will overwrite the file frequency.
tr : str, int, or float, optional
TR of the timeseries. Required if input is TXT file.
If declared with nifti file, it will overwrite the file TR.
trial_len : str or int, optional
Length of each single trial for tasks that have more than one
(E.g. BreathHold, CO2 challenges, ...)
Used to improve cross correlation estimation.
Default: None
n_trials : str or int, optional
Number of trials in the task.
Default: None
highcut : str, int, or float, optional
High frequency limit for filter.
Required if applying a filter.
Default: empty
lowcut : str, int, or float, optional
Low frequency limit for filter.
Required if applying a filter.
Default: empty
apply_filter : bool, optional
Apply a Butterworth filter to the functional input.
Default: False
run_regression : bool, optional
Also run the regression step within phys2cvr.
By default, phys2cvr will only estimate the regressor(s) of interest.
Default: False
lagged_regression : bool, optional
Estimates regressors to run a lagged regression approach.
If `run_regression` is True, also run the lagged regression.
Can be turned off.
Default: True
lag_max : int or float, optional
Limits (both positive and negative) of the temporal area to explore,
expressed in seconds.
Default: 9 (i.e. ±9 seconds)
lag_step : int or float, optional
Step of the lag to take into account.
Default: 0.3 (seconds)
l_degree : int, optional
Only used if performing the regression step.
Highest order of the Legendre polynomial to add to the denoising matrix.
phys2cvr will add all polynomials up to the specified order
(e.g. if user specifies 3, orders 0, 1, 2, and 3 will be added).
Default is 0, which will model only the mean of the timeseries.
denoise_matrix : list of np.array(s), optional
Add one or multiple denoising matrices to the regression model.
Ignored if not performing the regression step.
scale_factor : str, int, or float, optional
A scale factor to apply to the CVR map before exporting it.
Useful when using inputs recorded/stored in Volts that have a meaningful
unit of measurement otherwise, e.g. (CO2 traces in mmHg).
V->mmHg: CO2[mmHg] = (Patm-Pvap)[mmHg] * 10*CO2[V]/100[V]
Default: None
lag_map : str or path, optional
Filename of a lag map to get lags from.
Ignored if not running a lagged-GLM regression.
Default: None
regr_dir : str, optional
Directory containing pre-generated lagged regressors, useful
to (re-)run a GLM analysis.
Default: None
skip_conv : bool, optional
Skip the convolution of the physiological trace.
Default: False
quiet : bool, optional
Return to screen only warnings and errors.
Default: False
debug : bool, optional
Return to screen more output.
Default: False

Raises
------
Exception
- If functional timeseries is lacking TR and the latter was not specified.
- If functional nifti file is not at least 4D.
- If mask was specified but it has different dimensions than the
functional nifti file.
- If a file type is not supported yet.
- If physiological file is a txt file and no peaks were provided.
- If physiological file is lacking frequency and the latter was not specified.
- If a lag map was specified but it has different dimensions than the
functional nifti file.
- If a lag map was specified, lag_step was not, and the lag map seems
to have different lag_steps inside.
"""
# If lagged regression is selected, make sure run_regression is true.
if lagged_regression:
Expand Down
54 changes: 41 additions & 13 deletions phys2cvr/signal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#!/usr/bin/env python3
"""
Signal analysis module for phys2cvr.

Attributes
----------
LGR :
Logger
"""

import logging

Expand All @@ -18,17 +26,17 @@
def create_hrf(freq=40):
"""
Create a canonical haemodynamic response function sampled at the given frequency.

Parameters
----------
freq: float
freq : float
Sampling frequency of the haemodynamic response function.

Returns
-------
hrf: np.ndarray
hrf : np.ndarray
Haemodynamic response function.

"""
# Create HRF
RT = 1/freq
Expand Down Expand Up @@ -59,23 +67,23 @@ def create_hrf(freq=40):
def filter_signal(data, tr, lowcut='', highcut=''):
"""
Create a bandpass filter given a lowcut and a highcut, then filter data.

Parameters
----------
data: np.ndarray
data : np.ndarray
Data to filter (along last axis)
tr: float
tr : float
TR of functional files
lowcut: float
lowcut : float
Lower frequency in the bandpass
highcut: float
highcut : float
Higher frequency in the bandpass

Returns
-------
filt_data: np.ndarray
filt_data : np.ndarray
Input `data`, but filtered.

"""
if not lowcut:
lowcut = 0.02
Expand All @@ -90,6 +98,26 @@ def filter_signal(data, tr, lowcut='', highcut=''):


def convolve_petco2(co2, pidx, freq, outname):
"""
Convolve the CO2 trace into the PetCO2 trace

Parameters
----------
co2 : np.array
CO2 (or physiological) regressor
pidx : np.array
index of peaks
freq : str, int, or float
sample frequency of the CO2 regressor
outname : str
prefix of the exported file


Returns
-------
co2_conv : np.array
Convolved CO2 trace
"""
# Extract PETco2
hrf = create_hrf(freq)
co2_lenght = len(co2)
Expand Down
Loading