In [1]:
%pylab inline
from pyannote.core import notebook


Populating the interactive namespace from numpy and matplotlib

Timeline (pyannote.core.timeline.Timeline)


In [2]:
from pyannote.core import Timeline

Timeline instances are used to describe sets of temporal fragments (e.g. of an audio file).
One can optionally store an identifier of the associated multimedia document using uri keyword argument.


In [3]:
timeline = Timeline(uri='MyAudioFile')

Temporal fragments can be added to the timeline in any order and may be overlapping.


In [4]:
from pyannote.core import Segment
timeline.add(Segment(6, 8))
timeline.add(Segment(0.5, 3))
timeline.add(Segment(8.5, 10))
timeline.add(Segment(1, 4))
timeline.add(Segment(5, 7))
timeline.add(Segment(7, 8))

They are automatically sorted internally (by start time first).


In [5]:
for segment in timeline:
    print segment


[0.500 --> 3.000]
[1.000 --> 4.000]
[5.000 --> 7.000]
[6.000 --> 8.000]
[7.000 --> 8.000]
[8.500 --> 10.000]

In [6]:
print "Timeline contains %d segments" % len(timeline)
print "The second segment of timeline is %s" % (str(timeline[1]))


Timeline contains 6 segments
The second segment of timeline is [1.000 --> 4.000]

One can visualize Timeline instances in IPython Notebook.


In [7]:
timeline


Out[7]:

Coverage, extent and gaps

The extent of a timeline is the segment of minimum duration that contains every segments of the timeline.


In [8]:
timeline.extent()


Out[8]:

The coverage of a timeline is the timeline with the minimum number of segments with exactly the same time span as the original timeline.


In [9]:
timeline.coverage()


Out[9]:

One can also retrieve gaps in a timeline.


In [10]:
timeline.gaps()


Out[10]:

In [11]:
timeline.gaps(focus=Segment(0, 10.5))


Out[11]:

Cropping

Using the crop method, it is possible to select a subpart of timeline.


In [12]:
selection = Segment(3,7)
selection


Out[12]:

In [13]:
timeline


Out[13]:

In intersection mode, segments are cut in half if needed.


In [14]:
timeline.crop(selection, mode='intersection')


Out[14]:

In strict mode, only segments fully included in selection are kept.


In [15]:
timeline.crop(selection, mode='strict')


Out[15]:

In loose mode, any segment with a non-empty intersection is kept unchanged even though it starts before or end after the selection.


In [16]:
timeline.crop(selection, mode='loose')


Out[16]:

Union of timeline

The update (in place) and union (copy) methods can be used to combine two timelines.


In [17]:
notebook.crop = Segment(0, 6)
first_timeline = Timeline([Segment(0, 1), Segment(2, 3), Segment(4, 5)])
first_timeline


Out[17]:

In [18]:
second_timeline = Timeline([Segment(1.5, 4.5)])
second_timeline


Out[18]:

In [19]:
new_timeline = first_timeline.union(second_timeline)
new_timeline


Out[19]:

Intersection of timelines


In [20]:
second_timeline.crop(first_timeline)


Out[20]:

co_iter method allow to iterator over pairs of intersecting segments.


In [21]:
for s_first, s_second in first_timeline.co_iter(second_timeline):
    print s_first, s_second


[2.000 --> 3.000] [1.500 --> 4.500]
[4.000 --> 5.000] [1.500 --> 4.500]

Need help?

You can always try the following...
Who knows? It might give you the information you are looking for!


In [22]:
help(Timeline)


Help on class Timeline in module pyannote.core.timeline:

