Repository: NeuralEnsemble/python-neo

Issue:
Slicing epochs does only slice times not durations
When slicing an epoch only the times array is sliced and the durations array is not modified. This results in incompatible number of time stamps and durations.

Discussion:
pep8speaks: Hello @apdavison! Thanks for submitting the PR.

 - In the file [`neo/core/epoch.py`](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py), following are the PEP8 issues :

> [Line 22:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L22): [E302](https://duckduckgo.com/?q=pep8%20E302) expected 2 blank lines, found 1
> [Line 23:17](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L23): [E127](https://duckduckgo.com/?q=pep8%20E127) continuation line over-indented for visual indent
> [Line 23:75](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L23): [E251](https://duckduckgo.com/?q=pep8%20E251) unexpected spaces around keyword / parameter equals
> [Line 23:77](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L23): [E251](https://duckduckgo.com/?q=pep8%20E251) unexpected spaces around keyword / parameter equals
> [Line 26:70](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L26): [W291](https://duckduckgo.com/?q=pep8%20W291) trailing whitespace
> [Line 28:15](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L28): [E201](https://duckduckgo.com/?q=pep8%20E201) whitespace after '('
> [Line 28:100](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L28): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (112 > 99 characters)
> [Line 29:18](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L29): [E127](https://duckduckgo.com/?q=pep8%20E127) continuation line over-indented for visual indent
> [Line 33:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L33): [E302](https://duckduckgo.com/?q=pep8%20E302) expected 2 blank lines, found 1
> [Line 118:5](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L118): [E301](https://duckduckgo.com/?q=pep8%20E301) expected 1 blank line, found 0
> [Line 125:60](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L125): [W291](https://duckduckgo.com/?q=pep8%20W291) trailing whitespace
> [Line 207:67](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L207): [W291](https://duckduckgo.com/?q=pep8%20W291) trailing whitespace
> [Line 244:9](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L244): [E265](https://duckduckgo.com/?q=pep8%20E265) block comment should start with '# '
> [Line 245:9](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/core/epoch.py#L245): [E265](https://duckduckgo.com/?q=pep8%20E265) block comment should start with '# '

 - In the file [`neo/test/coretest/test_epoch.py`](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py), following are the PEP8 issues :

> [Line 240:58](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L240): [E231](https://duckduckgo.com/?q=pep8%20E231) missing whitespace after ','
> [Line 256:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L256): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 257:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L257): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 258:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L258): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 259:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L259): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 262:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L262): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 290:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L290): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 293:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L293): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 294:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L294): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 295:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L295): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 298:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L298): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 314:5](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L314): [E303](https://duckduckgo.com/?q=pep8%20E303) too many blank lines (2)
> [Line 325:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L325): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 326:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L326): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 327:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L327): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 328:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L328): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 331:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L331): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 359:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L359): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 361:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L361): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 362:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L362): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 363:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L363): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 366:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L366): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 380:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L380): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 394:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L394): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 395:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L395): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 396:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L396): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 397:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L397): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 400:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L400): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 414:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L414): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 428:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L428): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 431:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L431): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 432:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L432): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 433:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L433): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 436:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L436): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 450:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L450): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 464:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L464): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 465:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L465): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 466:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L466): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 467:21](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L467): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 470:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L470): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 471:25](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L471): [E221](https://duckduckgo.com/?q=pep8%20E221) multiple spaces before operator
> [Line 484:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L484): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 511:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L511): [W293](https://duckduckgo.com/?q=pep8%20W293) blank line contains whitespace
> [Line 541:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L541): [E302](https://duckduckgo.com/?q=pep8%20E302) expected 2 blank lines, found 1
> [Line 561:1](https://github.com/NeuralEnsemble/python-neo/blob/a51ab8b16efe9d342375b688c269567647e76f1e/neo/test/coretest/test_epoch.py#L561): [E305](https://duckduckgo.com/?q=pep8%20E305) expected 2 blank lines after class or function definition, found 1


coveralls: 
[![Coverage Status](https://coveralls.io/builds/14981826/badge)](https://coveralls.io/builds/14981826)

Coverage increased (+0.05%) to 49.221% when pulling **a51ab8b16efe9d342375b688c269567647e76f1e on apdavison:issue413** into **6fd9f49c8b0c497adfa777549cc97dc301f2dba2 on NeuralEnsemble:master**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/14981916/badge)](https://coveralls.io/builds/14981916)

Coverage increased (+0.05%) to 49.221% when pulling **cbcf404cdd0ca665b2da22360ef78d4a1c705f75 on apdavison:issue413** into **6fd9f49c8b0c497adfa777549cc97dc301f2dba2 on NeuralEnsemble:master**.

samuelgarcia: Hi andrew. Could you fix conflict in the file. So it would trigered a new test on circleci ?
So we could merge.
bjoern1001001: I have a question about this, because I have been working on `SpikeTrain.__getitem__` for the last days. It's rather general, but I noticed this here.

I noticed here that what you wrote works in Epoch for things like epoch[1], while it would raise an error in SpikeTrain, because when you create the new Epoch in `__getitem__`, times is a quantity scalar, NOT an array or Epoch. Creating a SpikeTrain like this in `__getitem__` via `SpikeTrain(times=super(...).__getitem, ...)` would raise an error here saying it's testing the length of an unsized object. Is it supposed to be okay that epochs are created with a scalar quantity instead of a quantity array? And if that is the case, shouldn't it be converted to an array then in order to ensure consistency?

A little example of what happens:

`epoch = neo.Epoch([1,2,3]*pq.s)`
`ep1 = epoch[1] # ep1 is now an Epoch with times=2*pq.s, not [2]*pq.s or array([2]*pq.s)`

This is because the following happens in `__getitem__`:
`times = super(...).__getitem__(1)` 
Times now becomes a scalar quantity, because numpy `__getitem__` returns a scalar instead of an array when called with int index. From this pq.Quantity.__getitem__ creates a quantity, because it is not yet a quantity.

`obj = Epoch(times=times, ...)`
This is not a problem, because there is no test about whether times is an array or not
 `...`
`return obj # This returns obj, with times=2*pq.s`

Should it be like this or should a test for this be introduced?

Apart from that I'd like to know if any of you has deeper knowledge of `__getitem__` because I noticed together with @JuliaSprenger that there a scalar quantity is returned instead of a SpikeTrain object. I've been trying to change this but it fails. Trying to copy what you did, I noticed that this works for Epoch, but not for SpikeTrain.

Again some code to illustrate what I mean:

What currently happens:
`st1 = new SpikeTrain(times=[1,2,3]*pq.s, ...)`
`testobj = st1[1]`
testobj is now a (scalar) quantity object, not a SpikeTrain
`print(testobject) # This prints 2 s`

`new_st = st1[0:1]`
new_st is a SpikeTrain, because numpy returns a SpikeTrain array
`print(new_st) # This prints [1] s` 



If one would do the same as you did in Epoch for SpikeTrain, it would raise an error
`st2 = st1[1] # This would raise an error`

What happens SpikeTrain `__getitem__`:

`times = super(...).__getitem__(1)`
times is now a scalar quantity just like in Epoch

`obj = SpikeTrain(times=times, ...)`
This will raise an error in `SpikeTrain.__new__` (line 220), because times is a scalar, and thus an unsized object: TypeError: len() of unsized object

On the other hand, calling things like `st1[0:1]` will work just fine, because numpy then returns an array (or a subclass, which is SpikeTrain in this case)


I then tried creating a new SpikeTrain if I get a quantity by creating a list with a single entry:

`if not isinstance(obj, SpikeTrain):`
        `obj = SpikeTrain(times=obj.magnitude, t_stop=self.t_stop, units=self.units) # Error happens here`

This works for most cases, but it fails whenever calling sorted(st1, st2), because apparently some kind of 'intermediate' SpikeTrains are generated that don't contain any attributes.
The error I get then is that SpikeTrain object [referring to `self` here] has no attribute t_stop.
If anybody knows more about this stuff, I'd really appreciate your help.
bjoern1001001: I kept working on this problem and noticed that returning a SpikeTrain when st[int] is called would create more problems than it solves. So it seems to be fine that a scalar Quantity object is returned.

But in my opinion this should be consistent across all neo objects, which means that also here in Epoch.__getitem__ an Epoch should be returned only, when ep[slice] was called, not when ep[int] was called. Do you agree with this @apdavison @samuelgarcia?
This would also simplify the code a bit here, because no new Epoch would have to be created but instead you would only have to check if an Epoch was returned from super(...).__getitem__() and if that is the case, slice durations correctly, like it is done in SpikeTrain.__getitem__.

On a more general level, as I wrote in the previous comment, I want to ask if it makes sense to allow Epochs to be created with times being a scalar instead of an array. In class SpikeTrain there are checks that fail if times is not a list or an array, whereas in Epoch nothing similar happens. If times is a scalar, then ep.times is simply a scalar quantity. Are there reasons for this or should checks be implemented to make sure it's consistent? And if it should be allowed, wouldn't it make sense to wrap it in an array then?
Apart from that it's also not assured that ep.labels and ep.durations are the same length as ep.times. I think this should also be checked in order to ensure consistency.

Patch:
diff --git a/neo/core/epoch.py b/neo/core/epoch.py
index a5cd367c..359947f9 100644
--- a/neo/core/epoch.py
+++ b/neo/core/epoch.py
@@ -24,10 +24,10 @@ def _new_epoch(cls, times=None, durations=None, labels=None, units=None,
                name=None, description=None, file_origin=None, annotations=None, segment=None):
     '''
     A function to map epoch.__new__ to function that
-    does not do the unit checking. This is needed for pickle to work. 
+    does not do the unit checking. This is needed for pickle to work.
     '''
-    e = Epoch(times=times, durations=durations, labels=labels, units=units, name=name, file_origin=file_origin,
-              description=description, **annotations)
+    e = Epoch(times=times, durations=durations, labels=labels, units=units, name=name,
+              file_origin=file_origin, description=description, **annotations)
     e.segment = segment
     return e
 
@@ -151,6 +151,16 @@ class Epoch(BaseNeo, pq.Quantity):
                 label, time, dur in zip(labels, self.times, self.durations)]
         return '<Epoch: %s>' % ', '.join(objs)
 
+    def __getitem__(self, i):
+        '''
+        Get the item or slice :attr:`i`.
+        '''
+        obj = Epoch(times=super(Epoch, self).__getitem__(i))
+        obj._copy_data_complement(self)
+        obj.durations = self.durations[i]
+        obj.labels = self.labels[i]
+        return obj
+
     @property
     def times(self):
         return pq.Quantity(self)
@@ -232,10 +242,7 @@ class Epoch(BaseNeo, pq.Quantity):
             _t_stop = np.inf
 
         indices = (self >= _t_start) & (self <= _t_stop)
-
         new_epc = self[indices]
-        new_epc.durations = self.durations[indices]
-        new_epc.labels = self.labels[indices]
         return new_epc
 
     def as_array(self, units=None):


Test patch:
diff --git a/neo/test/coretest/test_epoch.py b/neo/test/coretest/test_epoch.py
index 93f3acac..82449951 100644
--- a/neo/test/coretest/test_epoch.py
+++ b/neo/test/coretest/test_epoch.py
@@ -497,6 +497,28 @@ class TestEpoch(unittest.TestCase):
         self.assertIsInstance(epc_as_q, pq.Quantity)
         assert_array_equal(times * pq.ms, epc_as_q)
 
+    def test_getitem(self):
+        times = [2, 3, 4, 5]
+        durations = [0.1, 0.2, 0.3, 0.4]
+        labels = ["A", "B", "C", "D"]
+        epc = Epoch(times * pq.ms, durations=durations * pq.ms, labels=labels)
+        single_epoch = epc[2]
+        self.assertIsInstance(single_epoch, Epoch)
+        assert_array_equal(single_epoch.times, np.array([4.0]))
+        assert_array_equal(single_epoch.durations, np.array([0.3]))
+        assert_array_equal(single_epoch.labels, np.array(["C"]))
+
+    def test_slice(self):
+        times = [2, 3, 4, 5]
+        durations = [0.1, 0.2, 0.3, 0.4]
+        labels = ["A", "B", "C", "D"]
+        epc = Epoch(times * pq.ms, durations=durations * pq.ms, labels=labels)
+        single_epoch = epc[1:3]
+        self.assertIsInstance(single_epoch, Epoch)
+        assert_array_equal(single_epoch.times, np.array([3.0, 4.0]))
+        assert_array_equal(single_epoch.durations, np.array([0.2, 0.3]))
+        assert_array_equal(single_epoch.labels, np.array(["B", "C"]))
+
 
 class TestDuplicateWithNewData(unittest.TestCase):
     def setUp(self):