Dipoles, meshes, scouts and LFMs

I would like some analysis and advice on the project I am currently working on and how I can accomplish part of it with BSt. Narrowed to its essentials, we wish to train an EEG classifier (SVM, NN, etc.) to differentiate a subject's response to two classes (A and B) of stimuli, and then train the subject with neurofeedback to alter their EEG response to class A to make it more like class B's EEG response.
In order to get a good classification out of whatever classification scheme we use, we need to get a good set of features. My preference is always to transform the scalp EEG into source space, which is obviously where BSt comes in. We are using 64 EEG electrodes, and I wish to keep the number of features low, so my goal is to invert these into 64 source waves. We are not able to obtain MRIs to build a custom BEM model, nor will we be measuring individual 3D electrode locations. To achieve some semblance of geometric realism, though, I wish to use the BEM with a generic head and generic electrode locations.
From previous experience 15-20+ years ago, and fiddling around the past few weeks, I have managed to use the generic BEM with 15,002 dipoles, the already registered 10-5 electrode positions from the [ASA 10-5 343] set, to create the head model and compute the sources using the min-norm dSPM procedure. Beyond that, I was able to take the DKM atlas and remove all it's subcortical scouts to make a 63-scout custom "atlas" and apply it to the 15K source waves to get my reduced custom set of 63 source waves.
I would like to create and export a lead-field matrix that I could simply multiply any 64-channel EEG segment by to create the 63-channel source waves. I will need this for near real-time use in the neurofeedback "scenario".
At this point I have some questions:

  1. how do I export the final 63 scout source waves to Matlab so I can further process them?
  2. how do I export the LFM that transforms the 64 EEG waveforms into the 15,002 dipole waveform?
  3. I do not think creating a 64-scalpEEG to 63-source LFM, as stated above, is possible with what I have done so far. Might there be a way with existing BSt features? Maybe if I think deeply about it I could do it knowing the scout data structure.
    The straightforward way, to me, would be to reduce the cortical mesh to 63 (or so) patches, each representing a single source, and compute their sources. That will give me the LFM I need, I believe, but the fine geometric detail of the cortex will be lost.
    Hopefully you understand what I am looking for. Any help or analysis will be apprecaited.

This is done with the process Extract > Scout time series. See:

The inverse model is called an imaging kernel in Brainstorm; this is the matrix you are looking for. It is stored in the kernel file in the ImagingKernel field. So: sources = kernel * recordings

The cortical atlases are stored in the (cortical) surface file.
Each Scout consist on a list of the vertices that make the Scout
As such, if you want to aggregate the vertices in a Scout using a linear function (e.g., mean), then it will be possible to generate a matrix of the shape [nScouts, nSources], that can be multiplied with the kernel ([nSources, nChannels]) to obtain the transformation from Channels to Scouts.

Thank you for the locations of the files I asked about. I can complete items 1 and 2 now.

For item 3, I realized this technique will not give me what I think I need. An LFM (or kernel here) should be based only on the head geometry and its compartmental conductivities. By combining the scout (63x15002) and initial kernel matrices (64x15002) as you suggest (and I would have done as well) does not create a valid LFM - it is just creating something like the Scout process normally does (though I do not know how BSt performs the aggregation, probably not a simple mean?).

What I want to do is create a set of 63 distributed dipoles to feed into the inverse process. Each of these dipoles will be based on the cortical Scout atlas I created. I can do this myself in Matlab by taking the list of dipoles in each functional cortical patch and calculating their forward solution and adding the resultant scalp potentials together. The result will be an aggregated scalp topography produced by a unit activation of all the individual patch dipoles at the same time.

Here is the crux: I then need to be able to input this 63 (distributed dipole) patch x 64 channel matrix into the inverse process instead of the 15002 dipole x 64 channel matrix in order to create the LFM kernel I desire. Somehow I would have to fake BSt out to do this. This is my primary question to you now.


I have another question for this thread. How do I export the FORWARD models? I could not find documentation for this in the tutorial you shared above. I mainly want the 15002-vertex dipole cortex x 64-EEG channel one.

Regarding my item 3 above, do you understand what I am after here to create my distributed dipole source patches, or can I explain it better? Given the forward model I can create the 62 patches myself in Matlab, but the real trick will be to somehow insert them into BSt and create a kernel. If you cannot think of a way to do that, then I will have to do the min-norm calculation in Matlab, create the source waveforms there, and import those back into BSt for further processing.

Because that is in a different tutorial:

Thanks, I see I just need the Gain matrix.

I have a follow-up question. I realized yesterday that I overlooked something when I exported the Gain matrix and used it outside of BSt. In my previous post I had said I wanted the 15002-vertex x 64-channel matrix for the forward model. The Gain matrix for my set of electrodes is actually 62 channels x 45006, with three dipoles at each vertex. So, what I really wanted was the collapsed, or constrained version of this with dimensions 62 x 15002. To get that (back in Feb) I naively summed the three vertex dipole components. I knew better but was in a hurry and did not think it through. I believe I should instead take the dot-product of the 3 components with the GridOrient vector to get the correct value.
Can you please confirm this?

Also, I re-opened an older topic: "How to import other atlases to use as scouts". Can you please take a look at my new post there?

Going from unconstrained to constrained, sometimes is referred to as flattening, and this can be done in different ways, e.g., obtaining the L2-norm per vertex, using PCA per vertex.

You can use the following function:

  • bst_gain_orient(Gain, GridOrient): Apply orientation constraints.
1 Like

What you suggest is for after source imaging. I am just interested in the forward lead-field matrix.

This function is what I implemented on my own and asked about here. I tried it and got identical results. Thanks, this is more convenient.
Where is this documented? I am curious about the GridAtlas argument. I called bst_gain_orient without that and did not get an error.

It was at the bottom of the head model tutorial:

I can use it without the Gridatlas argument but am curious.
I looked at the bst_gain_orient doc at the link above, and there is no mention of the GridAtlas argument. What is that for? It shows when I ask for help at the Matlab command line:

help bst_gain_orient
bst_gain_orient: Constrain source orientation on a leadfield matrix

USAGE: Gain = bst_gain_orient(Gain, GridOrient, GridAtlas)

- Gain : [nChannels,3*nSources] leadfield matrix
- GridOrient : [nSources,3] orientation for each source of the Gain matrix
- Gain : [nChannels,nSources] leadfield matrix with fixed orientations

The GridAtlas parameter is used only for Mixed head models (mixed unconstrained and constrained regions)