Repository: obspy/obspy

Issue:
Stream.get_gaps() giving wrong results for some files
See details in https://github.com/obspy/obspy/pull/1141#issuecomment-218146707.



Discussion:
I think we should fix this for 1.2.0.
Here's some code to reproduce this:

```python 
import numpy as np
from obspy import Trace, Stream, UTCDateTime


data = [ 
    ("2016-01-07T00:00:00.008300Z", 3010),
    ("2016-01-07T00:00:02.668393Z", 686),
    ("2016-01-07T00:00:09.528393Z", 4086),
    ("2016-01-07T00:00:30.108393Z", 2028),
    ("2016-01-07T00:00:50.388393Z", 6158),
    ("2016-01-07T00:00:57.248393Z", 1370),
    ("2016-01-07T00:01:31.458393Z", 4107),
    ("2016-01-07T00:01:51.968393Z", 2056)]

x = np.arange(30000)
tr = Trace(x)
tr.stats.starttime = UTCDateTime("2016-01-07T00:00:00.008300Z")
tr.stats.sampling_rate = 100 

st = Stream()
for i, (start, numsamp) in enumerate(data):
    tr_ = tr.slice(starttime=UTCDateTime(start))
    tr_.data = tr_.data[:numsamp]
    st.append(tr_)

print(st)
st.plot()
st.plot(automerge=False)
st.print_gaps()
st.merge(-1)
st.plot()
st.print_gaps()
```
```
8 Trace(s) in Stream:
... | 2016-01-07T00:00:00.008300Z - 2016-01-07T00:00:30.098300Z | 100.0 Hz, 3010 samples
... | 2016-01-07T00:00:02.668300Z - 2016-01-07T00:00:09.518300Z | 100.0 Hz, 686 samples
... | 2016-01-07T00:00:09.528300Z - 2016-01-07T00:00:50.378300Z | 100.0 Hz, 4086 samples
... | 2016-01-07T00:00:30.108300Z - 2016-01-07T00:00:50.378300Z | 100.0 Hz, 2028 samples
... | 2016-01-07T00:00:50.388300Z - 2016-01-07T00:01:51.958300Z | 100.0 Hz, 6158 samples
... | 2016-01-07T00:00:57.248300Z - 2016-01-07T00:01:10.938300Z | 100.0 Hz, 1370 samples
... | 2016-01-07T00:01:31.458300Z - 2016-01-07T00:02:12.518300Z | 100.0 Hz, 4107 samples
... | 2016-01-07T00:01:51.968300Z - 2016-01-07T00:02:12.518300Z | 100.0 Hz, 2056 samples

Source            Last Sample                 Next Sample                 Delta           Samples 
...               2016-01-07T00:00:09.518300Z 2016-01-07T00:00:02.668300Z -6.850000       -685    
...               2016-01-07T00:00:50.378300Z 2016-01-07T00:00:30.108300Z -20.270000      -2027   
...               2016-01-07T00:01:10.938300Z 2016-01-07T00:00:57.248300Z -13.690000      -1369   
...               2016-01-07T00:01:10.938300Z 2016-01-07T00:01:31.458300Z 20.510000       2051    
...               2016-01-07T00:02:12.518300Z 2016-01-07T00:01:51.968300Z -20.550000      -2055   
Total: 1 gap(s) and 4 overlap(s)

Source            Last Sample                 Next Sample                 Delta           Samples 
Total: 0 gap(s) and 0 overlap(s)
```


@DominikStr I think this is something you could work on..

Make sure to branch off of current `master`, the new regression test case should check the output of `st.get_gaps()` similar to the above code and should be added to this file: https://github.com/obspy/obspy/blob/master/obspy/core/tests/test_stream.py

Resolving patch:
diff --git a/obspy/core/stream.py b/obspy/core/stream.py
--- a/obspy/core/stream.py
+++ b/obspy/core/stream.py
@@ -815,6 +815,24 @@ def get_gaps(self, min_gap=None, max_gap=None):
             # skip if is equal to delta (1 / sampling rate)
             if same_sampling_rate and nsamples == 0:
                 continue
+            # check if gap is already covered in trace before:
+            covered = False
+            # only need to check previous traces because the traces are sorted
+            for prev_trace in self.traces[:_i]:
+                prev_stats = prev_trace.stats
+                # look if trace is contained in other trace
+                prev_start = prev_stats['starttime']
+                prev_end = prev_stats['endtime']
+                if not (prev_start < stime < etime < prev_end):
+                    continue
+                # don't look in traces of other measurements
+                elif self.traces[_i].id != prev_trace.id:
+                    continue
+                else:
+                    covered = True
+                    break
+            if covered:
+                continue
             gap_list.append([stats['network'], stats['station'],
                              stats['location'], stats['channel'],
                              stime, etime, delta, nsamples])


Test patch:
diff --git a/obspy/core/tests/test_stream.py b/obspy/core/tests/test_stream.py
--- a/obspy/core/tests/test_stream.py
+++ b/obspy/core/tests/test_stream.py
@@ -1485,6 +1485,31 @@ def test_get_gaps_whole_overlap(self):
         endtime = gap[5]
         self.assertEqual(endtime, tr2.stats.starttime)
 
+    def test_get_gaps_overlap(self):
+        """
+         Tests the get_gaps method of the Stream objects.
+
+         Test for Issue #1403. Tests if wrong overlaps are returned.
+        """
+        data = [
+            ("2016-01-07T00:00:50.388393Z", 6158),
+            ("2016-01-07T00:00:57.248393Z", 1370),
+            ("2016-01-07T00:01:31.458393Z", 4107)]
+
+        x = np.arange(20000)
+        tr = Trace(x)
+        tr.stats.starttime = UTCDateTime("2016-01-07T00:00:50.388393Z")
+        tr.stats.sampling_rate = 100
+
+        st = Stream()
+        for i, (start, numsamp) in enumerate(data):
+            tr_ = tr.slice(starttime=UTCDateTime(start))
+            tr_.data = tr_.data[:numsamp]
+            st.append(tr_)
+
+        # min_gap=1 is used to only show the gaps
+        self.assertEqual(len(st.get_gaps(min_gap=1)), 0)
+
     def test_comparisons(self):
         """
         Tests all rich comparison operators (==, !=, <, <=, >, >=)