-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ENH] Add tutorial on time-frequency source estimation with STC viewer GUI #10920 #11352
Conversation
Ok, this is good to go by me, sorry I accidentally merged the original PR, please review/merge when you're ready @agramfort and @britta-wstnr, no rush Also tagging @larsoner |
Sorry it took so long, @alexrockhill, but I now finally had the chance to take a look at the GUI. Here are my points and some nitty-gritty details:
|
I tried to test this today using the test script @alexrockhill provided here: #10920 (comment). Here are a few videos showing problems I encountered. Scroll wheel on MRI slices causes weird shiftscroll-wheel.webmcmap midpoint slider has no effectmidpoint-slider-does-nothing.webmclicking the T/F plane moves crosshairs to wrong locationupdate after click is also slow, ~3 seconds on my (very fast Desktop) machine, but you can't tell that in the video because it doesn't visualize when the clicks happened. click-target-missed.webm |
@alexrockhill have you line profiled the code to see where the slowdowns are during interactive updates? |
I'll try that next when I have a minute! |
So I'm fixing all the other things but with regards to @drammock 's comment about the weird shift when you zoom, that's a feature not a bug. I really dislike in |
This demonstrates the issue: Screencast.from.01-06-2023.10.18.26.AM.webm |
OK, but there are smoother ways to solve that than a single shift of the image on first zoom interaction. Play around with google maps a bit. The map doesn't shift dramatically on the first turn of the scroll wheel to move the point where your mouse cursor was to lie at the center of the window. Instead, the thing that was right under your cursor stays right under your cursor (the zooming is centered where the cursor is). If the goal is to keep the selected voxel / crosshairs in view, then implement a "zoom to cursor" type interaction but pretend that the cursor is at the crosshairs regardless of where it actually is. To me that is better than what you have now, but less natural than the proposal in the following paragraph: Possibly even better, I think, would be zooming to where the cursor actually is for the slice that is under the mouse pointer, and zooming the other slices in a way that keeps the crosshairs in sync in terms of their x/y positions within each slice window. So in the PI and LI windows, the horizontal crosshair would always be aligned, and in the LI and LP windows the vertical crosshair would always be aligned. This gets to one of my peeves about freeview, which is that if transverse/horizontal view is nose-up, then it should not be in the lower-left corner (below saggital) but rather in lower-right (below coronal). If arranged that way (basically switch the lower two quadrants with each other) then the crosshair alignment makes a lot more sense. EDIT: this does allow the crosshairs to go out of view, if the user's cursor is not on/near the crosshairs when they spin the scroll wheel. But it allows both zooming on the selected voxel and zooming on some other location that you happen to want to inspect (without having to change the voxel selection first). |
That all sounds very reasonable @drammock but it will apply to this as well as the |
So the middle color scale only applies to the 3D rendering, on Screencast.from.01-09-2023.12.12.33.PM.webm |
Also the blinking cursors is a very annoying PyQt bug it looks like; even when you remove focus, the cursor still continues to blink. I tried the solution here (https://stackoverflow.com/questions/42475602/pyqt5-two-blinking-cursors-at-the-same-time) but once that cursor starts blinking, I can't figure out a way to stop it. I think best just to wait for a new PyQt version to fix that... |
Ok, I sped it up significantly, I fixed the spectrogram selection issue (I'm pretty sure) and I fixed the things pointed out as wrong with the baseline correction (that was a bit sloppy, sorry, it was added last minute) and fixed the keyboard shortcut issue because the focus was being set wrong. I didn't implement a better zoom and I only implemented |
Where are the NaNs coming from? The masking of the data via min/mid/max? If so, should the interpolation not be done before the masking? The more I think about it, the less intuitive I find it - after all, in the example above, it masks out the extreme value. But I think you said you fixed that now in one of your other comments? I am not sure I follow on the baseline - does this have to do with writing custom code (you mention that for the colorbar) - i.e. is the baseline operations underpinned by custom code as well? As for the symmetric colorbar - for me it is not (also check the figures above - shows a less extreme case though). There is quite some spelling mistakes etc in the latest code additions that Github catches - so please have a look at that and maybe check locally with a linter. |
The NaNs come from small float values being mapped to zero, then, when you go to take the log of that, you get NaN. The interpolation does happen after the masking though because the interpolation is done in
The baseline uses the MNE internal
So there's two issues there: 1) the gradiometers must be combined and that uses root mean square so it's strictly positive even after baseline correction makes the raw values negative and 2) the colorbar is reset to min 0, middle halfway and max all-the-way whenever you change the baseline selector. 2 is what I implemented when a symmetric colorbar was requested. For non-gradiometers, this is exactly the ticket and does exactly what you're asking for, there's just not an easy way to do that for gradiometers because they must be combined. We should combine them with
Those aren't mine, they came from changing the codespell testing code and I fixed them in another PR. |
To demonstrate the symmetric topomap, here is a script that uses magnetometers; there is not the same issue with the colorbar not being symmetric because they don't have to be combined.
|
Ok to merge? |
@alexrockhill from a high level perspective this PR does a lot of cool stuff. To do so it needs a lot of lines (+1700ish), and given the number of review iterations and the expected follow-up PRs to add new/experimental features (e.g., complex-valued phase-alignment), I'm a bit worried about the future review/maintenance bandwidth. I propose we do a variant of what @drammock suggested earlier -- but instead of moving code to mne-incubator, we create a new I think having the To be honest I wish we had done something similar for |
@britta-wstnr , the colorbar is symmetric in that vmin and vmax are at the extremes and vmid is exactly in the middle. It's not hard to make it symmetric so that vmin and vmax are the same absolute value, it just wasn't clear that's what you were asking for. For the second one, that is a bug, if you toggle interpolate on and off, it gets fixed. I forgot I needed to look into that, I'll fix that asap. @larsoner , that sounds like a pretty good idea, my only hesitancy is that core is shared with ieeg. With the seeg circle visualization shared with mne connectivity, that was really messy and more than a bit of a pain. We could move both guis over to a new repo though. What do you think? |
Sure if that makes logistics easier then that's fine. Early next week I can set up the repo and such (unless you're keen to learn/try!) and we can move iEEG first, get green, then move this. WDYT? |
Sounds good |
Now the colorbar is symmetric the right way and updates properly for the topomap. The way I was handling integers for the complex conjugate the used squares and so would overflow was causing a lot of values to be cast to zero so I fixed that as well. What was needed was casting to the next biggest data type temporarily but now I think that's unavoidable. That will cause a bump in the max amount of memory used but since it worked for a decent number of epochs on multiple pretty wimpy laptops I've tested so I think it's not too bad and will work fine. |
+1 to make this a separate package under the mne-tools org. It allow faster
iterations for you Alex
… Message ID: ***@***.***>
|
+1 for putting this in its own repo. As for the colorbar - for good measure:
|
That's the current behavior as far as I can tell. Except for combining planar gradiometers but, in that case, they can't be negative using root-mean-square so white is set to the midpoint value. Can you provide a screenshot if there's still something that's an issue? |
Yes, the latest iteration does it correctly. |
@alexrockhill FYI I haven't forgotten about this, hope to get to the new repo stuff in the next couple of days! |
@alexrockhill can you open a WIP PR to add this code to https://github.com/mne-tools/mne-gui-addons ? Then I can fix all the infrastructure stuff (unless you want to!) to get things green. Then once that's merged we can modify this PR just to have the tutorial that uses the GUI I think. Maybe eventually mne-gui-addons should have its own doc build and such but for now it's easy enough (and good for exposure) to have the tutorial using it live here. |
Definitely, thanks for doing that! |
Closing in favor of mne-tools/mne-gui-addons#5 |
Follow-up to #10920 accidentally merged.