Skip to content

sgnts.base.slice_tools

TSSlice dataclass

A class to support operations on an ordered tuple of integers start, stop.

Parameters:

Name Type Description Default
start int

int, The start of the TSSlice

required
stop int

int, The stop of the TSSlice

required
Source code in sgnts/base/slice_tools.py
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
@dataclass
class TSSlice:
    """A class to support operations on an ordered tuple of integers start, stop.

    Args:
        start:
            int, The start of the TSSlice
        stop:
            int, The stop of the TSSlice
    """

    start: int
    stop: int

    def __post_init__(self):
        if (self.start is None and self.stop is not None) or (
            self.stop is None and self.start is not None
        ):
            raise ValueError("if one of start or stop is None, both must be")
        if self.start is not None:
            if not isinstance(self.start, int) or not isinstance(self.stop, int):
                raise ValueError("if not None, start and stop must be integers")
            if not (self.stop >= self.start):
                raise ValueError("stop must be greater than or equal to start")

    @property
    def slice(self):
        """Convert to a python slice object with a stride of 1."""
        if self:
            return slice(self.start, self.stop, 1)
        else:
            return slice(-1, -1, 1)

    def __getitem__(self, item):
        assert item in (0, 1)
        if item == 0:
            return self.start
        else:
            return self.stop

    def __and__(self, o):
        """Find the intersection of two TSSlices

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> A&B
            TSSlice(start=2, stop=3)
            >>> B&A
            TSSlice(start=2, stop=3)

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> A&B
            TSSlice(start=None, stop=None)
            >>> B&A
            TSSlice(start=None, stop=None)

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> A&B
            TSSlice(start=None, stop=None)
            >>> B&A
            TSSlice(start=None, stop=None)
        """
        if self.start is None or self.stop is None or o.start is None or o.stop is None:
            return TSSlice(None, None)
        _start, _stop = max(self.start, o.start), min(self.stop, o.stop)
        if _start > _stop:
            return TSSlice(None, None)
        return TSSlice(_start, _stop)

    def __or__(self, o):
        """Find the TSSlice that spans both self and o.

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> A|B
            TSSlice(start=0, stop=5)
            >>> B|A
            TSSlice(start=0, stop=5)

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> A|B
            TSSlice(start=0, stop=6)
            >>> B|A
            TSSlice(start=0, stop=6)

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> A|B
            TSSlice(start=None, stop=None)
            >>> B|A
            TSSlice(start=None, stop=None)
        """
        if self.start is None or self.stop is None or o.start is None or o.stop is None:
            return TSSlice(None, None)
        return TSSlice(min(self.start, o.start), max(self.stop, o.stop))

    def __bool__(self):
        """Check the truth value of this TSSlice.

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> True if A else False
            True
            >>> True if B else False
            True

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> True if A else False
            True
            >>> True if B else False
            True

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> True if A else False
            True
            >>> True if B else False
            False
        """

        if self.start is None:
            assert self.stop is None
        if self.stop is None:
            assert self.start is None
        if self.start is None:
            return False
        else:
            return True

    def __add__(self, o):
        """Add two TSSlices together producing a single TSSlice if they intersect
        otherwise returning each in a list.

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> A+B
            [TSSlice(start=0, stop=5)]
            >>> B+A
            [TSSlice(start=0, stop=5)]

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> A+B
            [TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]
            >>> B+A
            [TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> A+B
            [TSSlice(start=0, stop=3), TSSlice(start=None, stop=None)]
            >>> B+A
            [TSSlice(start=None, stop=None), TSSlice(start=0, stop=3)]
        """
        if self & o:
            return [self | o]
        else:
            return sorted([self, o])

    def __gt__(self, o):
        """Check if a slice is greater than another slice.

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> A>B
            False
            >>> B>A
            True

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> A>B
            False
            >>> B>A
            True

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> A>B
            False
            >>> B>A
            False
        """
        if self.start is None or self.stop is None or o.start is None or o.stop is None:
            return False
        return self.start > o.start and self.stop > o.stop

    def __lt__(self, o):
        if self.start is None or self.stop is None or o.start is None or o.stop is None:
            return False
        return self.start < o.start and self.stop < o.stop

    def __ge__(self, o):
        return self.start >= o.start and self.stop >= o.stop

    def __le__(self, o):
        return self.start <= o.start and self.stop <= o.stop

    def __sub__(self, o):
        """Find the difference of two overlapping slices, it not overlapping return an
        empty list.

        Examples:
            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=2, stop=5)
            >>> A-B
            [TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]
            >>> B-A
            [TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=4, stop=6)
            >>> A-B
            []
            >>> B-A
            []

            >>> A = TSSlice(start=0, stop=3)
            >>> B = TSSlice(start=None, stop=None)
            >>> A-B
            []
            >>> B-A
            []
        """
        b = self | o
        i = self & o
        if not b or not i:
            return []
        out = [TSSlice(b.start, i.start), TSSlice(i.stop, b.stop)]
        return sorted(o for o in out if o.isfinite())

    def __contains__(self, o):
        return o.start >= self.start and o.stop <= self.stop

    def split(self, o: int):
        """Split the slice with the given boundary value.

        Args:
            o:
                int, the boundary to split the tsslice
        """
        assert self.start <= o < self.stop
        return [TSSlice(self.start, o), TSSlice(o, self.stop)]

    def isfinite(self):
        if not self:
            return False
        else:
            return self.stop > self.start

slice property

Convert to a python slice object with a stride of 1.

__add__(o)

Add two TSSlices together producing a single TSSlice if they intersect otherwise returning each in a list.

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> A+B
[TSSlice(start=0, stop=5)]
>>> B+A
[TSSlice(start=0, stop=5)]
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> A+B
[TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]
>>> B+A
[TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> A+B
[TSSlice(start=0, stop=3), TSSlice(start=None, stop=None)]
>>> B+A
[TSSlice(start=None, stop=None), TSSlice(start=0, stop=3)]
Source code in sgnts/base/slice_tools.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def __add__(self, o):
    """Add two TSSlices together producing a single TSSlice if they intersect
    otherwise returning each in a list.

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> A+B
        [TSSlice(start=0, stop=5)]
        >>> B+A
        [TSSlice(start=0, stop=5)]

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> A+B
        [TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]
        >>> B+A
        [TSSlice(start=0, stop=3), TSSlice(start=4, stop=6)]

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> A+B
        [TSSlice(start=0, stop=3), TSSlice(start=None, stop=None)]
        >>> B+A
        [TSSlice(start=None, stop=None), TSSlice(start=0, stop=3)]
    """
    if self & o:
        return [self | o]
    else:
        return sorted([self, o])

__and__(o)

Find the intersection of two TSSlices

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> A&B
TSSlice(start=2, stop=3)
>>> B&A
TSSlice(start=2, stop=3)
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> A&B
TSSlice(start=None, stop=None)
>>> B&A
TSSlice(start=None, stop=None)
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> A&B
TSSlice(start=None, stop=None)
>>> B&A
TSSlice(start=None, stop=None)
Source code in sgnts/base/slice_tools.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def __and__(self, o):
    """Find the intersection of two TSSlices

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> A&B
        TSSlice(start=2, stop=3)
        >>> B&A
        TSSlice(start=2, stop=3)

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> A&B
        TSSlice(start=None, stop=None)
        >>> B&A
        TSSlice(start=None, stop=None)

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> A&B
        TSSlice(start=None, stop=None)
        >>> B&A
        TSSlice(start=None, stop=None)
    """
    if self.start is None or self.stop is None or o.start is None or o.stop is None:
        return TSSlice(None, None)
    _start, _stop = max(self.start, o.start), min(self.stop, o.stop)
    if _start > _stop:
        return TSSlice(None, None)
    return TSSlice(_start, _stop)

__bool__()

Check the truth value of this TSSlice.

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> True if A else False
True
>>> True if B else False
True
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> True if A else False
True
>>> True if B else False
True
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> True if A else False
True
>>> True if B else False
False
Source code in sgnts/base/slice_tools.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
def __bool__(self):
    """Check the truth value of this TSSlice.

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> True if A else False
        True
        >>> True if B else False
        True

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> True if A else False
        True
        >>> True if B else False
        True

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> True if A else False
        True
        >>> True if B else False
        False
    """

    if self.start is None:
        assert self.stop is None
    if self.stop is None:
        assert self.start is None
    if self.start is None:
        return False
    else:
        return True

__gt__(o)

Check if a slice is greater than another slice.

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> A>B
False
>>> B>A
True
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> A>B
False
>>> B>A
True
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> A>B
False
>>> B>A
False
Source code in sgnts/base/slice_tools.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def __gt__(self, o):
    """Check if a slice is greater than another slice.

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> A>B
        False
        >>> B>A
        True

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> A>B
        False
        >>> B>A
        True

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> A>B
        False
        >>> B>A
        False
    """
    if self.start is None or self.stop is None or o.start is None or o.stop is None:
        return False
    return self.start > o.start and self.stop > o.stop

__or__(o)

Find the TSSlice that spans both self and o.

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> A|B
TSSlice(start=0, stop=5)
>>> B|A
TSSlice(start=0, stop=5)
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> A|B
TSSlice(start=0, stop=6)
>>> B|A
TSSlice(start=0, stop=6)
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> A|B
TSSlice(start=None, stop=None)
>>> B|A
TSSlice(start=None, stop=None)
Source code in sgnts/base/slice_tools.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def __or__(self, o):
    """Find the TSSlice that spans both self and o.

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> A|B
        TSSlice(start=0, stop=5)
        >>> B|A
        TSSlice(start=0, stop=5)

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> A|B
        TSSlice(start=0, stop=6)
        >>> B|A
        TSSlice(start=0, stop=6)

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> A|B
        TSSlice(start=None, stop=None)
        >>> B|A
        TSSlice(start=None, stop=None)
    """
    if self.start is None or self.stop is None or o.start is None or o.stop is None:
        return TSSlice(None, None)
    return TSSlice(min(self.start, o.start), max(self.stop, o.stop))

__sub__(o)

Find the difference of two overlapping slices, it not overlapping return an empty list.

Examples:

>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=2, stop=5)
>>> A-B
[TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]
>>> B-A
[TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=4, stop=6)
>>> A-B
[]
>>> B-A
[]
>>> A = TSSlice(start=0, stop=3)
>>> B = TSSlice(start=None, stop=None)
>>> A-B
[]
>>> B-A
[]
Source code in sgnts/base/slice_tools.py
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
def __sub__(self, o):
    """Find the difference of two overlapping slices, it not overlapping return an
    empty list.

    Examples:
        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=2, stop=5)
        >>> A-B
        [TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]
        >>> B-A
        [TSSlice(start=0, stop=2), TSSlice(start=3, stop=5)]

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=4, stop=6)
        >>> A-B
        []
        >>> B-A
        []

        >>> A = TSSlice(start=0, stop=3)
        >>> B = TSSlice(start=None, stop=None)
        >>> A-B
        []
        >>> B-A
        []
    """
    b = self | o
    i = self & o
    if not b or not i:
        return []
    out = [TSSlice(b.start, i.start), TSSlice(i.stop, b.stop)]
    return sorted(o for o in out if o.isfinite())

split(o)

Split the slice with the given boundary value.

Parameters:

Name Type Description Default
o int

int, the boundary to split the tsslice

required
Source code in sgnts/base/slice_tools.py
248
249
250
251
252
253
254
255
256
def split(self, o: int):
    """Split the slice with the given boundary value.

    Args:
        o:
            int, the boundary to split the tsslice
    """
    assert self.start <= o < self.stop
    return [TSSlice(self.start, o), TSSlice(o, self.stop)]

TSSlices dataclass

A class that holds a list of TSSlice objects and defines some operations on them.

Parameters:

Name Type Description Default
slices list

list, A list of TSSlice objects. These will be stored in a sorted order and are assumed to be immutable

required
Source code in sgnts/base/slice_tools.py
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
@dataclass
class TSSlices:
    """A class that holds a list of TSSlice objects and defines some operations on them.

    Args:
        slices:
            list, A list of TSSlice objects. These will be stored in a sorted order and
            are assumed to be immutable
    """

    slices: list

    def __post_init__(self):
        self.slices = sorted(self.slices)

    def __iadd__(self, other):
        """Inplace add (a new instance is made though)"""
        return TSSlices(self.slices + other.slices)

    def simplify(self):
        """Merge overlapping slices and return a new instance of TSSlices.

        Examples:
            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
            >>> slices.simplify()
            TSSlices(slices=[TSSlice(start=0, stop=6)])

            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
            ...     TSSlice(start=8, stop=10)])
            >>> slices.simplify()
            TSSlices(slices=[TSSlice(start=0, stop=6), TSSlice(start=8, stop=10)])
        """

        out = self.slices[0:1].copy()
        for s in self.slices[1:]:
            this = s + out[-1]
            if len(this) == 2:
                out.append(this[-1])
            else:
                out[-1] = this[0]
        return TSSlices(out)

    def intersection(self):
        """Find the intersection of all slices. Might be empty.

        Examples:
            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
            >>> slices.intersection()
            TSSlice(start=2, stop=3)

            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
            ...     TSSlice(start=8, stop=10)])
            >>> slices.intersection()
            TSSlice(start=None, stop=None)
        """
        s = TSSlice(self.slices[0].start, self.slices[0].stop)
        for s2 in self.slices[1:]:
            s = s & s2
        return s

    def search(self, tsslice: TSSlice, align: bool = True):
        """Search for the set of TSSlices that overlap wtih tsslice. If align=True the
        returned slices will be truncated to exactly fall within tsslice.

        Args:
            tsslice:
                TSSlice, the tsslice to search for overlap with
            align:
                bool, whether to align the tsslices

        Examples:
            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
            >>> slices.search(TSSlice(2,4), align=True)
            TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
                TSSlice(start=2, stop=4)])
            >>> slices.search(TSSlice(2,4), align=False)
            TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
                TSSlice(start=2, stop=6)])

            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
            ...     TSSlice(start=8, stop=10)])
            >>> slices.search(TSSlice(2,4), align=True)
            TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
                TSSlice(start=2, stop=4)])
            >>> slices.search(TSSlice(2,4), align=False)
            TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
                TSSlice(start=2, stop=6)])
        """

        startix = bisect.bisect_left(self.slices, TSSlice(tsslice.start, tsslice.start))
        stopix = bisect.bisect_right(self.slices, TSSlice(tsslice.stop, tsslice.stop))
        if not align:
            return TSSlices(self.slices[startix:stopix])
        else:
            out = []
            for s in self.slices[startix:stopix]:
                o = s & tsslice
                if o.isfinite():
                    out.append(o)
            return TSSlices(out)

    def invert(self, boundary_slice: TSSlice):
        """Within boundary_slice, return an inverted set of TSSlice's.

        Args:
            boundary_slice:
                TSSlice, the boundary to invert the TSSlices

        Examples:
            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
            >>> slices.invert(TSSlice(2,4))
            TSSlices(slices=[])

            >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
            ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
            ...     TSSlice(start=8, stop=10)])
            >>> slices.invert(TSSlice(2,4))
            TSSlices(slices=[TSSlice(start=6, stop=8)])
        """

        if len(self.slices) == 0:
            return TSSlices([TSSlice(boundary_slice.start, boundary_slice.stop)])
        _slices = self.simplify().slices
        out = []
        if boundary_slice.start < _slices[0].start:
            out.append(TSSlice(boundary_slice.start, _slices[0].start))
        out.extend(
            [TSSlice(s1.stop, s2.start) for (s1, s2) in zip(_slices[:-1], _slices[1:])]
        )
        if boundary_slice.stop > _slices[-1].stop:
            out.append(TSSlice(_slices[-1].stop, boundary_slice.stop))
        return TSSlices(out)

__iadd__(other)

Inplace add (a new instance is made though)

Source code in sgnts/base/slice_tools.py
280
281
282
def __iadd__(self, other):
    """Inplace add (a new instance is made though)"""
    return TSSlices(self.slices + other.slices)

intersection()

Find the intersection of all slices. Might be empty.

Examples:

>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
>>> slices.intersection()
TSSlice(start=2, stop=3)
>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
...     TSSlice(start=8, stop=10)])
>>> slices.intersection()
TSSlice(start=None, stop=None)
Source code in sgnts/base/slice_tools.py
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
def intersection(self):
    """Find the intersection of all slices. Might be empty.

    Examples:
        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
        >>> slices.intersection()
        TSSlice(start=2, stop=3)

        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
        ...     TSSlice(start=8, stop=10)])
        >>> slices.intersection()
        TSSlice(start=None, stop=None)
    """
    s = TSSlice(self.slices[0].start, self.slices[0].stop)
    for s2 in self.slices[1:]:
        s = s & s2
    return s

invert(boundary_slice)

Within boundary_slice, return an inverted set of TSSlice's.

Parameters:

Name Type Description Default
boundary_slice TSSlice

TSSlice, the boundary to invert the TSSlices

required

Examples:

>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
>>> slices.invert(TSSlice(2,4))
TSSlices(slices=[])
>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
...     TSSlice(start=8, stop=10)])
>>> slices.invert(TSSlice(2,4))
TSSlices(slices=[TSSlice(start=6, stop=8)])
Source code in sgnts/base/slice_tools.py
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
def invert(self, boundary_slice: TSSlice):
    """Within boundary_slice, return an inverted set of TSSlice's.

    Args:
        boundary_slice:
            TSSlice, the boundary to invert the TSSlices

    Examples:
        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
        >>> slices.invert(TSSlice(2,4))
        TSSlices(slices=[])

        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
        ...     TSSlice(start=8, stop=10)])
        >>> slices.invert(TSSlice(2,4))
        TSSlices(slices=[TSSlice(start=6, stop=8)])
    """

    if len(self.slices) == 0:
        return TSSlices([TSSlice(boundary_slice.start, boundary_slice.stop)])
    _slices = self.simplify().slices
    out = []
    if boundary_slice.start < _slices[0].start:
        out.append(TSSlice(boundary_slice.start, _slices[0].start))
    out.extend(
        [TSSlice(s1.stop, s2.start) for (s1, s2) in zip(_slices[:-1], _slices[1:])]
    )
    if boundary_slice.stop > _slices[-1].stop:
        out.append(TSSlice(_slices[-1].stop, boundary_slice.stop))
    return TSSlices(out)

