-
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
fix prefilter management for EDF/BDF #12441
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation, sounds reasonable and well thought out to me!
CIs fail because now more warnings need to be caught, see:
Locally if you make sure you have mne-testing-data
and pytest>=8
installed you can do pytest mne/io/edf
for example, then you should be able to replicate the failures rather than wait for CIs to complain
mne/io/edf/edf.py
Outdated
pass | ||
elif highpass[0] == "DC": | ||
info["highpass"] = 0.0 | ||
if "highpass" in edf_info and len(edf_info["highpass"]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More compact equivalent if you want it
if "highpass" in edf_info and len(edf_info["highpass"]): | |
if len(edf_info.get("highpass", [])): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tips.
I updated these codes for GDF with _set_prefilter
function
and similar code was implemented there.
@larsoner |
79131c2
to
bced368
Compare
and len(out["highpass"]) | ||
and out["highpass"][0] == "0.0" | ||
): | ||
out["highpass"][0] = "10.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String "0.000"
for lowpass was converted into float 0
in the previous code.
(it does not pass if lowpass[0] in ("NaN", "0", "0.0"):
)
In this case, both lowpass and highpass is set to 0, and
if info["highpass"] > info["lowpass"]:
is False.
I think this is a kind of special test for highpass > lowpass
case.
With the new code, "0.000"
for lowpass is skipped to be set as info["lowpass"]
and it remains as default (sfreq/2
).
Therefore, lowpass=256, highpass=0 are correctly obtained.
To make highpass > lowpass
case, _hp_lp_mod
function was added to force to set highpass > lowpass
.
Related PR: #8584
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me. @cbrnr looks like you've worked on this stuff a bit, can you look?
Yes, I can take a look early next week! |
6fa42b7
to
0f2f7c2
Compare
Fix prefilter management for GDF (highpass/lowpass are float instead of list of str) Fix tests which throw warnings of "Channels contain different..."
…highpass/lowpass of ndarray of str to _get_info. gdf returns highpass/lowpass of ndarray of np.float32 to _get_info)
… in _raw_extras Select channels of sel but stim chanenl to set highpass/lowpass in info
0f2f7c2
to
2b473d6
Compare
@cbrnr you happy with this now? If so we could get it into 1.7 I think |
It's been some time since I commented on this PR. Could you or @rcmdnk summarize the public (user-facing) changes? Are there any? "Fix pre-filtering management" doesn't really tell me a lot about the changes (and this more detailed information should go into the changelog entry as well). Thanks! |
@cbrnr Bugs:
Changes Introduced in This PR:
|
In it goes – the changelog entry is OK, people can always refer to this thread for more details. Thanks @rcmdnk! |
* upstream/main: fix prefilter management for EDF/BDF (mne-tools#12441) [pre-commit.ci] pre-commit autoupdate (mne-tools#12541) ENH: Allow removal of (up to two) bad marker coils in read_raw_kit() (mne-tools#12394) Implement `picks` argument to `Raw.plot()` (mne-tools#12467) Add Meggie under Related Software documentation (mne-tools#12540)
What does this implement/fix?
For EDF, BDF, and GDF formats, prefilter information, including highpass and lowpass filters, is stored in the info structure.
Arrays for highpass/lowpass are generated by the _parse_prefilter_string function, which omits adding a value if no filter information is found.
These arrays are constructed using all channels except the last one, which is presumed to be an Annotation or TAL channel.
I think it should use only selected channels.
Furthermore, it is occasionally necessary to access highpass/lowpass values in _raw_extras for corresponding channel information. To address this, I suggest the following modifications:
_parse_prefilter_string
function has been improved to insert an empty string "" when no information is available. It has also been enhanced to parse strings like "DC".I have reviewed filter string formats for
Biosemi EEG ECG EMG BSPM NEURO amplifiers systems, EDF specification, EDF+ specification.
In _get_info, where highpass/lowpass values are assigned to info, the current code exhibits bugs:
all(highpass)
is always true since highpass and lowpass are arrays of non-empty strings. The correct approach to check if all values are the same should be likenp.all(highpass == highpass[0])
.info["highpass"] = float(np.max(highpass))
fails because highpass contains strings. However, due to the always-true nature ofall(highpass)
, this code is never executed.This PR addresses and fixes these issues as well. With these changes, some EDF files will trigger warnings about varying highpass and lowpass filter settings across channels, which, due to a bug, were previously not displayed. These warnings are essential for ensuring data consistency and integrity.