Repository: mne-tools/mne-python

Issue:
TypeError: ‘float’ object does not support item assignment
- MNE-Python version: 0.22.0
- operating system: Windows & Mac

#### Describe the bug
*TypeError: ‘float’ object does not support item assignment*

I was trying to read in a hypnogram edf file using python. The data is directly from [PhysioNet](https://www.physionet.org/content/sleep-edfx/1.0.0/)
For example, when I tried to process this [file](https://www.physionet.org/content/sleep-edfx/1.0.0/sleep-cassette/SC4001EC-Hypnogram.edf) using my code below, it threw an error.

#### Steps to reproduce
```python
import mne

data = mne.io.read_raw_edf("SC4001EC-Hypnogram.edf")
```

#### ERROR results
```
Extracting EDF parameters from C:\Users\yxie\Desktop\healthcare\SC4001EC-Hypnogram.edf...
EDF file detected
Traceback (most recent call last):

  File "<ipython-input-77-d358ed2921e8>", line 4, in <module>
    data = mne.io.read_raw_edf(localpath)

  File "C:\Users\yxie\Anaconda3\lib\site-packages\mne\io\edf\edf.py", line 1217, in read_raw_edf
    return RawEDF(input_fname=input_fname, eog=eog, misc=misc,

  File "<decorator-gen-182>", line 24, in __init__

  File "C:\Users\yxie\Anaconda3\lib\site-packages\mne\io\edf\edf.py", line 114, in __init__
    info, edf_info, orig_units = _get_info(input_fname,

  File "C:\Users\yxie\Anaconda3\lib\site-packages\mne\io\edf\edf.py", line 358, in _get_info
    edf_info, orig_units = _read_header(fname, exclude)

  File "C:\Users\yxie\Anaconda3\lib\site-packages\mne\io\edf\edf.py", line 345, in _read_header
    return _read_edf_header(fname, exclude)

  File "C:\Users\yxie\Anaconda3\lib\site-packages\mne\io\edf\edf.py", line 598, in _read_edf_header
    record_length = record_length[0] = 1.

TypeError: 'float' object does not support item assignment
```


#### Additional information
Note: I'm only showing my Windows setup here. But it also failed on my Mac.

Platform:      Windows-10-10.0.18362-SP0
Python:        3.8.3 (default, Jul  2 2020, 17:30:36) [MSC v.1916 64 bit (AMD64)]
Executable:    C:\Users\yxie\Anaconda3\python.exe
CPU:           Intel64 Family 6 Model 158 Stepping 13, GenuineIntel: 12 cores
Memory:        15.8 GB

mne:           0.22.0
numpy:         1.19.5 {blas=D:\\a\\1\\s\\numpy\\build\\openblas_info, lapack=D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info}
scipy:         1.5.0
matplotlib:    3.2.2 {backend=module://ipykernel.pylab.backend_inline}

sklearn:       0.23.2
numba:         0.50.1
nibabel:       Not found
nilearn:       Not found
dipy:          Not found
cupy:          Not found
pandas:        1.2.2
mayavi:        Not found
pyvista:       Not found
vtk:           Not found



Discussion:
Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴🏽‍♂️

This file contains an invalid record length of zero. EDFBrowser doesn't open the file either, so it's clearly an invalid EDF file. However, we are already trying to work around this issue here:

https://github.com/mne-tools/mne-python/blob/acffc2ec986de456792503b5a6901fd68889bf8a/mne/io/edf/edf.py#L594-L600

It seems like this doesn't work, because of `record_length = record_length[0] = 1.`. I tried changing it to `record_length[0] = 1.` just like we do in the corresponding GDF section, but then there are several follow-up errors.
According to @schloegl this is a valid EDF file. However, the data it contains is a bit unconventional: the file contains only annotations and no signals. I think we should try to support this.
Hi Clemens, thanks for you help.
Yes you are right. I was able to figure out the "contents" of this EDF file with other tools, and it appears all the information was recorded in annotations.
I'm relatively new to EDF, not sure why it is done this way.

![image](https://user-images.githubusercontent.com/9292401/114189763-8c79f600-9918-11eb-80ab-4cf4982255ee.png)

I digged around a little bit in our reader, but it really seems like we're totally not prepared to read EDF files that contain only annotations. This would take me quite some time to refactor, which at the moment I don't have. If anyone feels up to it please feel free to submit a PR. @dreamiter which other tool did you use to extract annotations from this file? Maybe we can work around this by special-casing this situation and then just use the other tool instead of our reader (this would probably be much less effort).
@cbrnr Hi, I wasn't sure if it's ok to share other people's git here.
But I found a Gitlab repo, written by Teunis van Beelen ([Gitlab Link](https://gitlab.com/Teuniz/EDFlib-Python)).
Inside `edfreader.py` you can check out `self.annotationslist`
https://mne.tools/dev/generated/mne.read_annotations.html should be able to
read .edf that contain only
annotations. read_raw_edf should point to this when used to read a file
that contains only annotations.

>

Nice, thanks @agramfort, this works! What do you mean by "point to this"? When reading such a file with `read_raw_edf`, what should happen? Just issue a more informative error?
>
> Nice, thanks @agramfort <https://github.com/agramfort>, this works! What
> do you mean by "point to this"? When reading such a file with read_raw_edf,
> what should happen? Just issue a more informative error?
>

I mean raise an exception with a meaningful error message saying to use
read_annotations


Resolving patch:
diff --git a/mne/io/edf/edf.py b/mne/io/edf/edf.py
--- a/mne/io/edf/edf.py
+++ b/mne/io/edf/edf.py
@@ -597,7 +597,9 @@ def _read_edf_header(fname, exclude):
         if record_length[0] == 0:
             record_length = record_length[0] = 1.
             warn('Header information is incorrect for record length. Default '
-                 'record length set to 1.')
+                 'record length set to 1.\nIt is possible that this file only'
+                 ' contains annotations and no signals. In that case, please '
+                 'use mne.read_annotations() to load these annotations.')
 
         nchan = int(_edf_str(fid.read(4)))
         channels = list(range(nchan))


Test patch: