Skip to content

FIX: Preserve FIFF_NAME and fix active state handling in projection I/O#14029

Open
sametSeckiiin wants to merge 5 commits into
mne-tools:mainfrom
sametSeckiiin:fix-proj-active-and-name-io
Open

FIX: Preserve FIFF_NAME and fix active state handling in projection I/O#14029
sametSeckiiin wants to merge 5 commits into
mne-tools:mainfrom
sametSeckiiin:fix-proj-active-and-name-io

Conversation

@sametSeckiiin

Copy link
Copy Markdown
Contributor

Fixes #13910

What does this implement/fix?

This PR addresses an I/O round-trip bug in _write_proj (mne/_fiff/proj.py) where projection items lose metadata and force incorrect default values during saving.

Specifically:

  • Preserves FIFF_NAME: Added a check to write proj["desc"] as FIFF_NAME during saving so the projection name isn't dropped.
  • Fixes active state forcing 0: Updated write_int for FIFF_MNE_PROJ_ITEM_ACTIVE to only trigger when proj["active"] is not None. Previously, None evaluated as False in basic truthy checks, which silently forced uninitialized states to 0 and altered the original data.

Ran the projection test suite (mne/tests/test_proj.py) locally. All 17 tests passed without any regression.

@welcome

welcome Bot commented Jul 6, 2026

Copy link
Copy Markdown

Hello! 👋 Thanks for opening your first pull request here! ❤️ We will try to get back to you soon. 🚴

@nordme nordme left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @sametSeckiiin ! Welcome -- we always appreciate PR's from new contributors!

I took a look at your code and have a couple thoughts about this fix. I think we should probably be preserving the original projector names as the descriptors. The information that's most useful to display when loading the raw file, drawn from the proj["desc"] field in the info, is actually the information in the FIFF.FIFF_NAME field in the original fif file, e.g. "PCA-v1-mag-permutated", "PCA-v2-mag-permutated", "PCA-v1-grad-permutated", etc., rather than "generated with dossp-2.1" for all projectors, which is what we get currently. @larsoner do you agree? I'm pretty sure back in the day we kept the projector names as the description.

If we want to preserve the projector names, then we'll need to alter the _read_proj function as well as the _write_proj function.

Comment thread mne/_fiff/proj.py Outdated
write_int(fid, FIFF.FIFF_PROJ_ITEM_NVEC, proj["data"]["nrow"])
write_int(fid, FIFF.FIFF_MNE_PROJ_ITEM_ACTIVE, proj["active"])

if proj.get("desc") is not None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Careful not to duplicate the name field in the saved fif file, which is what happens here. Also, note that we'll want to keep the fields in order.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for catching that, @nordme!

I see the issue now—by adding the check there, I accidentally duplicated the name field and broke the expected field ordering in the FIFF structure.

I will inspect _write_proj to find where the name is originally written in the proper sequence, remove this duplicate check, and ensure that preserving proj["desc"] as FIFF_NAME is done exactly in the correct order (and coordinated with _read_proj). Working on the updated commits now

@sametSeckiiin sametSeckiiin force-pushed the fix-proj-active-and-name-io branch from e885064 to 4089c75 Compare July 8, 2026 11:40
@sametSeckiiin

Copy link
Copy Markdown
Contributor Author

Thanks again for the guidance, @nordme I have just pushed the updates:

Removed duplicate write (_write_proj): Removed the redundant check at the end of the block to prevent duplicate tags and preserve standard FIFF field ordering.

Preserved descriptor names (_read_proj): Updated the lookup priority to check FIFF_NAME before FIFF_DESCRIPTION, ensuring custom projector names are preserved across round-trip I/O.

All 17 tests in test_proj.py are passing cleanly locally. Let me know if this looks good to merge

@drammock

drammock commented Jul 8, 2026

Copy link
Copy Markdown
Member

@nordme and I took a look at an old FIFF file (recorded in 2020). What we see is that the projectors don't have a 233 FIFF_NAME for proj items, but they do have a comment/description field, e.g.:

206  = FIFF_COMMENT/FIFF_DESCRIPTION (16b str)  = mag.fif : PCA-v5 ... str len=16

We think this is why the existing code checks first for a 206 field, and only then falls back to a 233 if the description is missing:

tag = find_tag(fid, item, FIFF.FIFF_DESCRIPTION)
if tag is not None:
desc = tag.data
else:
tag = find_tag(fid, item, FIFF.FIFF_NAME)
if tag is not None:
desc = tag.data

Comparing this to the screenshot in #13910, it looks like modern FIFFs are being written by MEGIN with both 233 and 206, and the info that used to be in 206 is now in 233. So we may want to triage based on which version of Megin software wrote the file. @nordme can you reach out to Megin and see if you can determine when this change happened and how best to triage?

@nordme

nordme commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@nordme can you reach out to Megin and see if you can determine when this change happened and how best to triage?

@drammock @sametSeckiiin Ok, I reached out to MEGIN, and I'll update here when I get the info!!

@drammock

Copy link
Copy Markdown
Member

@sametSeckiiin please don't idly merge main just because GitHub says "you're out of date with the base branch". merging main causes CIs to run, which uses energy and costs us money. Specifically in the situation we're in here: we know some more changes will need to be made but they haven't been made yet, so running CIs before those changes happen is wasteful.

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.

Update handling of projectors in FIF I/O

3 participants