Skip to content

Commit

Permalink
Merge pull request #204 from marl/trim-empty
Browse files Browse the repository at this point in the history
Boundary condition on trimming
  • Loading branch information
bmcfee authored Nov 24, 2019
2 parents 6bc2d2e + ed37c3c commit 255a5ee
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
12 changes: 11 additions & 1 deletion docs/jams_structure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Annotation

Each annotation object contains the following properties:
* ``namespace`` : a string describing the type of this annotation;
* ``data`` : a list of observations, each containing:
* ``data`` : a list of *observations*, each containing:
* ``time`` : non-negative number denoting the time of the observation (in seconds)
* ``duration`` : non-negative number denoting the duration of the observation (in seconds)
* ``value`` : actual annotation (e.g., chord, segment label)
Expand All @@ -42,6 +42,16 @@ Each annotation object contains the following properties:

The permissible contents of the ``value`` and ``confidence`` fields are defined by the ``namespace``.

The interpretation of the ``time`` and ``duration`` observation fields are as follows:

- if ``duration > 0``, the observation covers the half-open time interval ``[time, time + duration)``.
- if ``duration == 0``, the observation covers the closed interval ``[time, time]``, that is, the single time instant.

The first case is the most widely used, and the half-open interval convention eliminates ambiguity of interval membership at the boundaries of adjacent intervals.

The second case is primarily useful for instantaneous measurements (e.g., beat events) or uniformly sampled values of a temporally continuous signal (e.g., fundamental frequency
curve).

.. note:: The ``time`` and ``duration`` fields of ``annotation`` are considered optional. If left blank,
the annotation should be assumed to be valid for the entirety of the track.

Expand Down
3 changes: 2 additions & 1 deletion jams/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,8 @@ def trim(self, start_time, end_time, strict=False):
obs_start = obs.time
obs_end = obs_start + obs.duration

if obs_start < trim_end and obs_end > trim_start:
# Special-case here handles duration=0 as a closed interval
if obs_start < trim_end and (obs_end > trim_start or obs_start == obs_end >= trim_start):

new_start = max(obs_start, trim_start)
new_end = min(obs_end, trim_end)
Expand Down
32 changes: 16 additions & 16 deletions tests/test_jams.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,44 +801,44 @@ def test_annotation_trim_partial_overlap_beginning():
# range: at the beginning
# strict=False
namespace = 'tag_open'
data = dict(time=[5.0, 5.0, 10.0],
duration=[2.0, 4.0, 4.0],
value=['one', 'two', 'three'],
confidence=[0.9, 0.9, 0.9])
data = dict(time=[4.0, 5.0, 5.0, 5.0, 10.0],
duration=[1.0, 0.0, 2.0, 4.0, 4.0],
value=['none', 'zero', 'one', 'two', 'three'],
confidence=[1, 0.1, 0.9, 0.9, 0.9])
ann = jams.Annotation(namespace, data=data, time=5.0, duration=10.0)

ann_trim = ann.trim(0, 8, strict=False)
ann_trim = ann.trim(1, 8, strict=False)

assert ann_trim.time == 5
assert ann_trim.duration == 3
assert ann_trim.sandbox.trim == [{'start_time': 0, 'end_time': 8,
assert ann_trim.sandbox.trim == [{'start_time': 1, 'end_time': 8,
'trim_start': 5, 'trim_end': 8}]
assert ann_trim.namespace == ann.namespace
assert ann_trim.annotation_metadata == ann.annotation_metadata

expected_data = dict(time=[5.0, 5.0],
duration=[2.0, 3.0],
value=['one', 'two'],
confidence=[0.9, 0.9])
expected_data = dict(time=[5.0, 5.0, 5.0],
duration=[0.0, 2.0, 3.0],
value=['zero', 'one', 'two'],
confidence=[0.1, 0.9, 0.9])
expected_ann = jams.Annotation(namespace, data=expected_data, time=5.0,
duration=3.0)

assert ann_trim.data == expected_ann.data

# strict=True
ann_trim = ann.trim(0, 8, strict=True)
ann_trim = ann.trim(1, 8, strict=True)

assert ann_trim.time == 5
assert ann_trim.duration == 3
assert ann_trim.sandbox.trim == [{'start_time': 0, 'end_time': 8,
assert ann_trim.sandbox.trim == [{'start_time': 1, 'end_time': 8,
'trim_start': 5, 'trim_end': 8}]
assert ann_trim.namespace == ann.namespace
assert ann_trim.annotation_metadata == ann.annotation_metadata

expected_data = dict(time=[5.0],
duration=[2.0],
value=['one'],
confidence=[0.9])
expected_data = dict(time=[5.0, 5.0],
duration=[0.0, 2.0],
value=['zero', 'one'],
confidence=[0.1, 0.9])
expected_ann = jams.Annotation(namespace, data=expected_data, time=5.0,
duration=3.0)

Expand Down

0 comments on commit 255a5ee

Please sign in to comment.