Axial to planar gradiometer transformation#13196
Conversation
This is based on the channel positions and orientations provided by fieldtrip: https://github.com/fieldtrip/fieldtrip/blob/master/template/gradiometer/ctf275.mat
This is based on the channel positions and orientations provided by fieldtrip: https://github.com/fieldtrip/fieldtrip/blob/master/template/gradiometer/neuromag306.mat
|
Hello! 👋 Thanks for opening your first pull request here! ❤️ We will try to get back to you soon. 🚴 |
That way we can parse the txt files and select the channel type we want to interpolate to. For example we do not want to interpolate to the ch_type = 'ref' for the CTF.
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
|
Looks like you're making some progress, let me know when you'd like some feedback! |
|
Hi @larsoner! After a while, I finally found some time :) I think this is a good moment for some feedback. Issues / Questions I encountered: My initial understanding was that when we interpolate from CTF to Neuromag, the ch_type should already be known. This is because, CTF systems have reference sensors that should not be interpolated and Neuromag systems have gradiometers and magnetometers, so we need to know the type of each channel. That's why I added the ch_type parameter in the .txt montage files — to explicitly specify this. 2. Scope of interpolation: only gradiometers? Based on this, I thought I would input in 3. Limitations of make_dig_montage From the documentation of I understood that for my setup (no fiducials) I should use a custom montage. However: running 4. Custom _meg() function and related problems But now I run into new problems. When I run
5. I added _meg() inside _standard_montage_utils but am I allowed to change such private function ? 6. I am trying to follow how interpolate_to() code style and structure is already built. However, this forces us to diverge a bit from the standard One idea I had would be to encapsulate some logic in a new function |
Added new montage data files for CTF151, CTF275, and Neuromag306 systems in CSV format to mne/channels/data/montages/. These files provide sensor location and orientation information.
Introduces the read_meg_montage function to load canonical MEG sensor positions and orientations from CSV files for supported systems ('neuromag', 'ctf151', 'ctf275'). This utility constructs an Info object with sensor metadata for use in field interpolation.
for more information, see https://pre-commit.ci
I was on holidays. I will work on it in the next two weeks and then you can take over to do the final adjustments if necessary |
for more information, see https://pre-commit.ci
Moved EEG and MEG interpolation code from InterpolationMixin in channels.py to dedicated helper functions (_interpolate_to_eeg and _interpolate_to_meg) in interpolation.py.
larsoner
left a comment
There was a problem hiding this comment.
Just a couple of preliminary comments -- can you see if you can get CIs happy?
mne/channels/channels.py
Outdated
| def interpolate_to(self, sensors, origin="auto", method="spline", reg=0.0): | ||
| """Interpolate EEG data onto a new montage. | ||
| def interpolate_to( | ||
| self, sensors, origin="auto", method="MNE", mode="accurate", reg=0.0 |
There was a problem hiding this comment.
We can't change the method to "MNE" for EEG without a deprecation cycle. Let's make the default method=None which means under the hood (and in docs) "MNE for MEG sensors and spline for EEG".
mne/channels/interpolation.py
Outdated
| inst : instance of Raw, Epochs, or Evoked | ||
| A new instance with interpolated data. | ||
| """ | ||
| from .._fiff.meas_info import create_info |
There was a problem hiding this comment.
CIs complain that some imports are nested that should not be etc.
|
@contsili would it help if I pushed some commits here? Would be good to get this in! |
|
@larsoner yes it would help! The implementation is working, the only thing to be done is see why the tests are failing and adjust the code. Once you are done, I can chime in and finish whatever is left :) |
* upstream/main: (67 commits) DOC: Add jupyterlite idea to roadmap (mne-tools#13620) MAINT: Use f-strings in test_import_nesting.py (mne-tools#13551) Improve docs for raw.to_data_frame (mne-tools#13590) Sensitivity map doc improved (mne-tools#13578) [pre-commit.ci] pre-commit autoupdate (mne-tools#13612) MAINT: Fix for latest SciPy (mne-tools#13613) Fix pre-commit call in SPEC0 action [ci skip] (mne-tools#13609) MAINT: Add mne-denoise to CI dependencies (mne-tools#13607) FIX: do not cache canvas object (mne-tools#13606) FIX: Set calibration plot axes to screen resolution if available (mne-tools#13558) Refactoring eyetracking.py (mne-tools#13602) [pre-commit.ci] pre-commit autoupdate (mne-tools#13601) Follow up PR to PR - mne-tools#13596 (mne-tools#13599) FIX: Sphinx (mne-tools#13600) Doc improvement - Examples using <some-method> section quirk fix (mne-tools#13596) Add more information to eSSS in examples and docsstring (mne-tools#13591) np.fix -> np.trunc (deprecation) (mne-tools#13594) Make mne.sys_info() work with powershell 7+ (mne-tools#13593) BUG: Fix minor bug with T1 check (mne-tools#13588) [pre-commit.ci] pre-commit autoupdate (mne-tools#13587) ...
| @@ -0,0 +1,152 @@ | |||
| name,coil_type,x,y,z,ex_x,ex_y,ex_z,ey_x,ey_y,ey_z,ez_x,ez_y,ez_z | |||
There was a problem hiding this comment.
@contsili I moved these to their own directory
I also renamed read_meg_montage to read_meg_canonical_info since it returns an Info not a montage
| info_eeg, info_to, mode="accurate", origin=origin | ||
| ) | ||
|
|
||
| return _remap_add(inst, mapping, info_to, ch_type="eeg") |
There was a problem hiding this comment.
@contsili some simplification + DRY-ing of code here -- once you have the mapping infos and the channel type to interp, the operations should be the same (including where the new channels get inserted)
|
@larsoner thank you for the finishing touches! |
|
🎉 Congrats on merging your first pull request! 🥳 Looking forward to seeing more from you in the future! 💪 |
* upstream/main: Axial to planar gradiometer transformation (#13196) MAINT: Work around pandas deprecation (#13632) FIX: Handle empty landmarkLabels in read_raw_snirf (#13628) Implement the MEF3 support (#13610) BUG: Fix bug with somato dataset paths (#13630) DOC: Move mne-kit-gui (#13629) fix team name for inactivity tool [ci skip] (#13626) MAINT: Update dependency specifiers (#13625)
Reference issue (if any)
Fixes #9609 .
What does this implement/fix?
Additional information
The channel positions and orientations are adopted from fieldtrip: https://github.com/fieldtrip/fieldtrip/blob/master/template/gradiometer
I am not sure if for the interpolation we need the coil positions and orientations. For clarity: a gradiometer is ONE channel but has TWO coils. A magnetometer is ONE channel and has ONE coil.
As an expectation I have that I will plot ERPs in the ctf and neuromag format. Also I want to create topoplots like: https://www.fieldtriptoolbox.org/assets/img/tutorial/eventrelatedaveraging/figure8.png