ENH: group triaxial OPM topomaps by orientation#13866
ENH: group triaxial OPM topomaps by orientation#13866PragnyaKhandelwal wants to merge 28 commits intomne-tools:mainfrom
Conversation
for more information, see https://pre-commit.ci
|
Hi @larsoner....Just a friendly ping on this final wrap-up for the OPM topomaps. I've included visual outputs in the PR description showing the new grouped views. Ready to review whenever you have a chance! |
|
Code looks reasonable at first look. But now I'm wondering whether or not this can be combined / refactored with the mag/grad code for Neuromag systems. The problem is similar there: there are three sensors per location, one radial (magnetometer) and two tangential (gradiometers) and we plot the mags in one plot and the RMS of the gradiometers in another. Do you think it's worth looking into that refactoring in this PR? Or would it be better to review + merge this PR as-is and then refactor afterward? |
|
Thanks @larsoner! I completely agree that unifying the OPM and Neuromag mag/grad logic is the right architectural direction since the underlying radial/tangential problem is so similar. |
|
Yeah that sounds reasonable to me! One last request, can you modify some example(s)/tutorial(s) in a way that shows this new functionality? |
…yaKhandelwal/mne-python into enh-opm-grouping-final-fix
…oad timeout in CI
|
Thanks @larsoner! I've added a new example demonstrating the grouped triaxial OPM topomaps using Well I initially tried using the Ready for final review and merge once these last CI checks turn green! |
Hmmm that's a problem, that's a real dataset and it should work on real data. Can you try running it with memory profiler for example to see if memory usage goes too high? It really shouldn't for evoked data... if you can push a commit that should work (or revert to one that should) I can also look A fake triaxial dataset I think is less useful for people. |
|
Agreed! Real data is definitely better for learning. To avoid stressing the CI with another heavy download, I just moved the visualization into the existing |
|
Ah, I see why the grouped view didn't trigger in the rendered docs! The Since |
|
This one is triaxial I think https://mne.tools/stable/auto_examples/datasets/kernel_phantom.html |
|
Alright, I migrated the example to the |
I'm not convinced... the Kernel dataset is a real dataset, and the feature needs to work for real datasets way more so than synthetic ones ...
... So I think the check for colocation needs adjusting. What doesn't match properly for that dataset? |
for more information, see https://pre-commit.ci
|
I fixed the docs example call path in |
|
The macOS tests I'll fix in #13878 and we can ignore, I've restarted CircleCI |
| ) | ||
| evoked = epochs.average() | ||
| t_peak = evoked.times[np.argmax(np.std(evoked.copy().pick("meg").data, axis=0))] | ||
| fig = evoked.plot_joint(picks="mag") |
| # | ||
| # Since Kernel OPMs are triaxial sensors (measuring Bx, By, Bz directions), | ||
| # we can visualize them as grouped topomaps showing radial and tangential | ||
| # components side-by-side when multiple colocated channels are detected: |
There was a problem hiding this comment.
Fixed two critical bugs in OPM grouped topomap rendering: 1. Use symmetric distance matrix (not upper triangle) to properly detect all colocated channel overlaps bidirectionally. 2. Lower grouping threshold from >=3 to >=2 channels to support both biaxial (e.g., bx+by or by+bz) and triaxial (bx+by+bz) OPM sensors. Real OPM hardware like Kernel phantom has biaxial pairs instead of perfect triaxial arrays. This fix enables grouped radial/tangential visualization for real datasets. Changes: - mne/viz/topomap.py: Fixed distance matrix and threshold - mne/viz/tests/test_topomap.py: Updated test expectations - examples/datasets/kernel_phantom.py: Updated docstring - tutorials/preprocessing/80_opm_processing.py: Restored plot_joint call Closes the rendering issue where only 1 plot showed instead of 2.
Tests now expect doubled axis counts due to radial+tangential grouping for biaxial OPM pairs. Kernel phantom data now correctly triggers grouped visualization with 20 axes for 10 ICA components and 9 axes for 4-point topomap (4 radial + 4 tangential + 1 colorbar).
|
I fixed this issue now to handle overlap grouping for biaxial OPM pairs, so grouped radial and tangential views now trigger correctly on this dataset and also updated the tests accordingly for new axis counts. ig ready to review and merge! |
| # Kernel OPMs measure multiple magnetic field directions (Bx, By, Bz). | ||
| # We can visualize colocated channels as grouped topomaps showing radial and | ||
| # tangential components side-by-side for clearer interpretation of the data: | ||
|
|
||
| fig = evoked.plot_joint(times=[t_peak], topomap_args=dict(sphere=sphere)) |
There was a problem hiding this comment.
Do we show radial and tangential for Neuromag data? We don't, right? So we should probably be consistent here and just show the radial.
This would be an advantage of refactoring the logic to be the same, to ensure consistency in behaviors...
At the very least, I think that changing the behavior of plot_joint should be out of scope for this PR. How those time points show up will need some discussion, thinking and testing. (And it should probably be the same behavior for Neuromag triplets and OPM triplets.)
|
Thanks @larsoner! you're completely right that |


Reference issue (if any)
Closes #13781
What does this implement/fix?
Final fix for #13781: adds caller-facing grouped rendering for colocated triaxial OPM channels so orientation information is shown explicitly across visualization entry points.
Implemented:
Additional information
Manual visual check done for:
Evoked.plot_topomapgrouped radial/tangential mapsEvoked.plot_jointgrouped maps + connector linesICA.plot_componentsgrouped radial/tangential titlesA local helper script was used for manual visual smoke-checking on synthetic triaxial OPM data. I can share it if needed.
Visual outputs: