Repository: mne-tools/mne-python

Issue:
Automatic Lowpass Filter When Creating `Raw` Object from Scratch
Hello, 

I am creating an `mne.io.raw` object from a `numpy.array` (in this case, a variable called 'channels') using the following code:

```
channel_data, info = create_mne_data_and_metadata(channels, 4000.0)
raw = mne.io.RawArray(channel_data, info)
```

where

```
def create_mne_data_and_metadata(channels, sampling_frequency):

    # instantiate metadata for mne
    channel_names = []
    channel_data = []

    # instantiate channel data
    for channel in channels:
        channel_names.append(channel.channel_name)
        channel_data.append(channel.readings)

    # create mne data and metadata objects
    info = mne.create_info(channel_names, sampling_frequency, 'EEG')
    info['sfreq'] = sampling_frequency

    return channel_data, info
```

However, I am running into a curious thing in which an automatic low-pass filter that is half sampling frequency is automatically applied to my data. This can be seen by inspecting `raw.info` which returns

```
<Info | 10 non-empty values
 bads: []
 ch_names: A11, A21, C31, C41, Cz1, E11, E21, F31, F41, Fz1, LAHC1, LAHC2, ...
 chs: 15 EEG, 58 SEEG
 custom_ref_applied: False
 description: ''
 file_id: 4 items (dict)
 highpass: 0.0 Hz
 lowpass: 2000.0 Hz
 meas_date: unspecified
 meas_id: 4 items (dict)
 nchan: 73
 projs: []
 sfreq: 4000.0 Hz
>
```

This is also the case in the official [MNE tutorial](https://mne.tools/stable/auto_tutorials/simulation/plot_creating_data_structures.html#sphx-glr-auto-tutorials-simulation-plot-creating-data-structures-py), in which creating a `raw` object with `sfreq=200` returns an object with `lowpass=100'. 
 
How might I fix this?


Discussion:
What you are seeing is just the Nyquist frequency, which acts as a "natural" lowpass filter - sampled signals can only contain frequencies up to half the sampling frequency.

It can of course be misleading if you undersample a signal that originally contained higher frequencies. This will result in frequencies above the Nyquist aliased to lower frequencies. So strictly speaking, MNE should probably not automatically assume a lowpass filter if no other information is available. WDYT @larsoner @agramfort?
Correctly sampling a band-passed signal with frequencies above Nyquist is in expert-level signal processing territory. I've never seen anyone do in practice in neuroscience. I think if anyone is actually doing this (and I doubt this is actually such a case) then we can just tell the person to ignore that entry -- and I'd expect them to understand why it was put there. Let's just update the docs to say that it's automatically set to half the sampling rate if there is otherwise no low-pass applied to the data.

In much more common/normal cases, our having that entry as it is now, set to half the sampling right, might more often correctly imply/teach users that they can't hope to correctly have signals above half their sampling rate (unless they have been very careful as above).
I wasn't even referring to special cases where such sampling might work, but to users forgetting to apply an anti-aliasing filter before downsampling (outside of MNE). Then technically, the lowpass filter at the new Nyquist frequency would be incorrect.

But this is really a very constructed detail, I agree that updating the docs to clarify this is sufficient!
I can try to update this. :)

Resolving patch:
diff --git a/mne/io/meas_info.py b/mne/io/meas_info.py
--- a/mne/io/meas_info.py
+++ b/mne/io/meas_info.py
@@ -284,6 +284,8 @@ class Info(dict, MontageMixin):
         Tilt angle of the gantry in degrees.
     lowpass : float
         Lowpass corner frequency in Hertz.
+        It is automatically set to half the sampling rate if there is
+        otherwise no low-pass applied to the data.
     meas_date : datetime
         The time (UTC) of the recording.
 


Test patch: