Repository: mne-tools/mne-python

Issue:
DOC: Clearer error message for bad events (tuple)
Hello,

I met a problem with mne.epoch() on v18. Please find the example code and the error bellow.
(I can share share the data on request)
Thank in advance.
William

```
# ==========================ImportPackage=====================================
import mne
import scipy
import numpy as np
from mne.datasets import sample
#=========================================================================
raw = mne.io.read_raw_brainvision(vhdr_fname, misc='auto', scale=1.0, preload=True, verbose=None)
# =================Select all event id or picks from files============================
#event_id = {'S 65': 65, 'S 66': 66}
# ==============================Channels===================================
channels = raw.rename_channels({'1': 'Fp1','2': 'Fz','3': 'F3','4': 'F7','5': 'FT9','6': 'FC5','7': 'FC1','8': 'C3','9': 'T7','10': 'TP9','11': 'CP5', '12': 'CP1','13': 'Pz','14': 'P3','15': 'P7','16': 'O1','17': 'Oz','18': 'O2','19': 'P4','20': 'P8','21': 'TP10','22': 'CP6','23': 'CP2','24': 'Cz', '25': 'C4','26': 'T8','27': 'FT10','28': 'FC6','29': 'FC2','30': 'F4','31': 'F8','32': 'Fp2'})
# =========================Find event in segment===============================
events = mne.events_from_annotations(raw, event_id='auto', regexp='^(?![Bb][Aa][Dd]|[Ee][Dd][Gg][Ee]).*$', use_rounding=True, chunk_duration=None, verbose=None)


events
`_{'New Segment/': 99999, 'Stimulus/S  1': 1, 'Stimulus/S 64': 64, 'Stimulus/S 65': 65, 'Stimulus/S 66': 66, 'Stimulus/S 67': 67, 'Stimulus/S 68': 68, 'Stimulus/S 69': 69, 'Stimulus/S 70': 70, 'Stimulus/S 71': 71, 'Stimulus/S 72': 72, 'Stimulus/S 73': 73, 'Stimulus/S 74': 74, 'Stimulus/S 75': 75, 'Stimulus/S 76': 76, 'Stimulus/S 77': 77, 'Stimulus/S 78': 78, 'Stimulus/S 79': 79, 'Stimulus/S 80': 80, 'Stimulus/S 81': 81, 'Stimulus/S 82': 82, 'Stimulus/S 83': 83, 'Stimulus/S 84': 84, 'Stimulus/S 85': 85, 'Stimulus/S 86': 86, 'Stimulus/S 87': 87, 'Stimulus/S 88': 88, 'Stimulus/S 89': 89, 'Stimulus/S 90': 90, 'Stimulus/S 91': 91, 'Stimulus/S 92': 92, 'Stimulus/S 93': 93, 'Stimulus/S 95': 95, 'Stimulus/S 96': 96, 'Stimulus/S 97': 97, 'Stimulus/S 98': 98, 'Stimulus/S 99': 99, 'Stimulus/S100': 100, 'Stimulus/S101': 101, 'Stimulus/S102': 102, 'Stimulus/S103': 103, 'Stimulus/S104': 104, 'Stimulus/S105': 105, 'Stimulus/S106': 106, 'Stimulus/S107': 107, 'Stimulus/S108': 108, 'Stimulus/S109': 109, 'Stimulus/S110': 110, 'Stimulus/S111': 111, 'Stimulus/S222': 222, 'Stimulus/S224': 224, 'Stimulus/S225': 225, 'Stimulus/S226': 226})_`

# =====================Compute epochs and average============================
epochs = mne.Epochs(raw, events, event_id=[65, 66], tmin=-0.5, tmax=1.0, baseline=(-0.25, 0), picks=None,preload=False, reject=None, flat=None, proj=True, decim=1, reject_tmin=None, reject_tmax=None, detrend=None,on_missing='error', reject_by_annotation=True, metadata=None, verbose=None)



**Traceback (most recent call last):
  File "<input>", line 5, in <module>
  File "</volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/externals/decorator.py:decorator-gen-204>", line 2, in __init__
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/utils/_logging.py", line 89, in wrapper
    return function(*args, **kwargs)
  File "/volatile/home/WVxx4/.local/lib/python3.7/site-packages/mne/epochs.py", line 1812, in __init__
    verbose=verbose)
  File "</volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/externals/decorator.py:decorator-gen-195>", line 2, in __init__
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/utils/_logging.py", line 89, in wrapper
    return function(*args, **kwargs)
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/epochs.py", line 278, in __init__
    'type %s' % (events.dtype))
ValueError: events must be an array of type int, got type object**
```


Discussion:
did it work with 0.18? can you share the .vrmk file?

>

That worked with 0.17. I send you the link for the files.

Thank you.

William
I just tried on current master and maint/0.18 branch and it works for me to
do:

In [*1*]: *import* *mne*


In [*2*]: raw = mne.io.read_raw_brainvision('Pilote1.vhdr')


what version of mne are you using? how did you install it?

It's 0.18.1. I install it with pycharm updated.
ok I just uploaded 0.18.2

please udpate and try again.

>

I updated but I have the same trouble after computed mne.Epochs()

epochs = mne.Epochs(raw, events, event_id=[65, 66], tmin=-0.5, tmax=1.0, baseline=(-0.25, 0), picks=None,preload=False, reject=None, flat=None, proj=True, decim=1, reject_tmin=None, reject_tmax=None, detrend=None,on_missing='error', reject_by_annotation=True, metadata=None, verbose=None)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "</volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/externals/decorator.py:decorator-gen-204>", line 2, in __init__
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/utils/_logging.py", line 89, in wrapper
    return function(*args, **kwargs)
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/epochs.py", line 1812, in __init__
    verbose=verbose)
  File "</volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/externals/decorator.py:decorator-gen-195>", line 2, in __init__
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/utils/_logging.py", line 89, in wrapper
    return function(*args, **kwargs)
  File "/volatile/home/WVxx/.local/lib/python3.7/site-packages/mne/epochs.py", line 278, in __init__
    'type %s' % (events.dtype))
ValueError: events must be an array of type int, got type object

can you run `mne.sys_info()`?

mne.sys_info()
Platform:      Linux-4.4.0-143-generic-x86_64-with-debian-stretch-sid
Python:        3.7.3 (default, Mar 27 2019, 22:11:17)  [GCC 7.3.0]
Executable:    /volatile/home/WVxx4/anaconda3/envs/mne/bin/python
CPU:           x86_64: 8 cores
Memory:        Unavailable (requires "psutil" package)
mne:           0.18.2
numpy:         1.16.3 {blas=openblas, lapack=openblas}
scipy:         1.2.1
matplotlib:    3.0.3 {backend=Qt5Agg}
sklearn:       0.20.3
nibabel:       Not found
mayavi:        Not found
cupy:          Not found
pandas:        Not found
dipy:          Not found
this is really weird. Can someone replicate the issue around you?
You can debug locally, too. When you get this error, you can do:
```
ValueError: events must be an array of type int, got type object
>>> import pdb; pdb.pm()
(pdb) p events.dtype
np.object  # probably
(pdb) p events
...
(pdb) p type(events[0])
...
(pdb) p events[0]
...
```
What `events` looks like (the `...` above) will be informative.
I think we fixed the pb IRL this morning. It's because @WilliamLabCea passed the output of events_from_annotations to events while it returns events and event_id as tuple
Can we improve the error message somehow? Probably by something like:
```
events_type = type(events)
events = np.array(events)
if events.dtype not integer-like:
    raise Whatever('... , original type %s'  % (..., events_type))
```
ok

PR welcome

>


Resolving patch:
diff --git a/mne/epochs.py b/mne/epochs.py
--- a/mne/epochs.py
+++ b/mne/epochs.py
@@ -364,17 +364,16 @@ def __init__(self, info, data, events, event_id=None, tmin=-0.2, tmax=0.5,
         _check_option('on_missing', on_missing, ['error', 'warning', 'ignore'])
 
         if events is not None:  # RtEpochs can have events=None
+            events_type = type(events)
             events = np.asarray(events)
-
+            if not np.issubdtype(events.dtype, np.integer):
+                raise TypeError('events should be a NumPy array of integers, '
+                                'got {}'.format(events_type))
         event_id = _check_event_id(event_id, events)
         self.event_id = event_id
         del event_id
 
         if events is not None:  # RtEpochs can have events=None
-            if events.dtype.kind not in ['i', 'u']:
-                raise ValueError('events must be an array of type int, got '
-                                 'type %s' % (events.dtype))
-            events = events.astype(int)
             if events.ndim != 2 or events.shape[1] != 3:
                 raise ValueError('events must be of shape (N, 3), got %s'
                                  % (events.shape,))


Test patch:
diff --git a/mne/tests/test_epochs.py b/mne/tests/test_epochs.py
--- a/mne/tests/test_epochs.py
+++ b/mne/tests/test_epochs.py
@@ -510,11 +510,17 @@ def test_base_epochs():
     epochs = BaseEpochs(raw.info, None, np.ones((1, 3), int),
                         event_id, tmin, tmax)
     pytest.raises(NotImplementedError, epochs.get_data)
-    # events with non integers
-    pytest.raises(ValueError, BaseEpochs, raw.info, None,
-                  np.ones((1, 3), float), event_id, tmin, tmax)
-    pytest.raises(ValueError, BaseEpochs, raw.info, None,
-                  np.ones((1, 3, 2), int), event_id, tmin, tmax)
+    # events have wrong dtype (float)
+    with pytest.raises(TypeError, match='events should be a NumPy array'):
+        BaseEpochs(raw.info, None, np.ones((1, 3), float), event_id, tmin,
+                   tmax)
+    # events have wrong shape
+    with pytest.raises(ValueError, match='events must be of shape'):
+        BaseEpochs(raw.info, None, np.ones((1, 3, 2), int), event_id, tmin,
+                   tmax)
+    # events are tuple (like returned by mne.events_from_annotations)
+    with pytest.raises(TypeError, match='events should be a NumPy array'):
+        BaseEpochs(raw.info, None, (np.ones((1, 3), int), {'foo': 1}))
 
 
 @requires_version('scipy', '0.14')
@@ -612,7 +618,7 @@ def test_events_type():
     raw, events = _get_data()[:2]
     events_id = {'A': 1, 'B': 2}
     events = (events, events_id)
-    with pytest.raises(ValueError, match='got type'):
+    with pytest.raises(TypeError, match='events should be a NumPy array'):
         Epochs(raw, events, event_id, tmin, tmax)