# adding montage and fiducials in bids format

**URL:** <https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102>\
**Category:** Support & Discussions\
**Tags:** mne-bids, montage\
**Created:** [June 18, 2023, 8:23pm UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102 "2023-06-18T20:23:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![JonasP](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@JonasP](https://mne.discourse.group/u/JonasP)\
**Post date:** [June 18, 2023, 8:23pm UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102/1 "2023-06-18T20:23:34Z")

</div>

- MNE version: 1.4.2
- operating system: Windows 10 / Ubuntu 22.04.2 LTS

Dear MNE community,

I am using mne/mne-bids to convert my data (from a TMSi SAGA in Poly5 format) to BIDS. Where I get stuck is in defining the electrode placements and properly document recorded fiducials.  
We use an easycap with standard 10-20 electrode layout and have recorded lpa/rpa/nasion with Localite neuronavigation.

However, a couple of things tell me I am doing something wrong.  
_First_, the electrodes are documented as being stored in CapTrak space, even though the standard montage in mne that I use should be defined in fsaverage space.  
_Second_, when I try to register the electrodes to the individuals MRI, it does not look very good, not what I would expect after transforming from fsaverage to individual freesurfer space.

This is roughly what I did:

First, I import the standard 10-20 montage and add it to my raw data:

```python
mont=mne.channels.make_standard_montage('standard_1020')
raw.set_montage(mont)

```

…and write it in bids format:

```python
write_raw_bids(raw, bids_path=[my bids path],event_id=event_id,allow_preload=True,
               format='BrainVision',overwrite=True)

```

I also add fiducials recorded with neuronavigation software to the T1w sidecar:

```python
entries = {
    'AnatomicalLandmarkCoordinates': {
        'NAS': [],
        'LPA': [],
        'RPA': []
    }
}

anat_nii=anat_folder.copy().update(extension='.nii.gz')
nif=nib.load(anat_nii)
nii_mat=nif.header.get_qform()
fiducial_voxels=fiducials
for idx,fid in enumerate(fiducials):
    coord=np.append(np.reshape(fid, (3,-1)),[[1]],axis=0)
    fiducial_voxels[idx,:]=np.reshape(np.linalg.lstsq(nii_mat,coord,rcond=0)[0][0:3],[1,3])

landmarks = mne.channels.make_dig_montage(lpa=fiducial_voxels[0],nasion=fiducial_voxels[1],rpa=fiducial_voxels[2],coord_frame="mri_voxel")
anat_folder = BIDSPath(subject=subject,session=session,datatype='anat',acquisition='lowres',suffix='T1w',root=bids_folder)
anat_sidecar = anat_folder.copy().update(extension='.json')
update_sidecar_json(bids_path=anat_sidecar, entries=entries)
update_anat_landmarks(anat_folder, landmarks)

```

I notice that fiducials have been added to the ‘coordsystem.json’ as well. I guess they are part of the standard monetage then?

Now, I try to read the bids formatted data and calculate transforms from standard electrode placements to the individual MRI:

```python
raw=read_raw_bids(eeg_data)

trans=get_head_mri_trans(eeg_data, 
                   t1_bids_path=t1_data, 
                   fs_subject=subject, 
                   fs_subjects_dir=fsdir)

```

…and plot the results:

```python
fig = mne.viz.plot_alignment(
    raw.info,
    trans=trans,
    subject=subject,
    subjects_dir=fsdir,
    show_axes=True,
    dig='fiducials',
    mri_fiducials=True,
    coord_frame="mri",
)

```

And this is the result:

 ![fiducials](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/5/531d9b6aa08de004080f8f39319cbbdb20d90e3e.jpeg)

Is there anthing obviously wrong with my approach or are the results to be expected?

Any help is much appreciated!

---

<div class="post-metadata">

**Author:** ![sappelhoff](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/sappelhoff/32/3276_2.png) [@sappelhoff](https://mne.discourse.group/u/sappelhoff)\
**Post date:** [June 19, 2023, 8:58am UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102/2 "2023-06-19T08:58:30Z")

</div>

> [@JonasP](#):
>
> I notice that fiducials have been added to the ‘coordsystem.json’ as well. I guess they are part of the standard monetage then?

yes, it seems like they are: [https://github.com/mne-tools/mne-python/blob/bb1d54798e56b2854cba76d0f3b12a383b8bb96f/mne/channels/data/montages/standard\_1020.elc#L104-L106](https://github.com/mne-tools/mne-python/blob/bb1d54798e56b2854cba76d0f3b12a383b8bb96f/mne/channels/data/montages/standard_1020.elc#L104-L106)

> [@JonasP](#):
>
> Is there anthing obviously wrong with my approach or are the results to be expected?

Why have you recorded the fiducial positions, but not the electrode positions? You are now trying to mix true, recorded (digitized) fiducial positions with template positions that have nothing to do with your study participant 🤔 I haven’t come across an approach like that and I am wondering what the advantages of this are.

Another complicating factor is that the MNE-Python 10-20 template positions are not “idealized” positions (e.g., computed on a sphere as in [GitHub - sappelhoff/eeg\_positions: Compute and plot standard EEG electrode positions.](https://github.com/sappelhoff/eeg_positions)), but based on “realistic” positions. A good read for this topic can be found here (it’s an ongoing problem):

- [Built-in, standard, and template montages, and layouts 🤯 · Issue #10741 · mne-tools/mne-python · GitHub](https://github.com/mne-tools/mne-python/issues/10741)
- [For all built-in EEG montages, describe whether they're based on idealized or (at least somewhat) realistic coordinates, and whether or not they might be a good idea for source modeling · Issue #10752 · mne-tools/mne-python · GitHub](https://github.com/mne-tools/mne-python/issues/10752)

> [@JonasP](#):
>
> _First_, the electrodes are documented as being stored in CapTrak space, even though the standard montage in mne that I use should be defined in fsaverage space.

This is probably a problem on the side of mne-bids.

Unfortunately dealing with digitized sensor positions is not very advanced in MNE-BIDS … one could call it a “work in progress”, but it’s been in progress for quite a while, because it is a relatively complex undertaking that requires input from many different people. So far, none of us volunteers was motivated or hard-pressed enough to take this on fully.

Some issues to read through may be:

- [Montage coordinate frames are saved wrongly · Issue #961 · mne-tools/mne-bids · GitHub](https://github.com/mne-tools/mne-bids/issues/961)
- [If no electrode positions are specified in the BIDS dataset metadata (electrodes.tsv), we should remove the montage upon loading the data · Issue #1040 · mne-tools/mne-bids · GitHub](https://github.com/mne-tools/mne-bids/issues/1040)
- [?Bug? Setting landmark coordinates in coord\_frame 'mri' for ecog/seeg channels results in Captrak coordframe · Issue #676 · mne-tools/mne-bids · GitHub](https://github.com/mne-tools/mne-bids/issues/676)

Finally, my practical advice for you when dealing with coordinate systems and mne-bids and it _doesn’t_ work out of the box is to:

1. report this issue (as you did), and hope that somebody (maybe even you?) will fix it eventually
2. proceed with your work by writing custom code and not relying on mne-bids for this particular aspect

---

<div class="post-metadata">

**Author:** ![JonasP](https://avatars.discourse-cdn.com/v4/letter/j/dbc845/32.png) [@JonasP](https://mne.discourse.group/u/JonasP)\
**Post date:** [June 19, 2023, 12:49pm UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102/3 "2023-06-19T12:49:08Z")

</div>

Thank you, this is very helpful!

It clarifies some things for me. My idea with recording fiducials was that they would allow for finding (nonlinear) transforms from template space to individual MRI space. But since the montage that I use is defined on fsaverage, this indeed seems redundant.

If I understand things correctly, I should manually changing the coordsystem.json for now.

What I am still struggling with is the correct approach when not having electrode positions recorded but an available MRI image. Would it make sense to run freesurfer on the individual MRI and use fsaverage to subject transforms on the standard 1020 montage to map that to subject MRI space? Seems like that would be the most accurate without recording actual eletrode placements.

I will make sure to read up on your suggestions, I wasn’t even aware of the idealized vs realistic issue.

Best regards,  
Jonas

---

<div class="post-metadata">

**Author:** ![sappelhoff](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/sappelhoff/32/3276_2.png) [@sappelhoff](https://mne.discourse.group/u/sappelhoff)\
**Post date:** [June 19, 2023, 1:19pm UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102/4 "2023-06-19T13:19:42Z")

</div>

> [@JonasP](#):
>
> What I am still struggling with is the correct approach when not having electrode positions recorded but an available MRI image. Would it make sense to run freesurfer on the individual MRI and use fsaverage to subject transforms on the standard 1020 montage to map that to subject MRI space? Seems like that would be the most accurate without recording actual eletrode placements.

I don’t really have experience with that, so I have my fingers crossed for your that somebody else stumbles over this and can be of help. 🙂

---

<div class="post-metadata">

**Author:** ![mainakjas](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/mainakjas/32/34_2.png) [@mainakjas](https://mne.discourse.group/u/mainakjas)\
**Post date:** [June 19, 2023, 1:42pm UTC](https://mne.discourse.group/t/adding-montage-and-fiducials-in-bids-format/7102/5 "2023-06-19T13:42:50Z")

</div>

While the approach sounds reasonable from a data analysis perspective, I don’t think it’s a good idea to store a standard montage in BIDS format as if it were digitized electrodes. (In fact, MNE aligns the montage using the LPA/RPA/nasion, so what you propose might already be done under the hood in raw.set\_montage). That has the potential to be confusing for folks consuming the data downstream.

Mainak
