Fitting

This file contains functions and classes related HRF fitting procedures, including deconvolution, epoching, parameter fitting, and curve fitting. All of these functions work with dataframes generated by Dataset.

class lazyfmri.fitting.CVDeconv(func, onsets, TR=0.105)[source]

Bases: InitFitter

crossvalidate()[source]

Performs cross-validation using lazyfmri.fitting.NideconvFitter by iteratively leaving out runs, training on the remaining runs, and predicting the left-out runs.

Parameters:
  • split (int, optional) – The number of runs included in each training fold, by default 2.

  • **kwargs (dict, optional) – Additional parameters passed to lazyfmri.fitting.NideconvFitter.

Returns:

The method updates self.r2_ with the R² values for each fold.

Return type:

None

Example

cv.crossvalidate(split=2, basis_sets="Fourier", n_regressors=9, interval=[-2,24])
predict_out_of_set()[source]

Predicts the responses for unseen (left-out) runs based on the beta weights from trained data.

Parameters:
Returns:

A DataFrame containing R² values for each subject, where columns represent the fMRI voxels or regions.

Return type:

pd.DataFrame

Example

r2_scores = cv.predict_out_of_set(trained_fitter, [1, 2])
return_combinations()[source]

Generates all possible unique combinations of run indices for cross-validation.

Parameters:

split (int, optional) – The number of runs to be included in each split, by default 2.

Returns:

A list containing tuples, where each tuple represents a unique combination of runs.

Return type:

list of tuples

Raises:

ValueError – If there are fewer than 3 runs, as cross-validation is ineffective with fewer than 3 runs.

Example

cv = CVDeconv(func, onsets, TR=1.32)
run_combinations = cv.return_combinations(split=2)
single_fitter()[source]

Creates an instance of lazyfmri.fitting.NideconvFitter for a given functional dataset and onset times.

Parameters:
  • func (pd.DataFrame) – Functional fMRI data in the form of a pandas DataFrame.

  • onsets (pd.DataFrame) – Onset timings corresponding to the events in the functional data.

  • **kwargs (dict, optional) – Additional parameters passed to lazyfmri.fitting.NideconvFitter.

Returns:

An instance of lazyfmri.fitting.NideconvFitter fitted to the given data.

Return type:

lazyfmri.fitting.NideconvFitter

Example

fitter = cv.single_fitter(df_func, df_onsets, basis_sets="Fourier", n_regressors=6)
class lazyfmri.fitting.CurveFitter[source]

Bases: object

Simple class to perform a quick curve fitting procedure on y_data. You can either specify your own function with func, or select a polynomial of order order (currently up until 3rd-order is included). Internally uses lmfit.Model to perform the fitting, allowing for access to confidence intervals.

Parameters:
  • y_data (np.ndarray) – Data-points to perform fitting on

  • x (np.ndarray, optional) – Array describing the x-axis, by default None.

  • func (function-object, optional) – Use custom function describing the behavior of the fit, by default None. If None, we’ll assume either a linear or polynomial fit (up to 3rd order)

  • order (str, int, optional) – Order of polynomial fit, by default 1 (linear).

  • verbose (bool, optional) – Print summary of fit, by default True

  • interpolate (str, optional) – Method of interpolation for an upsampled version of the predicted data (default = 1000 samples)

Raises:

NotImplementedError – If func=None and no valid polynomial order (see above) was specified

Example

# imports
from lazyfmri import fitting
import matplotlib.pyplot as plt
import numpy as np

# define data points
data = np.array([5.436, 5.467, 5.293, 0.99 , 2.603, 1.902, 2.317])

# create instantiation of CurveFitter
cf = fitting.CurveFitter(data, order=3, verbose=False)

# initiate figure with axis to be fed into LazyLine
fig, axs = plt.subplots(figsize=(8,8))

# plot original data points
axs.plot(cf.x, data, 'o', color="#DE3163", alpha=0.6)

# plot upsampled fit with 95% confidence intervals as shaded error
plotting.LazyLine(
    cf.y_pred_upsampled,
    xx=cf.x_pred_upsampled,
    error=cf.ci_upsampled,
    axs=axs,
    color="#cccccc",
    x_label="x-axis",
    y_label="y-axis",
    title="Curve-fitting with polynomial (3rd-order)"
)
static first_order()[source]

First-order polynomial function (linear model).

Parameters:
  • x (float or np.ndarray) – Input x-values.

  • a (float) – Slope of the linear function.

  • b (float) – Intercept of the linear function.

Returns:

Computed y-values based on the linear function.

Return type:

float or np.ndarray

Example

y = CurveFitter.first_order(x, a=2, b=1)
init_params()[source]

Initializes parameters for the selected fitting model. If no custom function (func) is provided, it selects a polynomial or predefined model (“gaussian”, “exponential”).

Raises:

NotImplementedError – If an unsupported model type is provided.

Returns:

Updates self.pmodel with the selected model and initializes self.params.

Return type:

None

Example

cf = CurveFitter(y_data, order=2)
cf.init_params()
run()[source]

Executes the fitting procedure using the selected model and updates predictions.

Returns:

Updates self.result with the fitting results and generates predicted values (self.y_pred), confidence intervals (self.ci), and upsampled versions (self.y_pred_upsampled).

Return type:

None

Example

cf = CurveFitter(y_data, order=3)
cf.run()
static second_order()[source]

Second-order polynomial function (quadratic model).

Parameters:
  • x (float or np.ndarray) – Input x-values.

  • a (float) – Coefficient for the linear term.

  • b (float) – Coefficient for the quadratic term.

  • c (float) – Intercept.

