"""Consolidators for features extracted from media files""" from abc import ABC class Consolidator(ABC): """Consolidator interface. A Consolidator's purpose is to reduce a list of features based on eg adjacency/overlap in time. Illustration ============ feature1: <----------> feature2: <------------> consolidated: <-----------------> TODO: consider how to ensure we only try to merge features from the same path!! #important """ def __init__(self, features=None): if features is None or len(features) == 0: raise ValueError("Features must be provided") # TODO: #API -- decide if this is necessary # maybe we want to permit [] which would 'consolidate' to [] self.features = features def consolidate(self): """Consolidate features by some criterion/criteria (eg overlap, adjacency)""" class OverlapConsolidator(Consolidator): """Consolidator that merges overlapping features. An overlap is defined as two features that share a common interval of time,ie: interval1.end < interval2.start or interval2.start < interval1.end """ def consolidate(self): """Consolidate overlapping features""" # sort features by start time self.features.sort(key=lambda x: x.interval.start) # merge overlapping features # TODO: check my working here (or write tests...) consolidated = [] current = self.features[0] for feature in self.features[1:]: if current.interval.end < feature.interval.start: # no overlap consolidated.append(current) current = feature else: # overlap current.interval.end = max(current.interval.end, feature.interval.end) consolidated.append(current) self.features = consolidated