audiomate.annotations¶
This module contains classes to describe the content of an audio-segment.
Label¶
-
class
audiomate.annotations.
Label
(value, start=0, end=inf, meta=None)[source]¶ Represents a label that describes some part of an utterance.
Parameters: - value (str) – The text of the label.
- start (float) – Start of the label within the utterance in seconds. (default: 0)
- end (float) – End of the label within the utterance in seconds. (default: inf) (inf defines the end of the utterance)
- meta (dict) – A dictionary containing additional information for the label.
Variables: label_list (LabelList) – The label-list this label is belonging to.
-
do_overlap
(other_label, adjacent=True)[source]¶ Determine whether
other_label
overlaps with this label. Ifadjacent==True
, adjacent labels are also considered as overlapping.Parameters: - other_label (Label) – Another label.
- adjacent (bool) – If
True
, adjacent labels are considered as overlapping.
Returns: True
if the two labels overlap,False
otherwise.Return type: bool
-
duration
¶ Return the duration of the label in seconds.
-
end_abs
¶ Return the absolute end of the label in seconds relative to the signal. If the label isn’t linked to any utterance via label-list, it is assumed
self.end
is relative to the start of the signal, henceself.end
==self.end_abs
.
-
length
¶ Return the length of the label (Number of characters).
-
overlap_duration
(other_label)[source]¶ Return the duration of the overlapping part between this label and
other_label
.Parameters: other_label (Label) – Another label to check. Returns: The duration of overlap in seconds. Return type: float Example
>>> label_a = Label('a', 3.4, 5.6) >>> label_b = Label('b', 4.8, 6.2) >>> label_a.overlap_duration(label_b) 0.8
-
read_samples
(sr=None)[source]¶ Read the samples of the utterance.
Parameters: sr (int) – If None uses the sampling rate given by the track, otherwise resamples to the given sampling rate. Returns: A numpy array containing the samples as a floating point (numpy.float32) time series. Return type: np.ndarray
-
start_abs
¶ Return the absolute start of the label in seconds relative to the signal. If the label isn’t linked to any utterance via label-list, it is assumed
self.start
is relative to the start of the signal, henceself.start
==self.start_abs
.
-
tokenized
(delimiter=' ')[source]¶ Return a list with tokens from the value of the label. Tokens are extracted by splitting the string using
delimiter
and then trimming any whitespace before and after splitted strings.Parameters: delimiter (str) – The delimiter used to split into tokens. (default: space) Returns: A list of tokens in the order they occur in the label. Return type: list Examples
>>> label = Label('as is oh') >>> label.tokenized() ['as', 'is', 'oh']
Using a different delimiter (whitespace is trimmed anyway):
>>> label = Label('oh hi, as, is ') >>> label.tokenized(delimiter=',') ['oh hi', 'as', 'is']
LabelList¶
-
class
audiomate.annotations.
LabelList
(idx='default', labels=None)[source]¶ Represents a list of labels which describe an utterance. An utterance can have multiple label-lists.
Parameters: - idx (str) – An unique identifier for the label-list within a corpus for one utterance.
- labels (list) – The list containing the
audiomate.annotations.Label
.
Variables: - utterance (Utterance) – The utterance this label-list is belonging to.
- label_tree (IntervalTree) – The interval-tree storing the labels.
Example
>>> label_list = LabelList(idx='transcription', labels=[ >>> Label('this', 0, 2), >>> Label('is', 2, 4), >>> Label('timmy', 4, 8) >>> ])
-
add
(label)[source]¶ Add a label to the end of the list.
Parameters: label (Label) – The label to add.
-
all_tokens
(delimiter=' ')[source]¶ Return a list of all tokens occurring in the label-list.
Parameters: delimiter (str) – The delimiter used to split labels into tokens. See audiomate.annotations.Label.tokenized()
Returns: A set of distinct tokens. Return type: set
-
apply
(fn)[source]¶ Apply the given function fn to every label in this label list. fn is a function of one argument that receives the current label which can then be edited in place.
Parameters: fn (func) – Function to apply to every label Example
>>> ll = LabelList(labels=[ ... Label('a_label', 1.0, 2.0), ... Label('another_label', 2.0, 3.0) ... ]) >>> def shift_labels(label): ... label.start += 1.0 ... label.end += 1.0 ... >>> ll.apply(shift_labels) >>> ll.labels [Label(a_label, 2.0, 3.0), Label(another_label, 3.0, 4.0)]
-
classmethod
create_single
(value, idx='default')[source]¶ Create a label-list with a single label containing the given value.
-
end
¶ Return end of the lastly ending label (upper bound).
-
join
(delimiter=' ', overlap_threshold=0.1)[source]¶ Return a string with all labels concatenated together. The order of the labels is defined by the start of the label. If the overlapping between two labels is greater than
overlap_threshold
, an Exception is thrown.Parameters: - delimiter (str) – A string to join two consecutive labels.
- overlap_threshold (float) – Maximum overlap between two consecutive labels.
Returns: A string with all labels concatenated together.
Return type: str
Example
>>> ll = LabelList(idx='some', labels=[ >>> Label('a', start=0, end=4), >>> Label('b', start=3.95, end=6.0), >>> Label('c', start=7.0, end=10.2), >>> Label('d', start=10.3, end=14.0) >>> ]) >>> ll.join(' - ') 'a - b - c - d'
-
label_count
()[source]¶ Return for each label the number of occurrences within the list.
Returns: A dictionary containing for every label-value (key) the number of occurrences (value). Return type: dict Example
>>> ll = LabelList(labels=[ >>> Label('a', 3.2, 4.5), >>> Label('b', 5.1, 8.9), >>> Label('a', 7.2, 10.5), >>> Label('b', 10.5, 14), >>> Label('a', 15, 18) >>> ]) >>> ll.label_count() {'a': 3 'b': 2}
-
label_total_duration
()[source]¶ Return for each distinct label value the total duration of all occurrences.
Returns: - A dictionary containing for every label-value (key)
- the total duration in seconds (value).
Return type: dict Example
>>> ll = LabelList(labels=[ >>> Label('a', 3, 5), >>> Label('b', 5, 8), >>> Label('a', 8, 10), >>> Label('b', 10, 14), >>> Label('a', 15, 18.5) >>> ]) >>> ll.label_total_duration() {'a': 7.5 'b': 7.0}
-
label_values
()[source]¶ Return a list of all occuring label values.
Returns: Lexicographically sorted list (str) of label values. Return type: list Example
>>> ll = LabelList(labels=[ >>> Label('a', 3.2, 4.5), >>> Label('b', 5.1, 8.9), >>> Label('c', 7.2, 10.5), >>> Label('d', 10.5, 14), >>> Label('d', 15, 18) >>> ]) >>> ll.label_values() ['a', 'b', 'c', 'd']
-
labels
¶ Return list of labels.
-
labels_in_range
(start, end, fully_included=False)[source]¶ Return a list of labels, that are within the given range. Also labels that only overlap are included.
Parameters: - start (float) – Start-time in seconds.
- end (float) – End-time in seconds.
- fully_included (bool) – If
True
, only labels fully included in the range are returned. Otherwise also overlapping ones are returned. (defaultFalse
)
Returns: List of labels in the range.
Return type: list
Example
>>> ll = LabelList(labels=[ >>> Label('a', 3.2, 4.5), >>> Label('b', 5.1, 8.9), >>> Label('c', 7.2, 10.5), >>> Label('d', 10.5, 14) >>>]) >>> ll.labels_in_range(6.2, 10.1) [Label('b', 5.1, 8.9), Label('c', 7.2, 10.5)]
-
merge_overlaps
(threshold=0.0)[source]¶ Merge overlapping labels with the same value. Two labels are considered overlapping, if
l2.start - l1.end < threshold
.Parameters: threshold (float) – Maximal distance between two labels to be considered as overlapping. (default: 0.0) Example
>>> ll = LabelList(labels=[ ... Label('a_label', 1.0, 2.0), ... Label('a_label', 1.5, 2.7), ... Label('b_label', 1.0, 2.0), ... ]) >>> ll.merge_overlapping_labels() >>> ll.labels [ Label('a_label', 1.0, 2.7), Label('b_label', 1.0, 2.0), ]
-
ranges
(yield_ranges_without_labels=False, include_labels=None)[source]¶ Generate all ranges of the label-list. A range is defined as a part of the label-list for which the same labels are defined.
Parameters: - yield_ranges_without_labels (bool) – If True also yields ranges for which no labels are defined.
- include_labels (list) – If not empty, only the label values in the list will be considered.
Returns: A generator which yields one range (tuple start/end/list-of-labels) at a time.
Return type: generator
Example
>>> ll = LabelList(labels=[ >>> Label('a', 3.2, 4.5), >>> Label('b', 5.1, 8.9), >>> Label('c', 7.2, 10.5), >>> Label('d', 10.5, 14) >>>]) >>> ranges = ll.ranges() >>> next(ranges) (3.2, 4.5, [ < audiomate.annotations.Label at 0x1090527c8 > ]) >>> next(ranges) (4.5, 5.1, []) >>> next(ranges) (5.1, 7.2, [ < audiomate.annotations.label.Label at 0x1090484c8 > ])
-
separated
()[source]¶ Create a separate Label-List for every distinct label-value.
Returns: - A dictionary with distinct label-values as keys. Every value
- is a LabelList containing only labels with the same value.
Return type: dict Example
>>> ll = LabelList(idx='some', labels=[ >>> Label('a', start=0, end=4), >>> Label('b', start=3.95, end=6.0), >>> Label('a', start=7.0, end=10.2), >>> Label('b', start=10.3, end=14.0) >>> ]) >>> s = ll.separate() >>> s['a'].labels [Label('a', start=0, end=4), Label('a', start=7.0, end=10.2)] >>> s['b'].labels [Label('b', start=3.95, end=6.0), Label('b', start=10.3, end=14.0)]
-
split
(cutting_points, shift_times=False, overlap=0.0)[source]¶ Split the label-list into x parts and return them as new label-lists. x is defined by the number of cutting-points (
x == len(cutting_points) + 1
).The result is a list of label-lists corresponding to each part. Label-list 0 contains labels between
0
andcutting_points[0]
. Label-list 1 contains labels betweencutting_points[0]
andcutting_points[1]
. And so on.Parameters: - cutting_points (list) – List of floats defining the points in seconds, where the label-list is splitted.
- shift_times (bool) – If True, start and end-time are shifted in splitted label-lists. So the start is relative to the cutting point and not to the beginning of the original label-list.
- overlap (float) – Amount of overlap in seconds. This amount is subtracted from a start-cutting-point, and added to a end-cutting-point.
Returns: A list of of: class: audiomate.annotations.LabelList.
Return type: list
Example
>>> ll = LabelList(labels=[ >>> Label('a', 0, 5), >>> Label('b', 5, 10), >>> Label('c', 11, 15), >>>]) >>> >>> res = ll.split([4.1, 8.9, 12.0]) >>> len(res) 4 >>> res[0].labels [Label('a', 0.0, 4.1)] >>> res[1].labels [ Label('a', 4.1, 5.0), Label('b', 5.0, 8.9) ] >>> res[2].labels [ Label('b', 8.9, 10.0), Label('c', 11.0, 12.0) ] >>> res[3].labels [Label('c', 12.0, 15.0)]
If
shift_times = True
, the times are adjusted to be relative to the cutting-points for every label-list but the first.>>> ll = LabelList(labels=[ >>> Label('a', 0, 5), >>> Label('b', 5, 10), >>>]) >>> >>> res = ll.split([4.6]) >>> len(res) 4 >>> res[0].labels [Label('a', 0.0, 4.6)] >>> res[1].labels [ Label('a', 0.0, 0.4), Label('b', 0.4, 5.4) ]
-
start
¶ Return start of the earliest starting label (lower bound).
-
tokenized
(delimiter=' ', overlap_threshold=0.1)[source]¶ Return a ordered list of tokens based on all labels. Joins all token from all labels (
label.tokenized()`
). If the overlapping between two labels is greater thanoverlap_threshold
, an Exception is thrown.Parameters: - delimiter (str) – The delimiter used to split labels into tokens. (default: space)
- overlap_threshold (float) – Maximum overlap between two consecutive labels.
Returns: - A list containing tokens of all labels ordered according
to the label order.
Return type: str
Example
>>> ll = LabelList(idx='some', labels=[ >>> Label('a d q', start=0, end=4), >>> Label('b', start=3.95, end=6.0), >>> Label('c a', start=7.0, end=10.2), >>> Label('f g', start=10.3, end=14.0) >>> ]) >>> ll.tokenized(delimiter=' ', overlap_threshold=0.1) ['a', 'd', 'q', 'b', 'c', 'a', 'f', 'g']
-
total_length
¶ Return the cumulative length of all labels (Number of characters).
-
update
(labels)[source]¶ Add a list of labels to the end of the list.
Parameters: labels (list) – Labels to add.
-
classmethod
with_label_values
(values, idx='default')[source]¶ Create a new label-list containing labels with the given values. All labels will have default start/end values of 0 and
inf
.Parameters: - values (list) – List of values(str) that should be created and appended to the label-list.
- idx (str) – The idx of the label-list.
Returns: New label-list.
Return type: Example
>>> ll = LabelList.with_label_values(['a', 'x', 'z'], idx='letters') >>> ll.idx 'letters' >>> ll.labels [ Label('a', 0, inf), Label('x', 0, inf), Label('z', 0, inf), ]
Relabeling¶
-
audiomate.annotations.relabeling.
find_missing_projections
(label_list, projections)[source]¶ Finds all combinations of labels in label_list that are not covered by an entry in the dictionary of projections. Returns a list containing tuples of uncovered label combinations or en empty list if there are none. All uncovered label combinations are naturally sorted.
Each entry in the dictionary of projections represents a single projection that maps a combination of labels (key) to a single new label (value). The combination of labels to be mapped is a tuple of naturally sorted labels that apply to one or more segments simultaneously. By defining a special wildcard projection using (‘**’,) is is not required to specify a projection for every single combination of labels.
Parameters: - label_list (audiomate.annotations.LabelList) – The label list to relabel
- projections (dict) – A dictionary that maps tuples of label combinations to string labels.
Returns: List of combinations of labels that are not covered by any projection
Return type: List
Example
>>> ll = annotations.LabelList(labels=[ ... annotations.Label('b', 3.2, 4.5), ... annotations.Label('a', 4.0, 4.9), ... annotations.Label('c', 4.2, 5.1) ... ]) >>> find_missing_projections(ll, {('b',): 'new_label'}) [('a', 'b'), ('a', 'b', 'c'), ('a', 'c'), ('c',)]
-
audiomate.annotations.relabeling.
load_projections
(projections_file)[source]¶ Loads projections defined in the given projections_file.
The projections_file is expected to be in the following format:
old_label_1 | new_label_1 old_label_1 old_label_2 | new_label_2 old_label_3 |
You can define one projection per line. Each projection starts with a list of one or multiple old labels (separated by a single whitespace) that are separated from the new label by a pipe (|). In the code above, the segment labeled with old_label_1 will be labeled with new_label_1 after applying the projection. Segments that are labeled with old_label_1 and old_label_2 concurrently are relabeled to new_label_2. All segments labeled with old_label_3 are dropped. Combinations of multiple labels are automatically sorted in natural order.
Parameters: projections_file (str) – Path to the file with projections Returns: Dictionary where the keys are tuples of labels to project to the key’s value Return type: dict Example
>>> load_projections('/path/to/projections.txt') {('b',): 'foo', ('a', 'b'): 'a_b', ('a',): 'bar'}
-
audiomate.annotations.relabeling.
relabel
(label_list, projections)[source]¶ Relabel an entire
LabelList
using user-defined projections. Labels can be renamed, removed or overlapping labels can be flattened to a single label per segment.Each entry in the dictionary of projections represents a single projection that maps a combination of labels (key) to a single new label (value). The combination of labels to be mapped is a tuple of naturally sorted labels that apply to one or more segments simultaneously. By defining a special wildcard projection using (‘**’,) is is not required to specify a projection for every single combination of labels.
This method raises a
UnmappedLabelsException
if a projection for one or more combinations of labels is not defined.Parameters: - label_list (audiomate.annotations.LabelList) – The label list to relabel
- projections (dict) – A dictionary that maps tuples of label combinations to string labels.
Returns: New label list with remapped labels
Return type: Raises: UnmappedLabelsException
– If a projection for one or more combinations of labels is not defined.Example
>>> projections = { ... ('a',): 'a', ... ('b',): 'b', ... ('c',): 'c', ... ('a', 'b',): 'a_b', ... ('a', 'b', 'c',): 'a_b_c', ... ('**',): 'b_c', ... } >>> label_list = annotations.LabelList(labels=[ ... annotations.Label('a', 3.2, 4.5), ... annotations.Label('b', 4.0, 4.9), ... annotations.Label('c', 4.2, 5.1) ... ]) >>> ll = relabel(label_list, projections) >>> [l.value for l in ll] ['a', 'a_b', 'a_b_c', 'b_c', 'c']