Core Workflow
This page describes the intended lifecycle of a typical ffTRF analysis from
raw arrays to a saved model.
1. Organize Your Data
ffTRF expects matched stimulus/response pairs.
- For single-trial data, pass a single NumPy array.
- For multi-trial data, pass a list of arrays.
- Within one fit, each stimulus trial and its matching response trial must have the same number of samples.
- Across trials, sample counts may differ.
The predictor side should be shaped (n_samples, n_features) and the target
side (n_samples, n_outputs).
2. Choose Modeling Direction
Construct the estimator with:
TRF(direction=1)for forward encoding: stimulus predicts responseTRF(direction=-1)for backward decoding: response predicts stimulus
This choice affects how train(...), predict(...), score(...), and the
diagnostic methods interpret stimulus and response.
3. Fit the Model
The main entry point is train(...).
Use a direct fit when you already know the ridge value:
model.train(
stimulus=stimulus,
response=response,
fs=fs,
tmin=0.0,
tmax=0.150,
regularization=1e-3,
)
Use cross-validation when you want the model to select a ridge value:
scores = model.train(
stimulus=stimulus,
response=response,
fs=fs,
tmin=0.0,
tmax=0.150,
regularization=np.logspace(-6, 0, 7),
k="loo",
segment_duration=1.024,
overlap=0.5,
)
Important fit-time choices:
tmin/tmax: lag window of the recovered kernelregularization: scalar ridge or CV gridsegment_length/segment_duration: spectral segment sizeoverlap: segment reusebands: grouped feature regularizationtrial_weights: how much each trial contributes
4. Inspect the Fitted Kernel
After fitting, the instance stores:
model.transfer_function: complex frequency-domain solutionmodel.frequencies: corresponding frequency axismodel.weights: lag-domain kernelmodel.times: lag axis in seconds
Use:
plot(...)for a single input/output pairplot_grid(...)for a full gridto_impulse_response(...)to extract a different lag window without refitting
5. Predict and Score
Use:
predict(...)when you want the predicted signalsscore(...)when you only want the metricpermutation_test(...)when you want a surrogate-null significance check for a held-out scorerefit_permutation_test(...)when you want the stronger retrain-and-score null
If you pass observed targets to predict(...), it returns both predictions and
the score.
6. Inspect Frequency-Domain Behavior
The model can also be explored spectrally:
transfer_function_at(...)transfer_function_components_at(...)plot_transfer_function(...)cross_spectral_diagnostics(...)plot_coherence(...)plot_cross_spectrum(...)
These methods are especially useful when you care about gain, phase, coherence, or whether the model reproduces the observed output spectrum.
7. Quantify Uncertainty and Significance
If you have multiple trials, you can estimate a trial-bootstrap confidence interval:
- during fitting with
bootstrap_samples=... - after fitting with
bootstrap_confidence_interval(...)
The stored interval can then be shown in kernel plots or extracted with
bootstrap_interval_at(...).
If you want to know whether a held-out prediction score beats a surrogate null
distribution, use permutation_test(...) on the evaluation data.
If you want the null to include retraining and regularization selection, use
refit_permutation_test(...) with explicit train/test splits.
8. Save or Copy the Model
save(...)serializes the estimator with pickleload(...)restores a saved estimator statecopy(...)creates an in-memory deep copy
A Good First Workflow
For many users, a good default sequence is:
- start with
TRF(direction=1) - fit with a small CV grid over ridge values
- inspect one kernel with
plot(...) - compute held-out performance with
score(...) - inspect coherence with
plot_coherence(...) - save the trained model