Returns:

Computed y-values based on the quadratic function.

Return type:

float or np.ndarray

Example

y = CurveFitter.second_order(x, a=1, b=-0.5, c=2)
static third_order()[source]

Third-order polynomial function (cubic model).

Parameters:
  • x (float or np.ndarray) – Input x-values.

  • a (float) – Coefficient for the linear term.

  • b (float) – Coefficient for the quadratic term.

  • c (float) – Coefficient for the cubic term.

  • d (float) – Intercept.

Returns:

Computed y-values based on the cubic function.

Return type:

float or np.ndarray

Example

y = CurveFitter.third_order(x, a=0.5, b=-0.3, c=2, d=1)
class lazyfmri.fitting.Epoch[source]

Bases: InitFitter

A class to extract timepoints within a specified interval based on onset times for all subjects, tasks, and runs in a dataframe. The extracted epochs can be indexed on subject, run, event_type, epoch, and t to facilitate event-related analyses.

Parameters:
  • func (pd.DataFrame) – Dataframe containing the fMRI data indexed on subject, run, and time (t). Expected format: output of lazyfmri.dataset.Datasets.fetch_fmri().

  • onsets (pd.DataFrame) – Dataframe containing the event onset timings indexed on subject, run, and event type. Expected format: output of lazyfmri.dataset.Datasets.fetch_onsets().

  • TR (float, optional) – Repetition time (TR) in seconds. Used to calculate the sampling frequency. Default is 0.105 seconds.

  • interval (list, optional) – Time interval around each event onset to extract the epoch data. Default is [-2, 14], meaning extraction starts 2 seconds before and ends 14 seconds after the event.

  • merge (bool, optional) – Whether to concatenate runs before extracting epochs. Default is False.

Example

from lazyfmri import fitting

# Instantiate the Epoch class
sub_ep = fitting.Epoch(
    func,
    onsets,
    TR=0.105,
    interval=[-2, 14]
)

# Extract the epoched dataframe
sub_df = sub_ep.df_epoch.copy()
static correct_baseline(d_, bsl=20, verbose=False)[source]

Correct the baseline of time-series data.

Shifts the data to ensure the baseline is centered around zero. If the mean of the first bsl timepoints is negative, it shifts the entire time-series upwards. If positive, it shifts downwards.

Parameters:
  • d (pd.DataFrame or np.ndarray) – Input time-series data. If a dataframe is provided, the operation is applied per column.

  • bsl (int, optional) – Number of initial timepoints to use for baseline correction. Default is 20.

  • verbose (bool, optional) – If True, prints shift information. Default is False.

Returns:

Baseline-corrected data with the same format as input.

Return type:

pd.DataFrame or np.ndarray

epoch_events(df_func, df_onsets, index=False)[source]

Extract event-specific epochs from functional data.

Iterates over all events in the provided onset dataframe and extracts corresponding time windows from the functional data.

Parameters:
  • df_func (pd.DataFrame) – Functional data indexed on subject, run, and t.

  • df_onsets (pd.DataFrame) – Onset data indexed on subject, run, and event_type.

  • index (bool, optional) – Whether to set hierarchical index on the output dataframe. Default is False.

Returns:

Extracted epochs with time (t), event type, subject, and run information.

Return type:

pd.DataFrame

epoch_input()[source]

Main function to extract epochs from input data.

Calls lazyfmri.fitting.Epoch.epoch_subjects() to extract epochs at the subject level and formats the resulting dataframe. The final output is stored in self.df_epoch.

Returns:

The extracted epoch dataframe is stored as self.df_epoch.

Return type:

None

epoch_runs(df_func, df_onsets, index=False)[source]

Extract epochs across multiple runs.

Loops over all available runs and applies lazyfmri.fitting.Epoch.epoch_events() to extract event-specific epochs for each run.

Parameters:
  • df_func (pd.DataFrame) – Functional data indexed on subject, run, and t.

  • df_onsets (pd.DataFrame) – Onset data indexed on subject, run, and event_type.

  • index (bool, optional) – Whether to set hierarchical index on the output dataframe. Default is False.

Returns:

Extracted epochs for all runs combined.

Return type:

pd.DataFrame

epoch_subjects(df_func, df_onsets)[source]

Extract epochs for all subjects.

Loops over all subjects in the dataset, extracts subject-specific functional data, and applies lazyfmri.fitting.Epoch.epoch_tasks() or lazyfmri.fitting.Epoch.epoch_runs() to process all tasks/runs within each subject.

Parameters:
  • df_func (pd.DataFrame) – Functional data indexed on subject, task, run, and t.

  • df_onsets (pd.DataFrame) – Onset data indexed on subject, task, run, and event_type.

Returns:

Extracted epochs for all subjects combined.

Return type:

pd.DataFrame

epoch_tasks(df_func, df_onsets)[source]

Extract epochs across multiple tasks.

Loops over all tasks in the dataset, extracts task-specific functional data, and applies lazyfmri.fitting.Epoch.epoch_runs() to process all runs within each task.

Parameters:
  • df_func (pd.DataFrame) – Functional data indexed on subject, task, run, and t.

  • df_onsets (pd.DataFrame) – Onset data indexed on subject, task, run, and event_type.

Returns:

Extracted epochs for all tasks combined.

Return type:

pd.DataFrame

class lazyfmri.fitting.FWHM(x, hrf, amplitude=None, negative=False, resample=500)[source]

Bases: object

half_max_x(x, y, amplitude=None)[source]
class lazyfmri.fitting.FitHRFparams[source]

Bases: object

Similar to Marco’s pRF modeling, we can also estimate the best set of parameters that describe the HRF. This has slightly more degrees of freedom compared to using basis sets, but is not as unconstrained as FIR.

Parameters:
  • data (np.ndarray) – Input must be an array (voxels,timepoints)

  • onsets (pd.DataFrame) – Dataframe indexed on subject, run, and event_type (as per lazyfmri.dataset.ParseExpToolsFile)

  • verbose (bool, optional) – Print progress to the terminal, by default False

  • TR (float, optional) – Repetition time, by default 1.32

  • osf (int, optional) – Oversampling factor to account for decimals in onset times, by default 100

  • starting_params (list, optional) – Starting parameters of the HRF, by default [6,12,0.9,0.9,0.35,5.4,10.8]

  • n_jobs (int, optional) – Number of jobs to use, by default 1

  • bounds (list, optional) – Specific bounds for each parameter, by default None

  • resample_to_shape (int, optional) – Resample the final profiles to a certain shape, by default None

  • xtol (float, optional) – x-tolerance of the fitter, by default 1e-4

  • ftol (float, optional) – f-tolerance of the fitter, by default 1e-4

  • interval (list, optional) – Interval used to define the full HRF profile, by default [0,30]

  • read_index (bool, optional) – Copy the index from the input dataframe, by default False

iterative_fit()[source]
profiles_from_parameters(resample_to_shape=None, negative=None, read_index=False)[source]
class lazyfmri.fitting.GLM[source]

Bases: InitFitter

Class to run a GLM for all subjects, tasks, and runs in a dataframe.

Parameters:
  • func (pd.DataFrame) – Dataframe as per the output of lazyfmri.dataset.Datasets.fetch_fmri(), containing the fMRI data indexed on subject, run, and t.

  • onsets (pd.DataFrame) – Dataframe as per the output of lazyfmri.dataset.Datasets.fetch_onsets(), containing the onset timings data indexed on subject, run, and event_type.

  • TR (float, optional) – Repetition time, by default 0.105. Use to calculate the sampling frequency (1/TR)

  • interval (list, optional) – Interval to fit the regressors over, by default [0,12]

  • merge (bool, optional) – Concatenate the runs before extracting the epochs

find_max_r2(df=None)[source]
find_r2(vox_nr, df=None)[source]
classmethod format_ev(glm_obj)[source]
classmethod format_fm(glm_obj)[source]
classmethod format_obj(glm_obj)[source]
classmethod format_output(glm_obj)[source]
classmethod format_r2(glm_obj)[source]
classmethod format_tstats(glm_obj)[source]
classmethod get_copes(evs, derivative=False, dispersion=False, add_intercept=True, **kwargs)[source]
get_result()[source]
glm_input(**kwargs)[source]
classmethod glm_runs(df_func, df_onsets, **kwargs)[source]
classmethod glm_subjects(df_func, df_onsets, **kwargs)[source]
classmethod glm_tasks(df_func, df_onsets, **kwargs)[source]
plot_ev_predictions(data=None, subject=None, task=None, run=None, vox_nr='max', cmap='inferno', axs=None, figsize=(14, 4), full=False, full_only=False, full_color='k', r2_dec=4, **kwargs)[source]
classmethod single_glm(func, onsets, **kwargs)[source]
class lazyfmri.fitting.HRFMetrics(hrf, **kwargs)[source]

Bases: object

classmethod get_slope_between_points(time_array, signal_array, t0, t1)[source]
classmethod plot_hrf_auc(time, signal, t_start=0, figsize=(5, 5))[source]
classmethod plot_profile_for_debugging()[source]

Plots the HRF time-series for debugging purposes.

Parameters:
  • hrf (pd.DataFrame) – The input HRF time-series.

  • axs (matplotlib.axes._axes.Axes, optional) – Matplotlib axis for plotting, by default None.

  • figsize (tuple, optional) – Figure size, by default (5, 5).

  • **kwargs (dict) – Additional keyword arguments for plotting.

Example

HRFMetrics.plot_profile_for_debugging(hrf_data)
return_metrics()[source]

Returns the extracted HRF parameters in a formatted DataFrame.

Returns:

A DataFrame containing extracted HRF metrics, such as peak amplitude, time-to-peak, full-width half-maximum (FWHM), area under the curve (AUC), and slope-related features.

Return type:

pd.DataFrame

Example

metrics_df = HRFMetrics(some_profile).return_metrics()
print(metrics_df)
class lazyfmri.fitting.InitFitter[source]

Bases: object

Initializes the fitter with functional data and onset times, formatting them for analysis.

Parameters:
  • func (pd.DataFrame) – Functional fMRI data as a pandas DataFrame.

  • onsets (pd.DataFrame) – Onset timings corresponding to the events in the functional data.

  • TR (float) – Repetition time (TR) in seconds.

  • merge (bool, optional) – Whether to concatenate runs before analysis, by default False.

Example

fitter = InitFitter(func, onsets, TR=1.32, merge=True)
classmethod concat_func()[source]

Concatenates functional MRI data from multiple runs into a single dataframe. Adjusts time indices based on TR and resets the run index.

Parameters:

df (pd.DataFrame) – Functional data dataframe indexed on subject, run, and t.

Returns:

Concatenated functional data with updated indices.

Return type:

pd.DataFrame

Example

func_concat = NideconvFitter.concat_func(func_df)
classmethod concat_onsets()[source]

Concatenates event onset data across multiple runs, updating onset times to reflect the new concatenated timeline.

Parameters:
  • onsets (pd.DataFrame) – Onset data indexed on subject, run, and event_type.

  • func (pd.DataFrame) – Functional data used to determine run durations.

Returns:

Concatenated onsets with updated onset times.

Return type:

pd.DataFrame

Example

onsets_concat = NideconvFitter.concat_onsets(onsets_df, func_df)
classmethod concat_runs()[source]

Concatenates functional MRI data and event onsets across multiple runs for each subject. Calls concat_func and concat_onsets internally.

Parameters:
  • func (pd.DataFrame) – Functional MRI data indexed by subject, run, and t.

  • onsets (pd.DataFrame) – Event onset data indexed by subject, run, and event_type.

Returns:

Dictionary containing concatenated functional (“func”) and onset (“onsets”) data.

Return type:

dict

Example

concatenated_data = NideconvFitter.concat_runs(func_df, onsets_df)
func_concat = concatenated_data["func"]
onsets_concat = concatenated_data["onsets"]
concatenate()[source]

Concatenates functional data and onset times across runs.

Returns:

Updates self.func and self.onsets with concatenated data.

Return type:

None

Example

fitter.concatenate()
static find_pars_index()[source]

Identifies any additional index columns present in a DataFrame that are not part of the expected indices.

Parameters:

df (pd.DataFrame) – The DataFrame to inspect.

Returns:

The name of the additional index column(s), if any.

Return type:

str or list

Example

index_col = InitFitter.find_pars_index(df)
format_epoch_pars(pars_df, ix=1, idx=['subject', 'event_type', 'run', 'vox'])[source]
classmethod format_evs_for_plotting(df, indexer='event_type', time_col='time', **kwargs)[source]

Formats a dataframe of event-related responses for plotting by averaging across time and computing error margins (SEM or STD) per condition to be compatible with. This output is compatible with plotting utilities such as LazyLine plotting class from the LazyfMRI package.

Parameters:
  • df (pd.DataFrame) – Multi-indexed dataframe containing timecourses with event labels and time. Expected indices include at least event_type and time.

  • indexer (str, optional) – Index level name corresponding to conditions (e.g., “event_type”).

  • time_col (str, optional) – Index level name corresponding to the time axis.

  • **kwargs (dict) – Additional arguments passed to format_for_plotting, such as error type (se=’sem’ or ‘std’).

Returns:

A dictionary with keys:
  • ”tc” : list of mean timecourses per condition

  • ”err”: list of SEM or STD values per condition

  • ”labels”: list of condition names (e.g., event types)

  • ”time”: common time axis (shared across events)

Return type:

dict

Example

# initialize the fitter
dec = fitting.NideconvFitter(
    df_func,
    df_onset,
    basis_sets="canonical_hrf_with_time_derivative",
    TR=0.105,
    interval=[-2,16]
)

# fetch the profiles
dec.timecourses_condition()

# format for plotting
fmt = dec.format_evs_for_plotting(dec.tc_condition)

# plot
pl = plotting.LazyLine(
    fmt["tc"],
    xx=fmt["time"],
    figsize=(5,5),
    labels=["center","medium","large"],
    x_label="time (s)",
    y_label="amplitude",
    error=fmt["err"],
    line_width=3,
    color=["#1B9E77","#D95F02","#4c75ff"],
    add_hline=0
)

plotting.add_axvspan(
    pl.axs,
    ymax=0.1
)
static format_for_plotting(df, se='sem')[source]

Computes the mean and error values (SEM or STD) for a timecourse dataframe.

Parameters:
  • df (pd.DataFrame) – A dataframe where rows represent timepoints and columns are different samples or subjects.

  • se (str, optional) –

    Error metric to compute:
    • ”sem” or “se”: standard error of the mean

    • ”std” or “sd”: standard deviation

Returns:

A dictionary with:
  • ”tc” : mean values (1D array)

  • ”err”: error margins (SEM or STD, 1D array)

Return type:

dict

Raises:

NotImplementedError – If se is not one of the supported values.

Example

>>> result = format_for_plotting(df, se="std")
>>> plt.plot(time, result["tc"])
>>> plt.fill_between(time, result["tc"] - result["err"], result["tc"] + result["err"])
merge_basissets_with_full_hrf()[source]

Merges basis set regressors with full hemodynamic response function (HRF) predictions for further analysis.

Parameters:

**kwargs (dict) – Additional parameters for merging.

Example

fitter = NideconvFitter(func, onsets, TR=1.32)
merged_data = fitter.merge_basissets_with_full_hrf()
static merge_dfs()[source]

Merges two dataframes by aligning their indices. Typically used for combining basis set estimates with full HRF predictions.

Parameters:
  • src (pd.DataFrame) – Source dataframe.

  • trg (pd.DataFrame) – Target dataframe to merge with.

  • name (str, optional) – Label assigned to the merged dataframe, by default “full HRF”.

  • first (str, optional) – Determines merge order, either “basissets” or “full”, by default “basissets”.

Returns:

Merged dataframe.

Return type:

pd.DataFrame

Example

merged_df = NideconvFitter.merge_dfs(df1, df2, name="HRF Comparison", first="full")
parameters_for_basis_sets()[source]

Extracts HRF parameters from basis set regressors.

Parameters:
Returns:

Updates self.pars_basissets with extracted parameters.

Return type:

None

Example

fitter.parameters_for_basis_sets()
parameters_for_epochs(df=None, **kwargs)[source]
parameters_for_tc_condition()[source]

Extracts HRF parameters for condition-averaged timecourses.

Parameters:
Returns:

Updates self.pars_condition with extracted parameters.

Return type:

None

Raises:

ValueError – If self.tc_condition is not available.

Example

fitter.parameters_for_tc_condition()
parameters_for_tc_subjects()[source]

Extracts HRF parameters for subject-specific timecourses.

Parameters:
Returns:

Updates self.pars_subjects with extracted parameters.

Return type:

None

Raises:

ValueError – If self.tc_subjects is not available.

Example

fitter.parameters_for_tc_subjects()
prepare_data()[source]

Prepares the functional data DataFrame by ensuring proper indexing and adding necessary columns.

Returns:

Updates self.func with formatted data.

Return type:

None

Example

fitter.prepare_data()
prepare_onsets()[source]

Prepares the onset DataFrame by ensuring proper indexing and adding necessary columns.

Returns:

Updates self.onsets with formatted data.

Return type:

None

Example

fitter.prepare_onsets()
class lazyfmri.fitting.NideconvFitter[source]

Bases: InitFitter

A wrapper class around nideconv.GroupResponseFitter for streamlined and flexible fMRI deconvolution. This class simplifies reproducibility, handles pandas indexing issues, and allows for efficient multiple deconvolutions. Designed to work with functional MRI (fMRI) data, event onsets, and grey matter ribbon voxels.

Main Features - Supports basis sets (‘fourier’ or ‘fir’). - Implements ordinary least squares (OLS) fitting. - Handles confounds and covariates. - Includes multiple visualization functions.

Parameters:
  • func (pd.DataFrame) – fMRI data indexed by subject, run, and t.

  • onsets (pd.DataFrame) – Dataframe with event onsets indexed by subject, run, and event_type.

  • TR (float, optional) – Repetition time in seconds. Default is 0.105.

  • confounds (pd.DataFrame, optional) – Confound regression matrix matching func. Default is None.

  • basis_sets (str, optional) – Type of basis set (‘fourier’ or ‘fir’). Default is ‘fourier’.

  • fit_type (str, optional) – Fitting method (‘ols’ or ‘ridge’). Default is ‘ols’.

  • n_regressors (int or str, optional) – Number of regressors (‘tr’ syncs regressors with TR). Default is 9.

  • add_intercept (bool, optional) – Whether to fit an intercept. Default is False.

  • lump_events (bool, optional) – If True, merges all event types. Default is False.

  • interval (list, optional) – Time window for fitting regressors. Default is [0, 20].

  • osf (int, optional) – Oversampling factor for design matrix. Default is 20.

  • fit (bool, optional) – If True, fits the model upon initialization. Default is True.

  • covariates (dict, optional) – Covariates for each event (dict of numpy arrays). Default is None.

  • conf_intercept (bool, optional) – Includes an intercept in confound model if True. Default is True.

  • **kwargs – Additional parameters for model initialization.

Example

from lazyfmri import dataset, fitting
df_func = dataset.fetch_fmri()
df_onsets = dataset.fetch_onsets()

nd_fit = fitting.NideconvFitter(
    df_func,
    df_onsets,
    basis_sets='fourier',
    n_regressors=4,
    TR=0.105,
    interval=[0,20]
)
add_event()[source]

Adds a new event to the response fitter.

Parameters:
  • *args (tuple) – Positional arguments passed to the add_event function.

  • **kwargs (dict) – Additional keyword arguments for defining the event.

Returns:

Updates the fitted model with the new event.

Return type:

None

Example

fitter.add_event("stimulus", basis_set="fourier", n_regressors=4)
change_name_set_index()[source]

Renames the “event type” column to “event_type” and resets the dataframe index.

Parameters:
  • df (pd.DataFrame) – Input dataframe.

  • index (list or str, optional) – List of index levels to set, by default [“subject”, “event_type”, “covariate”, “time”].

Returns:

Reformatted dataframe with updated index.

Return type:

pd.DataFrame

Example

formatted_df = fitter.change_name_set_index(df)
classmethod check_for_run_index()[source]

Ensures that the run index exists in a dataframe, adding a “run” column if missing.

Parameters:
  • df (pd.DataFrame) – Input dataframe.

  • loc (int, optional) – Position to insert the “run” column, by default 1.

Returns:

Dataframe with “run” column added if missing.

Return type:

pd.DataFrame

Example

df_checked = NideconvFitter.check_for_run_index(df)
define_events()[source]

Adds events to the deconvolution model, specifying the basis set and regression parameters.

Returns:

Stores event definitions in the fitted model.

Return type:

None

Example

fitter.define_events()
define_model()[source]

Defines the nideconv.GroupResponseFitter model and initializes it with the appropriate parameters.

Parameters:

**kwargs (dict) – Additional arguments passed to the GroupResponseFitter.

Returns:

Stores the initialized model in the object attribute model.

Return type:

None

Example

fitter.define_model()
derive_n_regressors()[source]

Determines the number of regressors to use based on the specified basis set. If “tr” is specified, automatically calculates regressors per TR.

Returns:

Stores the determined number of regressors in self.n_regressors.

Return type:

None

Example

fitter.derive_n_regressors()
print(fitter.n_regressors)
fit()[source]

Fits a deconvolution model to the functional MRI data based on subject, run, and event information. Uses single_response_fitter to fit the data and store results, including timecourse predictions, profiles, and parameter estimates.

Parameters:
  • debug (bool, optional) – If True, prints verbose messages during fitting, by default False.

  • **kwargs (dict) – Additional parameters passed to the single_response_fitter function.

Example

fitter = NideconvFitter(func, onsets, TR=1.32)
fitter.fit(debug=True)
format_fitters()[source]