class Timeline(__builtin__.object)
 |  Ordered set of segments.
 |  
 |  A timeline can be seen as an ordered set of non-empty segments (Segment).
 |  Segments can overlap -- though adding an already exisiting segment to a
 |  timeline does nothing.
 |  
 |  Parameters
 |  ----------
 |  segments : Segment iterator, optional
 |      initial set of segments
 |  uri : string, optional
 |      name of segmented resource
 |  
 |  Returns
 |  -------
 |  timeline : Timeline
 |      New timeline
 |  
 |  Examples
 |  --------
 |  Create a new empty timeline
 |  
 |      >>> timeline = Timeline()
 |      >>> if not timeline:
 |      ...    print "Timeline is empty."
 |      Timeline is empty.
 |  
 |  Add one segment (+=)
 |  
 |      >>> segment = Segment(0, 1)
 |      >>> timeline.add(segment)
 |      >>> if len(timeline) == 1:
 |      ...    print "Timeline contains only one segment."
 |      Timeline contains only one segment.
 |  
 |  Add all segments from another timeline
 |  
 |      >>> other_timeline = Timeline([Segment(0.5, 3), Segment(6, 8)])
 |      >>> timeline.update(other_timeline)
 |  
 |  Get timeline extent, coverage & duration
 |  
 |      >>> extent = timeline.extent()
 |      >>> print extent
 |      [0 --> 8]
 |      >>> coverage = timeline.coverage()
 |      >>> print coverage
 |      [
 |         [0 --> 3]
 |         [6 --> 8]
 |      ]
 |      >>> duration = timeline.duration()
 |      >>> print "Timeline covers a total of %g seconds." % duration
 |      Timeline covers a total of 5 seconds.
 |  
 |  Iterate over (sorted) timeline segments
 |  
 |      >>> for segment in timeline:
 |      ...    print segment
 |      [0 --> 1]
 |      [0.5 --> 3]
 |      [6 --> 8]
 |  
 |  Segmentation
 |  
 |      >>> segmentation = timeline.segmentation()
 |      >>> print segmentation
 |      [
 |         [0 --> 0.5]
 |         [0.5 --> 1]
 |         [1 --> 3]
 |         [6 --> 8]
 |      ]
 |  
 |  Gaps
 |  
 |      >>> timeline = timeline.copy()
 |      >>> print timeline
 |      [
 |         [0 --> 1]
 |         [0.5 --> 3]
 |         [6 --> 8]
 |      ]
 |      >>> print timeline.gaps()
 |      [
 |         [3 --> 6]
 |      ]
 |      >>> segment = Segment(0, 10)
 |      >>> print timeline.gaps(segment)
 |      [
 |         [3 --> 6]
 |         [8 --> 10]
 |      ]
 |  
 |  Methods defined here:
 |  
 |  __bool__(self)
 |  
 |  __contains__(self, included)
 |      Inclusion
 |      
 |      Use expression 'segment in timeline' or 'other_timeline in timeline'
 |      
 |      Parameters
 |      ----------
 |      included : `Segment` or `Timeline`
 |      
 |      Returns
 |      -------
 |      contains : bool
 |          True if every segment in `included` exists in timeline,
 |          False otherwise
 |  
 |  __eq__(self, other)
 |  
 |  __getitem__(self, k)
 |      Returns kth segment
 |  
 |  __init__(self, segments=None, uri=None)
 |  
 |  __iter__(self)
 |  
 |  __len__(self)
 |  
 |  __ne__(self, other)
 |  
 |  __nonzero__(self)
 |  
 |  __repr__(self)
 |  
 |  __str__(self)
 |      Human-friendly representation
 |  
 |  add(self, segment)
 |      Add segment
 |  
 |  co_iter(self, other)
 |  
 |  copy(self, segment_func=None)
 |      Duplicate timeline.
 |      
 |      If segment_func is provided, apply it to each segment first.
 |      
 |      Parameters
 |      ----------
 |      segment_func : function
 |      
 |      Returns
 |      -------
 |      timeline : Timeline
 |          A (possibly modified) copy of the timeline
 |      
 |      Examples
 |      --------
 |      
 |          >>> timeline = Timeline(uri="MyVideo.avi")
 |          >>> timeline += [Segment(0, 1), Segment(2, 3)]
 |          >>> cp = timeline.copy()
 |          >>> print cp.uri
 |          MyVideo.avi
 |          >>> print cp
 |          [
 |             [0 --> 1]
 |             [2 --> 3]
 |          ]
 |  
 |  coverage(self)
 |      Timeline coverage
 |      
 |      The coverage of timeline is the timeline with the minimum number of
 |      segments with exactly the same time span as the original timeline.
 |      It is (by definition) unique and does not contain any overlapping
 |      segments.
 |      
 |      Returns
 |      -------
 |      coverage : Timeline
 |          Timeline coverage
 |  
 |  crop(self, other, mode='intersection', mapping=False)
 |  
 |  duration(self)
 |      Timeline duration
 |      
 |      Returns
 |      -------
 |      duration : float
 |          Duration of timeline coverage, in seconds.
 |  
 |  empty(self)
 |      Empty copy of a timeline.
 |      
 |      Examples
 |      --------
 |      
 |          >>> timeline = Timeline(uri="MyVideo.avi")
 |          >>> timeline += [Segment(0, 1), Segment(2, 3)]
 |          >>> empty = timeline.empty()
 |          >>> print empty.uri
 |          MyVideo.avi
 |          >>> print empty
 |          [
 |          ]
 |  
 |  extent(self)
 |      Timeline extent
 |      
 |      The extent of a timeline is the segment of minimum duration that
 |      contains every segments of the timeline. It is unique, by definition.
 |      The extent of an empty timeline is an empty segment.
 |      
 |      Returns
 |      -------
 |      extent : Segment
 |          Timeline extent
 |      
 |      Examples
 |      --------
 |      
 |          >>> timeline = Timeline(uri="MyVideo.avi")
 |          >>> timeline += [Segment(0, 1), Segment(9, 10)]
 |          >>> print timeline.extent()
 |          [0 --> 10]
 |  
 |  for_json(self)
 |  
 |  gaps(self, focus=None)
 |      Timeline gaps
 |      
 |      Parameters
 |      ----------
 |      focus : None, Segment or Timeline
 |      
 |      Returns
 |      -------
 |      gaps : Timeline
 |          Timeline made of all gaps from original timeline, and delimited
 |          by provided segment or timeline.
 |      
 |      Raises
 |      ------
 |      TypeError when `focus` is neither None, Segment nor Timeline
 |      
 |      Examples
 |      --------
 |  
 |  index(self, segment)
 |      Index of segment
 |      
 |      Parameter
 |      ---------
 |      segment : Segment
 |      
 |      Raises
 |      ------
 |      ValueError if the segment is not present
 |  
 |  overlapping(self, timestamp)
 |      Get list of segments overlapping `timestamp`
 |  
 |  segmentation(self)
 |      Non-overlapping timeline
 |      
 |      Create the unique timeline with same coverage and same set of segment
 |      boundaries as original timeline, but with no overlapping segments.
 |      
 |      A picture is worth a thousand words:
 |      
 |          Original timeline:
 |          |------|    |------|     |----|
 |            |--|    |-----|     |----------|
 |      
 |          Non-overlapping timeline
 |          |-|--|-|  |-|---|--|  |--|----|--|
 |      
 |      Returns
 |      -------
 |      timeline : Timeline
 |      
 |      Examples
 |      --------
 |      
 |          >>> timeline = Timeline()
 |          >>> timeline += [Segment(0, 1), Segment(1, 2), Segment(2,3)]
 |          >>> timeline += [Segment(2, 4), Segment(6, 7)]
 |          >>> print timeline.segmentation()
 |          [
 |             [0 --> 1]
 |             [1 --> 2]
 |             [2 --> 3]
 |             [3 --> 4]
 |             [6 --> 7]
 |          ]
 |  
 |  union(self, other)
 |      Create new timeline made of union of segments
 |  
 |  update(self, timeline)
 |      Add `timeline` segments
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  from_df(cls, df, uri=None) from __builtin__.type
 |  
 |  from_json(cls, data) from __builtin__.type
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)