Skip to content

ENH: Allow selecting projectors for reconstruction - #14220

Merged
larsoner merged 8 commits into
mne-tools:mainfrom
BabaSanfour:enh-public-proj-reconstruction
Aug 27, 2026
Merged

ENH: Allow selecting projectors for reconstruction#14220
larsoner merged 8 commits into
mne-tools:mainfrom
BabaSanfour:enh-public-proj-reconstruction

Conversation

@BabaSanfour

@BabaSanfour BabaSanfour commented Aug 25, 2026

Copy link
Copy Markdown
Member

Reference issue (if any)

First phase of and closes #14208.

What does this implement/fix?

Make projection reconstruction public

Additional information

Ideation with Sol 5.6 xhigh, implementation with help of 5.6 luna high. All code verified and double checked.

@larsoner larsoner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good start! Can you look to see where we currently use reconstruct_proj and update that tutorial or example? Or add the new version to some example or tutorial where it shows why it's useful?

Comment thread mne/_fiff/proj.py Outdated
Comment thread mne/_fiff/proj.py
Comment thread mne/_fiff/proj.py Outdated
@BabaSanfour

Copy link
Copy Markdown
Member Author

@larsoner I will address these, but also I changed directions now so I will push a cleaner version now and then ping you (still draft + wrapping my head on how to approach this without breaking a lot of things/complex code)

@BabaSanfour

Copy link
Copy Markdown
Member Author

I also noticed ci launch with draft PRs, is that intended (I will add skip ci in the next commit) but maybe draft shouldn't launch CI only if asked?

@larsoner

Copy link
Copy Markdown
Member

Some authors open in draft but want to see CI results / green-ness before marking as ready for review

@BabaSanfour
BabaSanfour force-pushed the enh-public-proj-reconstruction branch from a091c07 to eaa44f4 Compare August 25, 2026 14:55
@BabaSanfour

BabaSanfour commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

@larsoner I was not very happy with the initial implementation after I read it again, it applied the projection matrix directly inside _reconstruct_proj(), while the whole idea was to use MNE existing apply_proj() (instead of retaining separate application logic in mne-denoise). Which links also to your suggestion. my v2 is to let apply_proj() accept projs= also (placed after the existing verbose parameter to avoid breaking anything for now, I can move it though).

This way _reconstruct_proj(projs=...) relies on apply_proj(projs=...). I think this is similar to what you suggested?

I will keep working on the rest piece by piece, and I think I will do the 2nd part of the issue (optional rank and field) in a seperate PR to keep things clean and tidy.

Looks like a good start! Can you look to see where we currently use reconstruct_proj and update that tutorial or example? Or add the new version to some example or tutorial where it shows why it's useful?

Yes I will do this once I am done with the implementation

@larsoner larsoner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still quite a bit of complexity added... but maybe it's unavoidable. Okay with me to proceed!

Comment thread mne/_fiff/proj.py Outdated
Comment thread mne/_fiff/proj.py Outdated
Comment thread mne/tests/test_proj.py Outdated
@BabaSanfour

Copy link
Copy Markdown
Member Author

Another attempt to simplify it

@larsoner larsoner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me, I like the idea of moving the logic into apply_proj for applying a subset!

One tiny last equivalence test I'd like to see (unless I missed it, which is possible) would be something that can be done on main: create instance, add proj(s), apply it/them, then add more projs. This should give an equivalent object state to what you now support on this PR: create instance, add all projs, apply_proj on the same subset. I think in theory you should be able to do assert evoked_a == evoked_b, if not that then maybe object_diff, if not that, then checking ._data equivalence and _projector equivalence plus info["projs"] equivalence (active vs not, values, etc.) would work.

Doing this just on one object type (evoked) is enough I think, we should be able to trust our MixinAbstraction to get us to other objects.

@BabaSanfour

Copy link
Copy Markdown
Member Author

Can you look to see where we currently use reconstruct_proj and update that tutorial or example? Or add the new version to some example or tutorial where it shows why it's useful?

  1. tutorials/preprocessing/45_projectors_background.py currently says: For all instance types, you can always copy the contents of <instance>.info['projs'] into a separate list variable, use <instance>.del_proj(<index of proj(s) to remove>) to remove one or more projectors, and then add them back later with <instance>.add_proj(<list containing projs>) if desired. so we could replace this with a short apply_proj(projs=...) selection example?

  2. extend tutorials/preprocessing/50_artifact_correction_ssp.py in section Visualizing SSP sensor-space bias via signal reconstruction by adding a reconstruct_proj(projs=...) example using the ECG/EOG projectors which are already created.

  3. Create a new example/tutorial. but I am not sure what to do with it, plus it would be replicating things from 1/2.

I am leaning to 1+2.

@larsoner

Copy link
Copy Markdown
Member

Yeah 1+2 would be good!

@BabaSanfour
BabaSanfour marked this pull request as ready for review August 27, 2026 09:34
@BabaSanfour
BabaSanfour requested a review from larsoner August 27, 2026 09:35
@larsoner
larsoner merged commit aa864bc into mne-tools:main Aug 27, 2026
30 checks passed
@larsoner

Copy link
Copy Markdown
Member

Thanks @BabaSanfour !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make projection reconstruction public; allow projector selection; add optional forward/rank control

2 participants