Apply alignment EEG positions to fsaverage

Hi everyone,

I have scanned the positions of my electrodes using a 3D scan like the one use in fieldtrip (Localizing electrodes using a 3D-scanner - FieldTrip toolbox). As it is described in that tutorial, the coordinate system in which my electrode positions are after is the CTF system.

Now, what I have done, is import the locations into mne and using the code you see below, to add the positions to my raw data.

After that, I have used the fig = mne.viz.plot_alignment(...) to align it to the fsaverage, since I have the individual EEG positions but not the individual MRI.

However, what I don’t understand or I don’t know how to do, is how can I now save the “aligned” positions to my raw dataset. Are these already saved but not applied?

I want to do this, before I continue with my preprocessing (next step is ICA), since afterwards, we will perform source reconstruction.

# Load the json file
with open(pathOut + f'{partID}/' + f'sub-{participant}_positionElectrodes_NEW_fiducials.json') as f:
    mat_file = json.load(f)

factorUnits = 1000  # Convert mm to m
elecpos_data = np.array(mat_file['elecpos']).reshape(67,3) / factorUnits

# Ensure channel names match those in the raw data
ch_names = mat_file['label']

# Create a dictionary with channel names as keys and 3D coordinates as values
channel_positions = {ch_names[i]: elecpos_data[i] for i in range(len(ch_names))}

#Find indices for the fiducial points

nas = channel_positions['nas']
lpa = channel_positions['lpa']
rpa = channel_positions['rpa']

#%% Montage creation and alignment
# Create a new montage with the rotated positions
montage = mne.channels.make_dig_montage(ch_pos=channel_positions, nasion=nas, lpa=lpa, rpa=rpa)

raw.set_montage(montage)
raw.set_eeg_reference(projection=True)  # needed for inverse modeling

#SECOND PART CODE
# Step 1: Download and set the fsaverage template MRI
subject = 'fsaverage'
subjects_dir = r'C:\Users\HuertasPenenS\mne_data\MNE-fsaverage-data'
src = r'C:\Users\HuertasPenenS\mne_data\MNE-fsaverage-data\fsaverage\bem\fsaverage-ico-5-src.fif'
# Load transformation matrix
trans = r'C:\Users\HuertasPenenS\mne_data\MNE-fsaverage-data\fsaverage\bem\fsaverage-trans.fif'


# Step 4: Plot the alignment (head surface and EEG electrodes)
fig = mne.viz.plot_alignment(
    raw.info,
    subject=subject,
    subjects_dir=subjects_dir,
    src = src,
    surfaces=['head'],   # Plot the head surface
    coord_frame='mri',   # Use MRI coordinate frame
    eeg=['original','projected'],    # Plot EEG electrodes
    trans=trans, # Use the identity transformation matrix
    show_axes=True,
    mri_fiducials=True,
    dig="fiducials",
)
  • MNE VERSION: 1.7.1
  • WINDOWS: 11
1 Like

If you have nasion, lpa, and rpa, you can transform your coordinate system to the “head” coordinate system that MNE-Python uses. Try this code:

from mne.channels.montage import transform_to_head
montage = transform_to_head(montage)

xref: DigMontages: information on coordinate systems; Document `transform_to_head` in API docs · Issue #12904 · mne-tools/mne-python · GitHub

What do you mean by this? mne.viz.plot_alignment by itself does not do any alignment, it just shows your alignment, given a specific source space (in your case fsaverage)

Do you mean you performed some co-registration? For example, where did you get r'C:\Users\HuertasPenenS\mne_data\MNE-fsaverage-data\fsaverage\bem\fsaverage-ico-5-src.fif' from? Did you save that?

I actually don’t know this. I suspect it has something to do with the apply_trans method.

@larsoner, can you perhaps shed some light on this? I think the steps would need to be:

  1. Obtain digitized electrode locations
  2. Read them into MNE-Python as a DigMontage, and transform to “head” space
  3. Co-register them to fsaverage (does this actually NEED to be done, or can this be automatic if the electrode locations are in “head” space?)
  4. Somehow apply a transformation (the one obtained from co-registration) to the DigMontage
  5. …?

Do we have a tutorial on this?

Yes, good point … however note that for the ICA itself, the electrode locations do not matter: ICA can also work if you do not have any electrode locations. We only use the locations to plot topographic maps of the independent components … and for this purpose, a more coarsely resolved “map” already suffices (as we are projecting to 2D anyhow and this is already only an approximation).

1 Like

However, what I don’t understand or I don’t know how to do, is how can I now save the “aligned” positions to my raw dataset. Are these already saved but not applied?

All you should need to do is raw.set_montage(...), then you have your points in head space. If plot_alignment(..., trans="fsaverage") looks okay then you’re good. This is because we know the location of LPA/Nasion/RPA for fsaverage so the head-to-MRI trans is known, assuming your digitized locations of those same locations are correct (and match what we think they are for fsaverage). As long as you pass trans='fsaverage' elsewhere (e.g., in forward modeling) things should be accounted for properly.

Do we have a tutorial on this?

https://mne.tools/stable/auto_tutorials/forward/35_eeg_no_mri.html

1 Like