search(tsslice, align=True)

Search for the set of TSSlices that overlap wtih tsslice. If align=True the returned slices will be truncated to exactly fall within tsslice.

Parameters:

Name Type Description Default
tsslice TSSlice

TSSlice, the tsslice to search for overlap with

required
align bool

bool, whether to align the tsslices

True

Examples:

>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
>>> slices.search(TSSlice(2,4), align=True)
TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
    TSSlice(start=2, stop=4)])
>>> slices.search(TSSlice(2,4), align=False)
TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
    TSSlice(start=2, stop=6)])
>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
...     TSSlice(start=8, stop=10)])
>>> slices.search(TSSlice(2,4), align=True)
TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
    TSSlice(start=2, stop=4)])
>>> slices.search(TSSlice(2,4), align=False)
TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
    TSSlice(start=2, stop=6)])
Source code in sgnts/base/slice_tools.py
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
def search(self, tsslice: TSSlice, align: bool = True):
    """Search for the set of TSSlices that overlap wtih tsslice. If align=True the
    returned slices will be truncated to exactly fall within tsslice.

    Args:
        tsslice:
            TSSlice, the tsslice to search for overlap with
        align:
            bool, whether to align the tsslices

    Examples:
        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
        >>> slices.search(TSSlice(2,4), align=True)
        TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
            TSSlice(start=2, stop=4)])
        >>> slices.search(TSSlice(2,4), align=False)
        TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
            TSSlice(start=2, stop=6)])

        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
        ...     TSSlice(start=8, stop=10)])
        >>> slices.search(TSSlice(2,4), align=True)
        TSSlices(slices=[TSSlice(start=2, stop=4), TSSlice(start=2, stop=3),
            TSSlice(start=2, stop=4)])
        >>> slices.search(TSSlice(2,4), align=False)
        TSSlices(slices=[TSSlice(start=0, stop=4), TSSlice(start=1, stop=3),
            TSSlice(start=2, stop=6)])
    """

    startix = bisect.bisect_left(self.slices, TSSlice(tsslice.start, tsslice.start))
    stopix = bisect.bisect_right(self.slices, TSSlice(tsslice.stop, tsslice.stop))
    if not align:
        return TSSlices(self.slices[startix:stopix])
    else:
        out = []
        for s in self.slices[startix:stopix]:
            o = s & tsslice
            if o.isfinite():
                out.append(o)
        return TSSlices(out)

simplify()

Merge overlapping slices and return a new instance of TSSlices.

Examples:

>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
>>> slices.simplify()
TSSlices(slices=[TSSlice(start=0, stop=6)])
>>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
...     TSSlice(start=8, stop=10)])
>>> slices.simplify()
TSSlices(slices=[TSSlice(start=0, stop=6), TSSlice(start=8, stop=10)])
Source code in sgnts/base/slice_tools.py
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
def simplify(self):
    """Merge overlapping slices and return a new instance of TSSlices.

    Examples:
        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6)])
        >>> slices.simplify()
        TSSlices(slices=[TSSlice(start=0, stop=6)])

        >>> slices = TSSlices(slices=[TSSlice(start=0, stop=4),
        ...     TSSlice(start=1, stop=3), TSSlice(start=2, stop=6),
        ...     TSSlice(start=8, stop=10)])
        >>> slices.simplify()
        TSSlices(slices=[TSSlice(start=0, stop=6), TSSlice(start=8, stop=10)])
    """

    out = self.slices[0:1].copy()
    for s in self.slices[1:]:
        this = s + out[-1]
        if len(this) == 2:
            out.append(this[-1])
        else:
            out[-1] = this[0]
    return TSSlices(out)