praatio.data_classes.textgrid_tier API documentation

# praatio.data_classes.textgrid_tier

The abstract class used by all textgrid tiers

View Source

      1"""
      2The abstract class used by all textgrid tiers
      3"""
      4import re
      5import copy
      6import math
      7from typing import (
      8    List,
      9    Optional,
     10    Type,
     11    TypeVar,
     12    Union,
     13)
     14from abc import ABC, abstractmethod
     15
     16from typing_extensions import Literal
     17
     18
     19from praatio.utilities import constants
     20from praatio.utilities import errors
     21from praatio.utilities import utils
     22
     23T = TypeVar("T", bound="TextgridTier")
     24
     25
     26class TextgridTier(ABC):
     27    tierType: str
     28    entryType: Union[Type[constants.Point], Type[constants.Interval]]
     29
     30    def __init__(
     31        self,
     32        name: str,
     33        entries: List,
     34        minT: float,
     35        maxT: float,
     36        errorMode: Literal["silence", "warning", "error"] = "warning",
     37    ):
     38        "A container that stores and operates over interval and point tiers"
     39        utils.validateOption("errorMode", errorMode, constants.ErrorReportingMode)
     40
     41        """See PointTier or IntervalTier"""
     42        entries.sort()
     43
     44        self.name = name
     45        self._entries = entries
     46        self.minTimestamp = minT
     47        self.maxTimestamp = maxT
     48        self.errorReporter = utils.getErrorReporter(errorMode)
     49
     50    def __len__(self):
     51        return len(self._entries)
     52
     53    def __iter__(self):
     54        for entry in self.entries:
     55            yield entry
     56
     57    def __eq__(self, other):
     58        if not isinstance(self, type(other)):
     59            return False
     60
     61        isEqual = True
     62        isEqual &= self.name == other.name
     63        isEqual &= math.isclose(self.minTimestamp, other.minTimestamp)
     64        isEqual &= math.isclose(self.maxTimestamp, other.maxTimestamp)
     65        isEqual &= len(self.entries) == len(other.entries)
     66
     67        # TODO: Intervals and Points now use isclose, so we can simplify this
     68        #       logic (selfEntry == otherEntry); however, this will break
     69        #       things for klattgrids
     70        if isEqual:
     71            for selfEntry, otherEntry in zip(self.entries, other.entries):
     72                for selfSubEntry, otherSubEntry in zip(selfEntry, otherEntry):
     73                    try:
     74                        isEqual &= math.isclose(selfSubEntry, otherSubEntry)
     75                    except TypeError:
     76                        isEqual &= selfSubEntry == otherSubEntry
     77
     78        return isEqual
     79
     80    @property
     81    def entries(self):
     82        return tuple(self._entries)
     83
     84    @property
     85    @abstractmethod
     86    def timestamps(self) -> List[float]:
     87        pass
     88
     89    def appendTier(self, tier: "TextgridTier") -> "TextgridTier":
     90        """Append a tier to the end of this one.
     91
     92        This tier's maxtimestamp will be lengthened by the amount in the passed in tier.
     93        """
     94        if self.tierType != tier.tierType:
     95            raise errors.ArgumentError(
     96                f"Cannot append a tier of type {type(self)} to a tier of type {type(tier)}."
     97            )
     98
     99        maxTime = self.maxTimestamp + tier.maxTimestamp
    100
    101        # We're increasing the size of the tier, so of course its intervals
    102        # may exceed the bounds of the tier's maxTimestamp, triggering
    103        # errors/warnings--we can ignore those
    104        appendTier = tier.editTimestamps(
    105            self.maxTimestamp, constants.ErrorReportingMode.SILENCE
    106        )
    107
    108        entries = self._entries + appendTier._entries
    109        entries.sort()
    110
    111        return self.new(
    112            self.name, entries, minTimestamp=self.minTimestamp, maxTimestamp=maxTime
    113        )
    114
    115    def find(
    116        self,
    117        matchLabel: str,
    118        substrMatchFlag: bool = False,
    119        usingRE: bool = False,
    120    ) -> List[int]:
    121        """Returns the index of all intervals that match the given label
    122
    123        Args:
    124            matchLabel: the label to search for
    125            substrMatchFlag: if True, match any label containing matchLabel.
    126                if False, label must be the same as matchLabel.
    127            usingRE: if True, matchLabel is interpreted as a regular expression
    128
    129        Returns:
    130            A list of indicies
    131        """
    132        returnList = []
    133        if usingRE is True:
    134            for i, entry in enumerate(self.entries):
    135                matchList = re.findall(matchLabel, entry.label, re.I)
    136                if matchList != []:
    137                    returnList.append(i)
    138        else:
    139            for i, entry in enumerate(self.entries):
    140                if not substrMatchFlag:
    141                    if entry.label == matchLabel:
    142                        returnList.append(i)
    143                else:
    144                    if matchLabel in entry.label:
    145                        returnList.append(i)
    146
    147        return returnList
    148
    149    def new(
    150        self: T,
    151        name: Optional[str] = None,
    152        entries: Optional[list] = None,
    153        minTimestamp: Optional[float] = None,
    154        maxTimestamp: Optional[float] = None,
    155    ) -> T:
    156        """Make a new tier derived from the current one"""
    157        if name is None:
    158            name = self.name
    159        if entries is None:
    160            entries = copy.deepcopy(self.entries)
    161            entries = [
    162                self.entryType(*entry)
    163                if isinstance(entry, tuple) or isinstance(entry, list)
    164                else entry
    165                for entry in entries
    166            ]
    167        if minTimestamp is None:
    168            minTimestamp = self.minTimestamp
    169        if maxTimestamp is None:
    170            maxTimestamp = self.maxTimestamp
    171        return type(self)(name, entries, minTimestamp, maxTimestamp)
    172
    173    def sort(self) -> None:
    174        """Sorts the entries in the list of entries"""
    175        # A list containing tuples and lists will be sorted with tuples
    176        # first and then lists.  To correctly sort, we need to make
    177        # sure that all data structures inside the entry list are
    178        # of the same data type.  The entry list is sorted whenever
    179        # the entry list is modified, so this is probably the best
    180        # place to enforce the data type
    181        self._entries = [
    182            entry if isinstance(entry, self.entryType) else self.entryType(*entry)
    183            for entry in self.entries
    184        ]
    185        self._entries.sort()
    186
    187    def union(self, tier: "TextgridTier") -> "TextgridTier":
    188        """The given tier is set unioned to this tier.
    189
    190        All entries in the given tier are added to the current tier.
    191        Overlapping entries are merged.
    192        """
    193        retTier = self.new()
    194
    195        for entry in tier.entries:
    196            retTier.insertEntry(
    197                entry,
    198                collisionMode=constants.IntervalCollision.MERGE,
    199                collisionReportingMode=constants.ErrorReportingMode.SILENCE,
    200            )
    201
    202        retTier.sort()
    203
    204        return retTier
    205
    206    @abstractmethod
    207    def editTimestamps(
    208        self,
    209        offset: float,
    210        reportingMode: Literal["silence", "warning", "error"] = "warning",
    211    ) -> "TextgridTier":  # pragma: no cover
    212        pass
    213
    214    @abstractmethod
    215    def insertEntry(
    216        self,
    217        entry,
    218        collisionMode: Literal["replace", "merge", "error"] = "error",
    219        collisionReportingMode: Literal["silence", "warning"] = "warning",
    220    ) -> None:  # pragma: no cover
    221        pass
    222
    223    @abstractmethod
    224    def dejitter(
    225        self,
    226        referenceTier: "TextgridTier",
    227        maxDifference: float = 0.001,
    228    ) -> "TextgridTier":  # pragma: no cover
    229        pass
    230
    231    @abstractmethod
    232    def eraseRegion(
    233        self,
    234        start: float,
    235        end: float,
    236        collisionMode: Literal["truncate", "categorical", "error"] = "error",
    237        doShrink: bool = True,
    238    ) -> "TextgridTier":  # pragma: no cover
    239        pass
    240
    241    @abstractmethod
    242    def crop(
    243        self,
    244        cropStart: float,
    245        cropEnd: float,
    246        mode: Literal["strict", "lax", "truncated"],
    247        rebaseToZero: bool,
    248    ) -> "TextgridTier":  # pragma: no cover
    249        pass
    250
    251    @abstractmethod
    252    def insertSpace(
    253        self,
    254        start: float,
    255        duration: float,
    256        collisionMode: Literal["stretch", "split", "no_change", "error"],
    257    ) -> "TextgridTier":  # pragma: no cover
    258        pass
    259
    260    @abstractmethod
    261    def deleteEntry(self, entry) -> None:  # pragma: no cover
    262        pass
    263
    264    @abstractmethod
    265    def validate(self, reportingMode) -> bool:  # pragma: no cover
    266        pass

