Skip to content

EEG Data Structures

Understanding EegFun.jl's core data structures.

Julia Types

If you're coming from Python or MATLAB, Julia's type system works a little differently. The full details are in the Julia documentation, but the key idea for everyday EegFun.jl use is multiple dispatch.

This means a function can have the same name but do different things depending on the type of data passed to it.

In Julia function signatures, the :: notation means "this argument must be of this type":

julia
plot_erp(erp::ErpData)         # plots a single ERP
plot_erp(erp::Vector{ErpData}) # plots multiple ERPs overlaid

Here erp::ErpData means "an argument called erp of type ErpData". Julia automatically selects the right function version based on what you pass in — you never need to call a different function name.

More examples from EegFun.jl:

julia
# Same function, different input types → different behaviour
plot_topography(erp::ErpData, ...)          # plots ERP topography
plot_topography(tf::TimeFreqData, ...)      # plots time-frequency topography

average_epochs(dat::EpochData)              # averages a single condition
average_epochs(dat::Vector{EpochData})      # averages multiple conditions

extract_epochs(dat::ContinuousData, ...)    # extracts from continuous recording

Both are called plot_erp — Julia picks the right function version automatically based on what you pass in. You never need to call a different function name.

If you're ever unsure what type a variable is, use typeof():

julia
typeof(my_data)   # e.g. EegFun.ContinuousData

This is useful when reading error messages — if Julia says "no method matching plot_erp(::ContinuousData)" it means you passed the wrong type, and typeof() can help you check what you actually have.

Abstract vs Concrete Types

Julia also distinguishes between concrete and abstract types:

  • Concrete types are the actual data structures you create and work with — for example ContinuousData, ErpData, or EpochData. These hold real data.

  • Abstract types are categories or groupings — you can never create one directly, but they let functions accept a family of related types. For example, EegData is abstract; it simply says "any EEG data type".

This matters in practice because a function written for EegData will work on any concrete EEG type — ContinuousData, ErpData, etc. — without needing a separate version for each one.


Type Hierarchy

EegFunData (abstract)
└── EegData (abstract) - All EEG data types
    ├── SingleDataFrameEeg (abstract) - Data in a single DataFrame
    │   ├── ContinuousData - Raw continuous recordings
    │   ├── ErpData - Averaged event-related potentials
    │   ├── TimeFreqData - Time-frequency decomposition
    │   └── SpectrumData - Power spectrum
    └── MultiDataFrameEeg (abstract) - Data across multiple DataFrames
        ├── EpochData - Trial-segmented data
        └── TimeFreqEpochData - TF with individual trials

See the Types Reference for full field-by-field documentation of each type.

ContinuousData

Raw, unsegmented EEG recordings.

FieldTypeDescription
fileStringSource filename
dataDataFrameContinuous data (time × channels)
layoutLayoutElectrode positions and neighbors
sample_rateInt64Sampling frequency in Hz
analysis_infoAnalysisInfoPreprocessing metadata

EpochData

Trial-segmented data for event-related analysis.

FieldTypeDescription
fileStringSource filename
conditionInt64Condition number
condition_nameStringHuman-readable condition name
dataVector{DataFrame}One DataFrame per epoch
layoutLayoutElectrode positions
sample_rateInt64Sampling frequency in Hz
analysis_infoAnalysisInfoPreprocessing metadata

ErpData

Averaged event-related potentials.

FieldTypeDescription
fileStringSource filename
conditionInt64Condition number
condition_nameStringHuman-readable condition name
dataDataFrameAveraged ERP (time × channels)
layoutLayoutElectrode positions
sample_rateInt64Sampling frequency in Hz
analysis_infoAnalysisInfoPreprocessing metadata
n_epochsInt64Number of epochs averaged

TimeFreqData

Time-frequency decomposition results.

FieldTypeDescription
fileStringSource filename
conditionInt64Condition number
condition_nameStringHuman-readable condition name
data_powerDataFramePower values (time × freq × channels)
data_phaseDataFramePhase values in radians
layoutLayoutElectrode positions
sample_rateInt64Original sampling frequency
methodSymbolAnalysis method (:wavelet, :multitaper, etc.)
baselineBaselineInfoBaseline correction info (if applied)
analysis_infoAnalysisInfoPreprocessing metadata

SpectrumData

Power spectral density (frequency domain only).

FieldTypeDescription
fileStringSource filename
conditionInt64Condition number
condition_nameStringHuman-readable condition name
dataDataFramePSD values (freq × channels)
layoutLayoutElectrode positions
sample_rateInt64Original sampling frequency
methodSymbolAnalysis method (:welch, etc.)
analysis_infoAnalysisInfoPreprocessing metadata

Layout

Electrode spatial information and neighbor relationships.

FieldTypeDescription
dataDataFramePositions with columns: label, x, y, z
neighboursUnion{Nothing, OrderedDict{Symbol,Neighbours}}Neighbor info per electrode
criterionUnion{Nothing, Float64}Distance criterion used to compute neighbors (mm)
criterion_typeUnion{Nothing, Symbol}Type of criterion (e.g. :xy, :xyz)

Data Flow

Raw EEG File (.bdf, .vhdr, .set, .mat)
    ↓ read_raw_data()
ContinuousData
    ↓ extract_epochs()
EpochData
    ↓ average_epochs()
ErpData

See Also