Setup

using Unfold
using UnfoldMakie, CairoMakie
using UnfoldSim
using UnfoldDecode
using DataFrames
using Statistics

Quick start of Back-To-Back (b2b)

Data generation

Simulation and data collection

Generate single channel data via UnfoldSim.jl

dat, evts = UnfoldSim.predef_eeg(; noiselevel = 0.1, return_epoched = true);

dat is a time x repetition Matrix, evts is a DataFrame`with independent variables / features to explain the data

Dimension expansion

Repeat the dat 20 times, representing 20 channels. In the future we will replace this with a direct multi-channel simulation.

dat_3d = permutedims(repeat(dat, 1, 1, 20), [3 1 2]);

Channels shouldnt be identical, so we add some noise.

dat_3d .+= 0.1 * rand(size(dat_3d)...);

Modeling

Solver selection

Call b2b solver in UnfoldDecode

b2b_solver = (x, y) -> UnfoldDecode.solver_b2b(x, y; cross_val_reps = 5);
Hint

one could specify the specific solvers for G and H by passing the solver_G and solver_H parameters to the solver_b2b function. Implemented solvers are ridge, lasso, lsq, svm, but other solvers from MLJ.jl can be used as well.

Generate the formula

We want to decode condition, but simultaneously control for the effect of continuous.

f = @formula 0 ~ 1 + condition + continuous
time = range(0, 0.44, step = 1 / 100)
designDict = [Any => (f, time)]

m = Unfold.fit(UnfoldModel, designDict, evts, dat_3d; solver = b2b_solver);

results = coeftable(m);
results.estimate = abs.(results.estimate); ## back2back has no sign
results = results[results.coefname.!="(Intercept)", :] ## the intercept in b2b is hard to interpret
90×7 DataFrame
Rowchannelcoefnameestimateeventnamegroupstderrortime
Int64StringFloat64DataTypeNothingNothingFloat64
11condition: face0.000276096Any0.0
21condition: face0.00121805Any0.01
31condition: face0.00905281Any0.02
41condition: face0.00492913Any0.03
51condition: face0.000306879Any0.04
61condition: face0.0011858Any0.05
71condition: face0.00734451Any0.06
81condition: face0.00833586Any0.07
91condition: face0.00952535Any0.08
101condition: face0.00563764Any0.09
111condition: face0.0590155Any0.1
121condition: face0.187331Any0.11
131condition: face0.576066Any0.12
141condition: face0.304674Any0.13
151condition: face0.269461Any0.14
161condition: face0.27268Any0.15
171condition: face0.27276Any0.16
181condition: face0.286085Any0.17
191condition: face0.310983Any0.18
201condition: face0.389116Any0.19
211condition: face0.0400523Any0.2
221condition: face0.0209925Any0.21
231condition: face0.00728841Any0.22
241condition: face0.00631977Any0.23
251condition: face0.00666009Any0.24
261condition: face0.00641612Any0.25
271condition: face0.00634659Any0.26
281condition: face0.00605966Any0.27
291condition: face0.0064253Any0.28
301condition: face0.00661277Any0.29
311condition: face0.00657537Any0.3
321condition: face0.0062685Any0.31
331condition: face0.00681632Any0.32
341condition: face0.00674751Any0.33
351condition: face0.00723387Any0.34
361condition: face0.00693519Any0.35
371condition: face0.00673979Any0.36
381condition: face0.00701447Any0.37
391condition: face0.00625599Any0.38
401condition: face0.00684818Any0.39
411condition: face0.00893697Any0.4
421condition: face0.00750376Any0.41
431condition: face0.0104718Any0.42
441condition: face0.024929Any0.43
451condition: face0.0225599Any0.44
461continuous0.000147515Any0.0
471continuous6.21685e-5Any0.01
481continuous0.000455905Any0.02
491continuous4.37426e-5Any0.03
501continuous0.000123742Any0.04
511continuous1.94433e-5Any0.05
521continuous8.24115e-5Any0.06
531continuous1.53654e-6Any0.07
541continuous7.52518e-6Any0.08
551continuous0.00014592Any0.09
561continuous8.25061e-7Any0.1
571continuous0.000104262Any0.11
581continuous5.49448e-6Any0.12
591continuous0.0001882Any0.13
601continuous1.16102e-6Any0.14
611continuous6.31581e-5Any0.15
621continuous1.56448e-6Any0.16
631continuous0.000599661Any0.17
641continuous0.00728231Any0.18
651continuous0.0978105Any0.19
661continuous0.854214Any0.2
671continuous0.355671Any0.21
681continuous0.282977Any0.22
691continuous0.285093Any0.23
701continuous0.278331Any0.24
711continuous0.282962Any0.25
721continuous0.284605Any0.26
731continuous0.284962Any0.27
741continuous0.283158Any0.28
751continuous0.281591Any0.29
761continuous0.284366Any0.3
771continuous0.282344Any0.31
781continuous0.284764Any0.32
791continuous0.285409Any0.33
801continuous0.281967Any0.34
811continuous0.280067Any0.35
821continuous0.281299Any0.36
831continuous0.274928Any0.37
841continuous0.278807Any0.38
851continuous0.267941Any0.39
861continuous0.259431Any0.4
871continuous0.239387Any0.41
881continuous0.1926Any0.42
891continuous0.0523001Any0.43
901continuous0.000115614Any0.44

Plotting

plot_erp(results; axis = (xlabel = "Time [s]", ylabel = "Performance"))
Example block output

We can see from the graph that b2b solver identifies regions where the signal can be decoded, taking into account the continuous feature


This page was generated using Literate.jl.