class TextgridTier(abc.ABC): View Source

     27class TextgridTier(ABC):
     28    tierType: str
     29    entryType: Union[Type[constants.Point], Type[constants.Interval]]
     30
     31    def __init__(
     32        self,
     33        name: str,
     34        entries: List,
     35        minT: float,
     36        maxT: float,
     37        errorMode: Literal["silence", "warning", "error"] = "warning",
     38    ):
     39        "A container that stores and operates over interval and point tiers"
     40        utils.validateOption("errorMode", errorMode, constants.ErrorReportingMode)
     41
     42        """See PointTier or IntervalTier"""
     43        entries.sort()
     44
     45        self.name = name
     46        self._entries = entries
     47        self.minTimestamp = minT
     48        self.maxTimestamp = maxT
     49        self.errorReporter = utils.getErrorReporter(errorMode)
     50
     51    def __len__(self):
     52        return len(self._entries)
     53
     54    def __iter__(self):
     55        for entry in self.entries:
     56            yield entry
     57
     58    def __eq__(self, other):
     59        if not isinstance(self, type(other)):
     60            return False
     61
     62        isEqual = True
     63        isEqual &= self.name == other.name
     64        isEqual &= math.isclose(self.minTimestamp, other.minTimestamp)
     65        isEqual &= math.isclose(self.maxTimestamp, other.maxTimestamp)
     66        isEqual &= len(self.entries) == len(other.entries)
     67
     68        # TODO: Intervals and Points now use isclose, so we can simplify this
     69        #       logic (selfEntry == otherEntry); however, this will break
     70        #       things for klattgrids
     71        if isEqual:
     72            for selfEntry, otherEntry in zip(self.entries, other.entries):
     73                for selfSubEntry, otherSubEntry in zip(selfEntry, otherEntry):
     74                    try:
     75                        isEqual &= math.isclose(selfSubEntry, otherSubEntry)
     76                    except TypeError:
     77                        isEqual &= selfSubEntry == otherSubEntry
     78
     79        return isEqual
     80
     81    @property
     82    def entries(self):
     83        return tuple(self._entries)
     84
     85    @property
     86    @abstractmethod
     87    def timestamps(self) -> List[float]:
     88        pass
     89
     90    def appendTier(self, tier: "TextgridTier") -> "TextgridTier":
     91        """Append a tier to the end of this one.
     92
     93        This tier's maxtimestamp will be lengthened by the amount in the passed in tier.
     94        """
     95        if self.tierType != tier.tierType:
     96            raise errors.ArgumentError(
     97                f"Cannot append a tier of type {type(self)} to a tier of type {type(tier)}."
     98            )
     99
    100        maxTime = self.maxTimestamp + tier.maxTimestamp
    101
    102        # We're increasing the size of the tier, so of course its intervals
    103        # may exceed the bounds of the tier's maxTimestamp, triggering
    104        # errors/warnings--we can ignore those
    105        appendTier = tier.editTimestamps(
    106            self.maxTimestamp, constants.ErrorReportingMode.SILENCE
    107        )
    108
    109        entries = self._entries + appendTier._entries
    110        entries.sort()
    111
    112        return self.new(
    113            self.name, entries, minTimestamp=self.minTimestamp, maxTimestamp=maxTime
    114        )
    115
    116    def find(
    117        self,
    118        matchLabel: str,
    119        substrMatchFlag: bool = False,
    120        usingRE: bool = False,
    121    ) -> List[int]:
    122        """Returns the index of all intervals that match the given label
    123
    124        Args:
    125            matchLabel: the label to search for
    126            substrMatchFlag: if True, match any label containing matchLabel.
    127                if False, label must be the same as matchLabel.
    128            usingRE: if True, matchLabel is interpreted as a regular expression
    129
    130        Returns:
    131            A list of indicies
    132        """
    133        returnList = []
    134        if usingRE is True:
    135            for i, entry in enumerate(self.entries):
    136                matchList = re.findall(matchLabel, entry.label, re.I)
    137                if matchList != []:
    138                    returnList.append(i)
    139        else:
    140            for i, entry in enumerate(self.entries):
    141                if not substrMatchFlag:
    142                    if entry.label == matchLabel:
    143                        returnList.append(i)
    144                else:
    145                    if matchLabel in entry.label:
    146                        returnList.append(i)
    147
    148        return returnList
    149
    150    def new(
    151        self: T,
    152        name: Optional[str] = None,
    153        entries: Optional[list] = None,
    154        minTimestamp: Optional[float] = None,
    155        maxTimestamp: Optional[float] = None,
    156    ) -> T:
    157        """Make a new tier derived from the current one"""
    158        if name is None:
    159            name = self.name
    160        if entries is None:
    161            entries = copy.deepcopy(self.entries)
    162            entries = [
    163                self.entryType(*entry)
    164                if isinstance(entry, tuple) or isinstance(entry, list)
    165                else entry
    166                for entry in entries
    167            ]
    168        if minTimestamp is None:
    169            minTimestamp = self.minTimestamp
    170        if maxTimestamp is None:
    171            maxTimestamp = self.maxTimestamp
    172        return type(self)(name, entries, minTimestamp, maxTimestamp)
    173
    174    def sort(self) -> None:
    175        """Sorts the entries in the list of entries"""
    176        # A list containing tuples and lists will be sorted with tuples
    177        # first and then lists.  To correctly sort, we need to make
    178        # sure that all data structures inside the entry list are
    179        # of the same data type.  The entry list is sorted whenever
    180        # the entry list is modified, so this is probably the best
    181        # place to enforce the data type
    182        self._entries = [
    183            entry if isinstance(entry, self.entryType) else self.entryType(*entry)
    184            for entry in self.entries
    185        ]
    186        self._entries.sort()
    187
    188    def union(self, tier: "TextgridTier") -> "TextgridTier":
    189        """The given tier is set unioned to this tier.
    190
    191        All entries in the given tier are added to the current tier.
    192        Overlapping entries are merged.
    193        """
    194        retTier = self.new()
    195
    196        for entry in tier.entries:
    197            retTier.insertEntry(
    198                entry,
    199                collisionMode=constants.IntervalCollision.MERGE,
    200                collisionReportingMode=constants.ErrorReportingMode.SILENCE,
    201            )
    202
    203        retTier.sort()
    204
    205        return retTier
    206
    207    @abstractmethod
    208    def editTimestamps(
    209        self,
    210        offset: float,
    211        reportingMode: Literal["silence", "warning", "error"] = "warning",
    212    ) -> "TextgridTier":  # pragma: no cover
    213        pass
    214
    215    @abstractmethod
    216    def insertEntry(
    217        self,
    218        entry,
    219        collisionMode: Literal["replace", "merge", "error"] = "error",
    220        collisionReportingMode: Literal["silence", "warning"] = "warning",
    221    ) -> None:  # pragma: no cover
    222        pass
    223
    224    @abstractmethod
    225    def dejitter(
    226        self,
    227        referenceTier: "TextgridTier",
    228        maxDifference: float = 0.001,
    229    ) -> "TextgridTier":  # pragma: no cover
    230        pass
    231
    232    @abstractmethod
    233    def eraseRegion(
    234        self,
    235        start: float,
    236        end: float,
    237        collisionMode: Literal["truncate", "categorical", "error"] = "error",
    238        doShrink: bool = True,
    239    ) -> "TextgridTier":  # pragma: no cover
    240        pass
    241
    242    @abstractmethod
    243    def crop(
    244        self,
    245        cropStart: float,
    246        cropEnd: float,
    247        mode: Literal["strict", "lax", "truncated"],
    248        rebaseToZero: bool,
    249    ) -> "TextgridTier":  # pragma: no cover
    250        pass
    251
    252    @abstractmethod
    253    def insertSpace(
    254        self,
    255        start: float,
    256        duration: float,
    257        collisionMode: Literal["stretch", "split", "no_change", "error"],
    258    ) -> "TextgridTier":  # pragma: no cover
    259        pass
    260
    261    @abstractmethod
    262    def deleteEntry(self, entry) -> None:  # pragma: no cover
    263        pass
    264
    265    @abstractmethod
    266    def validate(self, reportingMode) -> bool:  # pragma: no cover
    267        pass

Helper class that provides a standard way to create an ABC using inheritance.

TextgridTier( name: str, entries: List, minT: float, maxT: float, errorMode: Literal['silence', 'warning', 'error'] = 'warning') View Source

    31    def __init__(
    32        self,
    33        name: str,
    34        entries: List,
    35        minT: float,
    36        maxT: float,
    37        errorMode: Literal["silence", "warning", "error"] = "warning",
    38    ):
    39        "A container that stores and operates over interval and point tiers"
    40        utils.validateOption("errorMode", errorMode, constants.ErrorReportingMode)
    41
    42        """See PointTier or IntervalTier"""
    43        entries.sort()
    44
    45        self.name = name
    46        self._entries = entries
    47        self.minTimestamp = minT
    48        self.maxTimestamp = maxT
    49        self.errorReporter = utils.getErrorReporter(errorMode)

A container that stores and operates over interval and point tiers

tierType: str
entryType: Union[Type[praatio.utilities.constants.Point], Type[praatio.utilities.constants.Interval]]
name
minTimestamp
maxTimestamp
errorReporter
entries
timestamps: List[float]
def appendTier( self, tier: TextgridTier) -> TextgridTier: View Source

     90    def appendTier(self, tier: "TextgridTier") -> "TextgridTier":
     91        """Append a tier to the end of this one.
     92
     93        This tier's maxtimestamp will be lengthened by the amount in the passed in tier.
     94        """
     95        if self.tierType != tier.tierType:
     96            raise errors.ArgumentError(
     97                f"Cannot append a tier of type {type(self)} to a tier of type {type(tier)}."
     98            )
     99
    100        maxTime = self.maxTimestamp + tier.maxTimestamp
    101
    102        # We're increasing the size of the tier, so of course its intervals
    103        # may exceed the bounds of the tier's maxTimestamp, triggering
    104        # errors/warnings--we can ignore those
    105        appendTier = tier.editTimestamps(
    106            self.maxTimestamp, constants.ErrorReportingMode.SILENCE
    107        )
    108
    109        entries = self._entries + appendTier._entries
    110        entries.sort()
    111
    112        return self.new(
    113            self.name, entries, minTimestamp=self.minTimestamp, maxTimestamp=maxTime
    114        )