Converts fitted model output into a structured dataframe for easier indexing and retrieval.

Returns:

Stores formatted fitters in the object attribute fitters.

Return type:

None

Example

fitter.format_fitters()
print(fitter.fitters)
get_basisset_timecourses()[source]

Extracts the fitted basis set regressors from the model, retrieving timecourses for each event.

Returns:

Stores timecourses in object attributes: - sub_basis: Basis function timecourses indexed by subject, event type, and time.

Return type:

None

Example

fitter.get_basisset_timecourses()
print(fitter.sub_basis)
static get_curves_from_fitter()[source]

Extracts the predicted response curves for each event type from the fitted model.

Parameters:
  • fitter (nideconv.GroupResponseFitter) – The fitted response model.

  • index (bool, optional) – If True, maintains dataframe index structure, by default True.

  • icpt (bool, optional) – If True, includes the intercept regressor in the predictions, by default False.

Returns:

Dataframe containing event-specific response curves.

Return type:

pd.DataFrame

Example

response_curves = NideconvFitter.get_curves_from_fitter(fitter)
static get_event_predictions_from_fitter()[source]

Extracts event-specific predictions from a fitted model.

Parameters:
  • fitter (nideconv.GroupResponseFitter) – The fitted response model.

  • intercept (bool, optional) – If True, includes intercept regressors in the predictions, by default True.

Returns:

Dataframe containing predicted response for each event type.

Return type:

pd.DataFrame

Example

event_predictions = NideconvFitter.get_event_predictions_from_fitter(fitter)
get_predictions_per_event()[source]

Retrieves both full-model and event-specific predictions from the fitted model.

Stores predictions in object attributes:
  • self.ev_predictions: Event-level predicted responses.

  • self.sub_pred_full: Full model predictions per subject.

Return type:

None

Example

>>> fitter.get_predictions_per_event()
>>> print(fitter.ev_predictions)
interpolate_fir_condition(obj)[source]

Interpolates FIR model responses for all conditions in the input DataFrame.

Parameters:

obj (pd.DataFrame) – DataFrame with FIR model responses, indexed on [‘event_type’, ‘covariate’, ‘time’].

Returns:

Interpolated timecourses per condition and event type.

Return type:

pd.DataFrame

interpolate_fir_subjects()[source]

Interpolates the finite impulse response (FIR) model across subjects, resampling plateaus to obtain smoother timecourses.

Returns:

Interpolated FIR timecourses indexed by subject, run, event_type, covariate, and time.

Return type:

pd.DataFrame

Example

interpolated_fir = fitter.interpolate_fir_subjects()
make_onsets_for_response_fitter(i, run=None)[source]
make_response_fitter(data, run=None, cov=None)[source]
melt_events()[source]

Merges all events in the onset dataframe into a single generic event type “stim”.

Returns:

Onset dataframe with all events combined into a single category.

Return type:

pd.DataFrame

Example

lumped_onsets = fitter.melt_events()
plot_areas_per_event(colors=None, save_as=None, add_offset=True, error_type='sem', axs=None, events=None, **kwargs)[source]
plot_average_per_event()[source]

Plot the average across runs and voxels for each event in your data. Allows the option to have time-to-peak or full-width half max (FWHM) plots as insets. This makes the most sense if you have multiple events, otherwise you have 1 bar..

Parameters:
  • add_offset (bool, optional) – Shift the HRFs to have the baseline at zero, by default True. Theoretically, this should already happen if your baseline is estimated properly, but for visualization and quantification purposes this is alright

  • axs (<AxesSubplot:>, optional) – Matplotlib axis to store the figure on, by default None

  • title (str, optional) – Plot title, by default None, by default “Average HRF across events”

  • save_as (str, optional) – Save the plot as a file, by default None

  • error_type (str, optional) – Which error type to use across runs/voxels, by default “sem”

  • ttp (bool, optional) – Plot the time-to-peak on the inset axis, by default False

  • ttp_lines (bool, optional) – Plot lines on the original axis with HRFs to indicate the maximum amplitude, by default False

  • ttp_labels (list, optional) – Which labels to use for the inset axis; this can be different than your event names (e.g., if you want to round numbers), by default None

  • events (list, optional) – List that decides the order of the events to plot, by default None. By default, it takes the event names, but sometimes you want to flip around the order.

  • fwhm (bool, optional) – Plot the full-width half-max (FWHM) on the inset axis, by default False

  • fwhm_lines (bool, optional) – Plot lines on the original axis with HRFs to indicate the maximum amplitude, by default False

  • fwhm_labels (list, optional) – Which labels to use for the inset axis; this can be different than your event names (e.g., if you want to round numbers), by default None

  • inset_ttp (list, optional) – Where to put your TTP-axis, by default [0.75, 0.65, 0.3]. Height will be scaled by the number of events

  • inset_fwhm (list, optional) – Where to put your FWHM-axis, by default [0.75, 0.65, 0.3, 0.3]. Width will be scaled by the number of events

  • reduction_factor (float, optional) – Reduction factor of the font size in the inset axis, by default 1.3

Example

# do the fitting
nd_fit = fitting.NideconvFitter(
    df_ribbon, # dataframe with functional data
    df_onsets,  # dataframe with onsets
    basis_sets='canonical_hrf_with_time_derivative',
    TR=0.105,
    interval=[-3,17],
    add_intercept=True,
    verbose=True)

# plot TTP with regular events + box that highlights stimulus onset
fig,axs = plt.subplots(figsize=(8,8))
nd_fit.plot_average_per_event(
    xkcd=plot_xkcd,
    x_label="time (s)",
    y_label="magnitude (%)",
    add_hline='default',
    ttp=True,
    lim=[0,6],
    ticks=[0,3,6],
    ttp_lines=True,
    y_label2="size (°)",
    x_label2="time-to-peak (s)",
    title="regular events",
    ttp_labels=[f"{round(float(ii),2)}°" for ii in nd_fit.cond],
    add_labels=True,
    fancy=True,
    cmap='inferno')
# plot simulus onset
axs.axvspan(0,1, ymax=0.1, color="#cccccc")

# plot FWHM and flip the events
nd_fit.plot_average_per_event(
    x_label="time (s)",
    y_label="magnitude (%)",
    add_hline='default',
    fwhm=True,
    fwhm_lines=True,
    lim=[0,5],
    ticks=[i for i in range(6)],
    fwhm_labels=[f"{round(float(ii),2)}°" for ii in nd_fit.cond[::-1]],
    events=nd_fit.cond[::-1],
    add_labels=True,
    x_label2="size (°)",
    y_label2="FWHM (s)",
    fancy=True,
    cmap='inferno')
plot_average_per_voxel()[source]

Plot the average across runs for each voxel in your dataset. Generally, this plot is used to plot HRFs across depth. If you have multiple events, we’ll create a grid of n_cols wide (from which the rows are derived), with the HRFs for each event in the subplot. The legend will be put in the first subplot. If you only have 1 event, you can say n_cols=None to put the average across events for all voxels in 1 plot.

Parameters:
  • add_offset (bool, optional) – Shift the HRFs to have the baseline at zero, by default True. Theoretically, this should already happen if your baseline is estimated properly, but for visualization and quantification purposes this is alright

  • axs (<AxesSubplot:>, optional) – Matplotlib axis to store the figure on, by default None

  • n_cols (int, optional) – Decides the number of subplots on the x-axis, by default 4. If you have 1 event, specify n_cols=None

  • wspace (float, optional) – Decide the width between subplots, by default 0

  • figsize (tuple, optional) – Figure size, by default (24,5*nr_of_rows) or (8,8) if n_cols=None

  • make_figure (bool, optional) – Actually create the plot or just fetch the data across depth, by default True

  • labels (list, optional) – Which labels to use for the inset axis; this can be different than your event names (e.g., if you want to round numbers), by default None

  • save_as (str, optional) – Save to file, by default None

  • sharey (bool, optional) – Save all y-axes the same, by default False. Can be nice if you want to see the progression across depth

Example

nd_fit.plot_average_per_voxel(
    labels=[f"{round(float(ii),2)} dva" for ii in nd_fit.cond],
    wspace=0.2,
    cmap="inferno",
    line_width=2,
    font_size=font_size,
    label_size=16,
    sharey=True
)
plot_fwhm(df, axs=None, hrf_axs=None, fwhm_lines=False, fwhm_labels=None, split='event_type', figsize=(8, 8), fwhm_ori='v', par_kw={}, **kwargs)[source]
plot_hrf_across_depth()[source]

Plot the magnitude of the HRF across depth as points with a seaborn regplot through it. The points can be colored with color according to the HRF from lazyfmri.fitting.NideconvFitter.plot_average_across_voxels(), or they can be given 1 uniform color. The linear fit can be colored using ci_color, for which the default is light gray.

Parameters:
  • axs (<AxesSubplot:>, optional) – Matplotlib axis to store the figure on, by default None

  • figsize (tuple, optional) – Figure size, by default (8,8)

  • cmap (str, optional) – Color map for the data points, by default ‘viridis’

  • color (str, tuple, optional) – Don’t use a color map for the data points, but a uniform color instead, by default None. cmap takes precedence!

  • ci_color (str, tuple, optional) – Color of the linear fit with seaborn’s regplot, by default “#cccccc”

  • ci_alpha (float, optional) – Alpha of linear fit, by default 0.6

  • save_as (str, optional) – Save as file, by default None

  • invert (bool, optional) – By default, we’ll assume your input data represents voxels from CSF to WM. This flag can flip that around, by default False

Example

# lump events together
lumped = fitting.NideconvFitter(
    df_ribbon,
    df_onsets,
    basis_sets='fourier',
    n_regressors=4,
    lump_events=True,
    TR=0.105,
    interval=[-3,17])

# plot
lumped.plot_hrf_across_depth(x_label="depth [%]")

# make a combined plot of HRFs and magnitude
fig = plt.figure(figsize=(16, 8))
gs = fig.add_gridspec(1, 2)
    >>>
ax = fig.add_subplot(gs[0])
lumped.plot_average_per_voxel(
    n_cols=None,
    axs=ax,
    labels=True,
    x_label="time (s)",
    y_label="magnitude",
    set_xlim_zero=False)
ax.set_title("HRF across depth (collapsed stimulus events)", fontsize=lumped.pl.font_size)
    >>>
ax = fig.add_subplot(gs[1])
lumped.plot_hrf_across_depth(
    axs=ax,
    order=1,
    x_label="depth [%]")
ax.set_title("Maximum value HRF across depth", fontsize=lumped.pl.font_size)
plot_ttp(df=None, axs=None, hrf_axs=None, ttp_lines=False, ttp_labels=None, figsize=(8, 8), ttp_ori='h', split='event_type', lines_only=False, par_kw={}, **kwargs)[source]
set_plotting_defaults()[source]

Initializes default settings for plot visualization.

Returns:

Stores plotting defaults in the object attributes.

