fix prefilter management for EDF/BDF#12441
Conversation
larsoner
left a comment
There was a problem hiding this comment.
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.
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.
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.
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
|
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_stringfunction 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.