Append a tier to the end of this one.

This tier's maxtimestamp will be lengthened by the amount in the passed in tier.

def find( self, matchLabel: str, substrMatchFlag: bool = False, usingRE: bool = False) -> List[int]: View Source

    116    def find(
    117        self,
    118        matchLabel: str,
    119        substrMatchFlag: bool = False,
    120        usingRE: bool = False,
    121    ) -> List[int]:
    122        """Returns the index of all intervals that match the given label
    123
    124        Args:
    125            matchLabel: the label to search for
    126            substrMatchFlag: if True, match any label containing matchLabel.
    127                if False, label must be the same as matchLabel.
    128            usingRE: if True, matchLabel is interpreted as a regular expression
    129
    130        Returns:
    131            A list of indicies
    132        """
    133        returnList = []
    134        if usingRE is True:
    135            for i, entry in enumerate(self.entries):
    136                matchList = re.findall(matchLabel, entry.label, re.I)
    137                if matchList != []:
    138                    returnList.append(i)
    139        else:
    140            for i, entry in enumerate(self.entries):
    141                if not substrMatchFlag:
    142                    if entry.label == matchLabel:
    143                        returnList.append(i)
    144                else:
    145                    if matchLabel in entry.label:
    146                        returnList.append(i)
    147
    148        return returnList

