-
Notifications
You must be signed in to change notification settings - Fork 5
Project structure
This page provides an overview of the software structure of BrainTrak. BrainTrak is based around object-oriented programming (OOP). You will need a working understanding of fundamental OOP concepts such as classes, methods, and inheritance. See here for some information about these. It will be very difficult to understand how BrainTrak works if you do not understand these concepts.
Having read about the theory, you should have an idea of some of the essential components in fitting. To perform fitting, we need (as a minimum) the following components:
- A set of spectra (data)
- A model consisting of a function that takes in parameters and returns a predicted spectrum
- A function that compares the spectrum to the data to compute chisq
- A function that computes the probability based on chisq and the prior
- A function that implements the MCMC random walk
- A function that selects the best fit from the random walk
- A function that incrementally updates the priors and records successive fits
- A set of analysis routines to display the model results
We also need the system to be capable of quickly implementing and testing different models. We can separate the items above into three independent categories
- The model, which defines the mapping from parameters to the predicted spectrum, and does not depend on the data or the fitting algorithm. There may be many different models you want to test.
- The fitting algorithm which defines how to compute the random walk, how to select the best fit, and how to update the priors, which does not depend on the data or the model.
- The data, which is obtained from experiments and is thus independent of the model and of the fitting algorithm. The data are stored in
.mat
files, and there may be many of them.
A single run of BrainTrak corresponds to selecting one of each of these components - you run BrainTrak with one model, using a single fitting algorithm, applied to one set of data.
There are also the analysis routines that are weakly dependent on the choice of both model and data, but the key concept is that BrainTrak returns a single type of result, which can then be used by any of the analysis routines.
These components are all reflected in the structure of the code
- The models are objects whose definitions are contained in
braintrak/+bt/+model
. For example,bt.model.full
is the representation of one particular model - The fitting algorithm consists of the files in
braintrak/+bt/+core/
- The data themselves are stored on disk wherever the user likes. In
braintrak/+data/
, the filesget_tfs.m
,import_raw_eeg.m
andelectrode_positions.m
relate to converting raw EEG data into a format that BrainTrak can use. - The storage of the fit outputs and the analysis routines are implemented by the
feather
object inbraintrak/+bt/@feather
, and by theviewer
object inbraintrak/+bt/@viewer
- Functions and scripts in
braintrak/+bt
relate to specific applications of BrainTrak
Detailed information about the models are provided here. In brief, a model
is an object that has a number of methods, including
- A list of parameters
- Their initial values
- Criteria for validating the parameters e.g. limits on their values
- A function (method) that computes the spectrum given the model parameters
Essentially, a model
object is a complete representation of the particular neural field model. The standard interface is provided in template.m
, which specifies the functions/methods that all models must implement. Specific models then inherit from template
and provide the implementation of the model. The model object can then be passed around to the various BrainTrak functions.
Detailed information about the fitting process is provided here. At a high level, there are three primary uses for BrainTrak
- Computation of the random walk and generation of the chain is performed by
chain.m
andchain_parallel.m
- A minimal fit is generated by
fit_spectrum.m
which callschain.m
. This function takes in a spectrum
Typically, you would not use the core functions directly. Instead, you would write other scripts and functions that use these core routines. For example
-
+bt/fit.m
shows a minimal fitting example, taking in a model, a spectrum, and optionally the length of the chain (i.e., how long to run the routine for) -
+bt/fit_track.m
shows common usage of BrainTrak, where a data set is automatically loaded and preprocessed, and then a sequence of spectra is fitted with incremental prior updates.
Additional wrappers for these routines are provided in braintrak/data_examples
(for fitting various data sets), and braintrak/published/Abeysuriya_2015
which contains wrappers used to generate the fits published in Abeysuriya (2015).
More information about how the data is processed is available here. Data files are generated using +bt/+data/import_raw_eeg.m
which in turn uses get_tfs.m
. This workflow also implements the artifact rejection scheme described in Abeysuriya (2015). The output is saved to a .mat
file, an example of which is provided in the repository as braintrak/demo.mat
.
The output file contains data for all of the electrodes in the original raw EEG files, but typically you would only want to fit different subsets of electrodes. Also, there may be extended periods of wakefulness at the start of sleep recordings, or you might want to pre-process or select various subsets of the data prior to fitting. Therefore, the .mat
files are typically loaded via a function like bt.core.load_subject
. For example, load_subject()
- Takes in a list of electrode names to retain in the data
- Automatically truncates extended periods of wake at the start of sleep recordings from particular data sets
More information about analysis is available here. The fit output is generated by bt.core.fit_spectrum
and consists broadly of two parts
-
fit_data
which contains the fitted parameter values, the posterior distributions, goodness of fit statistics, information about the simulation performance and runtime -
plot_data
which contains counts in XYZ bins used to draw the clouds in XYZ. These variables are very large compared tofit_data
and may be stored separately for very long trajectories.
These variables are returned by fit_spectrum.m
. However, you often need to work with many of them e.g. if you have a trajectory, you would have one of these variables for each of the spectra you fitted, and they would be in a meaningful sequence. Therefore, BrainTrak provides an object to store these outputs, called feather
(named for historical reasons - see here). This object has a number of methods to plot and manipulate multiple fits, which makes it a convenient way to interact with the outputs generated by BrainTrak.
Now that you know what the key software components in BrainTrak are, proceed on to try out various workflows in BrainTrak.