Return type:

None

Example

fitter.set_plotting_defaults()
timecourses_condition()[source]

Computes condition-wise timecourses by averaging across runs and extracting subject-level and condition-level HRF responses from the model.

Stores timecourse data in object attributes:
  • self.tc_condition: Condition-wise average across subjects.

  • self.tc_subjects: Subject-level timecourses.

  • self.tc_mean: Mean timecourse (subject-level).

  • self.tc_sem: Standard error of the mean.

  • self.tc_std: Standard deviation.

  • self.sem_condition: SEM at condition level.

  • self.std_condition: STD at condition level.

  • self.time: Extracted time axis.

  • self.rsq_: R² values from model (if available).

  • self.ev_predictions: Event-level predictions (if OLS fit).

class lazyfmri.fitting.ParameterFitter[source]

Bases: InitFitter

Initializes the ParameterFitter class for estimating hemodynamic response function (HRF) parameters using an optimizer procedure.

Parameters:
  • func (pd.DataFrame) – Dataframe containing fMRI data indexed by subject, run, and time.

  • onsets (pd.DataFrame) – Dataframe containing onset timings indexed by subject, run, and event type.

  • TR (float, optional) – Repetition time (TR) of the fMRI acquisition, by default 0.105 seconds.

  • merge (bool, optional) – Whether to concatenate runs before parameter estimation, by default False.

  • verbose (bool, optional) – Whether to print additional information during processing, by default False.

  • *args (tuple) – Additional positional arguments.

  • **kwargs (dict) – Additional keyword arguments for parameter fitting.

Returns:

Initializes the object and stores parameters internally.

Return type:

None

Example

from lazyplot import fitting

# Initialize the fitter
nd_fit = fitting.ParameterFitter(
    func,
    onsets,
    merge=True,
    verbose=True
)
fit()[source]

Fits HRF parameters across subjects, runs, and event types.

Parameters:
  • debug (bool, optional) – If True, prints verbose messages during the fitting process, by default False.

  • **kwargs (dict) – Additional keyword arguments for HRF fitting.

Returns:

Stores fitted HRF parameters and model outputs as object attributes: - tc_subjects: Extracted HRF profiles for each subject. - ev_predictions: Event-specific model predictions. - estimates: Estimated HRF parameters. - tc_condition: Mean HRF timecourses across conditions. - sem_condition: Standard error of the mean (SEM) of timecourses. - std_condition: Standard deviation of timecourses.

Return type:

None

Example

nd_fit.fit(debug=True)
print(nd_fit.tc_subjects)
static single_response_fitter()[source]

Fits a single HRF response using the FitHRFparams optimizer.

Parameters:
  • data (np.ndarray or pd.DataFrame) – Functional data, either a NumPy array or a Pandas DataFrame with time-series data.

  • onsets (pd.DataFrame) – Dataframe containing onset timings indexed by subject, run, and event type.

  • TR (float, optional) – Repetition time (TR) of the fMRI acquisition, by default 0.105 seconds.

  • **kwargs (dict) – Additional keyword arguments for HRF fitting.

Returns:

A fitted HRF parameters object.

Return type:

FitHRFparams

Example

from lazyplot.fitting import FitHRFparams

# Fit single HRF response
fitted_hrf = ParameterFitter.single_response_fitter(func, onsets, TR=0.105)
lazyfmri.fitting.double_gamma_with_d(a1, a2, b1, b2, c, d1, d2, x=None, negative=False)[source]
lazyfmri.fitting.error_function(parameters, args, data, objective_function)[source]
Parameters:
  • parameters (list or ndarray) – A tuple of values representing a model setting.

  • args (dictionary) – Extra arguments to objective_function beyond those in parameters.

  • data (ndarray) – The actual, measured time-series against which the model is fit.

  • objective_function (callable) – The objective function that takes parameters and args and produces a model time-series.

Returns:

error – The residual sum of squared errors between the prediction and data.

Return type:

float

lazyfmri.fitting.fwhm_lines(fwhm_list, axs, cmap='viridis', color=None, **kwargs)[source]

Iterative search function to find the best set of parameters that describe the HRF across a full timeseries. During the optimization, each parameter is adjusted and a new prediction is formed until the variance explained of this prediction is maximized.

Parameters:
  • data (np.ndarray) – Input must be an array (voxels,timepoints)

  • onsets (pd.DataFrame) – Dataframe indexed on subject, run, and event_type (as per lazyfmri.dataset.ParseExpToolsFile)

  • verbose (bool, optional) – Print progress to the terminal, by default False

  • TR (float, optional) – Repetition time, by default 1.32

  • osf (int, optional) – Oversampling factor to account for decimals in onset times, by default 100

  • starting_params (list, optional) – Starting parameters of the HRF, by default [6,12,0.9,0.9,0.35,5.4,10.8]. This is generally a good start.

  • n_jobs (int, optional) – Number of jobs to use, by default 1

  • bounds (list, optional) – Specific bounds for each parameter, by default None

  • resample_to_shape (int, optional) – Resample the final profiles to a certain shape, by default None

  • xtol (float, optional) – x-tolerance of the fitter, by default 1e-4

  • ftol (float, optional) – f-tolerance of the fitter, by default 1e-4

  • interval (list, optional) – Interval used to define the full HRF profile, by default [0,30]

  • read_index (bool, optional) – Copy the index from the input dataframe, by default False

lazyfmri.fitting.make_prediction(parameters, onsets=None, scan_length=None, TR=1.32, osf=1, cov_as_ampl=None, negative=False, interval=[0, 25])[source]