Returns the index of all intervals that match the given label

###### Arguments:

- matchLabel: the label to search for
- substrMatchFlag: if True, match any label containing matchLabel. if False, label must be the same as matchLabel.
- usingRE: if True, matchLabel is interpreted as a regular expression

###### Returns:

> A list of indicies

def new( self: ~T, name: Optional[str] = None, entries: Optional[list] = None, minTimestamp: Optional[float] = None, maxTimestamp: Optional[float] = None) -> ~T: View Source

    150    def new(
    151        self: T,
    152        name: Optional[str] = None,
    153        entries: Optional[list] = None,
    154        minTimestamp: Optional[float] = None,
    155        maxTimestamp: Optional[float] = None,
    156    ) -> T:
    157        """Make a new tier derived from the current one"""
    158        if name is None:
    159            name = self.name
    160        if entries is None:
    161            entries = copy.deepcopy(self.entries)
    162            entries = [
    163                self.entryType(*entry)
    164                if isinstance(entry, tuple) or isinstance(entry, list)
    165                else entry
    166                for entry in entries
    167            ]
    168        if minTimestamp is None:
    169            minTimestamp = self.minTimestamp
    170        if maxTimestamp is None:
    171            maxTimestamp = self.maxTimestamp
    172        return type(self)(name, entries, minTimestamp, maxTimestamp)

Make a new tier derived from the current one

def sort(self) -> None: View Source

    174    def sort(self) -> None:
    175        """Sorts the entries in the list of entries"""
    176        # A list containing tuples and lists will be sorted with tuples
    177        # first and then lists.  To correctly sort, we need to make
    178        # sure that all data structures inside the entry list are
    179        # of the same data type.  The entry list is sorted whenever
    180        # the entry list is modified, so this is probably the best
    181        # place to enforce the data type
    182        self._entries = [
    183            entry if isinstance(entry, self.entryType) else self.entryType(*entry)
    184            for entry in self.entries
    185        ]
    186        self._entries.sort()

Sorts the entries in the list of entries

def union( self, tier: TextgridTier) -> TextgridTier: View Source

    188    def union(self, tier: "TextgridTier") -> "TextgridTier":
    189        """The given tier is set unioned to this tier.
    190
    191        All entries in the given tier are added to the current tier.
    192        Overlapping entries are merged.
    193        """
    194        retTier = self.new()
    195
    196        for entry in tier.entries:
    197            retTier.insertEntry(
    198                entry,
    199                collisionMode=constants.IntervalCollision.MERGE,
    200                collisionReportingMode=constants.ErrorReportingMode.SILENCE,
    201            )
    202
    203        retTier.sort()
    204
    205        return retTier

The given tier is set unioned to this tier.

All entries in the given tier are added to the current tier. Overlapping entries are merged.

@abstractmethod
def editTimestamps( self, offset: float, reportingMode: Literal['silence', 'warning', 'error'] = 'warning') -> TextgridTier: View Source

    207    @abstractmethod
    208    def editTimestamps(
    209        self,
    210        offset: float,
    211        reportingMode: Literal["silence", "warning", "error"] = "warning",
    212    ) -> "TextgridTier":  # pragma: no cover
    213        pass

@abstractmethod
def insertEntry( self, entry, collisionMode: Literal['replace', 'merge', 'error'] = 'error', collisionReportingMode: Literal['silence', 'warning'] = 'warning') -> None: View Source

    215    @abstractmethod
    216    def insertEntry(
    217        self,
    218        entry,
    219        collisionMode: Literal["replace", "merge", "error"] = "error",
    220        collisionReportingMode: Literal["silence", "warning"] = "warning",
    221    ) -> None:  # pragma: no cover
    222        pass

@abstractmethod
def dejitter( self, referenceTier: TextgridTier, maxDifference: float = 0.001) -> TextgridTier: View Source

    224    @abstractmethod
    225    def dejitter(
    226        self,
    227        referenceTier: "TextgridTier",
    228        maxDifference: float = 0.001,
    229    ) -> "TextgridTier":  # pragma: no cover
    230        pass

@abstractmethod
def eraseRegion( self, start: float, end: float, collisionMode: Literal['truncate', 'categorical', 'error'] = 'error', doShrink: bool = True) -> TextgridTier: View Source

    232    @abstractmethod
    233    def eraseRegion(
    234        self,
    235        start: float,
    236        end: float,
    237        collisionMode: Literal["truncate", "categorical", "error"] = "error",
    238        doShrink: bool = True,
    239    ) -> "TextgridTier":  # pragma: no cover
    240        pass

@abstractmethod
def crop( self, cropStart: float, cropEnd: float, mode: Literal['strict', 'lax', 'truncated'], rebaseToZero: bool) -> TextgridTier: View Source

    242    @abstractmethod
    243    def crop(
    244        self,
    245        cropStart: float,
    246        cropEnd: float,
    247        mode: Literal["strict", "lax", "truncated"],
    248        rebaseToZero: bool,
    249    ) -> "TextgridTier":  # pragma: no cover
    250        pass

@abstractmethod
def insertSpace( self, start: float, duration: float, collisionMode: Literal['stretch', 'split', 'no_change', 'error']) -> TextgridTier: View Source

    252    @abstractmethod
    253    def insertSpace(
    254        self,
    255        start: float,
    256        duration: float,
    257        collisionMode: Literal["stretch", "split", "no_change", "error"],
    258    ) -> "TextgridTier":  # pragma: no cover
    259        pass

@abstractmethod
def deleteEntry(self, entry) -> None: View Source

    261    @abstractmethod
    262    def deleteEntry(self, entry) -> None:  # pragma: no cover
    263        pass

@abstractmethod
def validate(self, reportingMode) -> bool: View Source

    265    @abstractmethod
    266    def validate(self, reportingMode) -> bool:  # pragma: no cover
    267        pass