SPPAS 4.20

Module sppas.src.annotations

Class sppasTGA

Description

Estimate TGA on a tier -- from D. Gibbon.

Create time groups then map them into a dictionary where:

  • key is a label assigned to the time group;
  • value is the list of observed durations of segments in this TG.

Constructor

Create a new sppasTGA instance.

Log is used for a better communication of the annotation process and its

results. If None, logs are redirected to the default logging system.

Parameters
  • log: (sppasLog) Human-readable logs.
View Source
def __init__(self, log=None):
    """Create a new sppasTGA instance.

    Log is used for a better communication of the annotation process and its
    results. If None, logs are redirected to the default logging system.

    :param log: (sppasLog) Human-readable logs.

    """
    super(sppasTGA, self).__init__('tga.json', log)
    self._tg_separators = list(symbols.phone.keys())
    self._tg_separators.append('#')
    self._tg_separators.append('@@')
    self._tg_separators.append('+')
    self._tg_separators.append('gb')
    self._tg_separators.append('lg')
    self._tg_separators.append('_')

Public functions

fix_options

Fix all options.

Available options are:

  • with_radius
  • original
  • annotationpro
  • tgprefixlabel
Parameters
  • options: (sppasOption)
View Source
def fix_options(self, options):
    """Fix all options.

        Available options are:

            - with_radius
            - original
            - annotationpro
            - tg_prefix_label

        :param options: (sppasOption)

        """
    for opt in options:
        key = opt.get_key()
        if 'with_radius' == key:
            self.set_with_radius(opt.get_value())
        elif 'original' == key:
            self.set_intercept_slope_original(opt.get_value())
        elif 'annotationpro' == key:
            self.set_intercept_slope_annotationpro(opt.get_value())
        elif 'tg_prefix_label' == key:
            self.set_tg_prefix_label(opt.get_value())
        elif 'pattern' in key:
            self._options[key] = opt.get_value()
        else:
            raise AnnotationOptionError(key)
set_tg_prefix_label

Fix the prefix to add to each TG.

Parameters
  • prefix: (str) Default is 'tg_'
View Source
def set_tg_prefix_label(self, prefix):
    """Fix the prefix to add to each TG.

        :param prefix: (str) Default is 'tg_'

        """
    sp = sppasUnicode(prefix)
    tg = sp.to_strip()
    if len(tg) > 0:
        self._options['tg_prefix_label'] = tg
set_with_radius

Set the with_radius option, used to estimate the duration.

Parameters
  • with_radius: (int)
  • 0 means to use Midpoint;
  • negative value means to use R-;
  • positive radius means to use R+.
View Source
def set_with_radius(self, with_radius):
    """Set the with_radius option, used to estimate the duration.

        :param with_radius: (int)

        - 0 means to use Midpoint;
        - negative value means to use R-;
        - positive radius means to use R+.

        """
    try:
        w = int(with_radius)
        self._options['with_radius'] = w
    except ValueError:
        raise
set_intercept_slope_original

Estimate intercepts and slopes with the original method.

Default is False.

Parameters
  • value: (boolean)
View Source
def set_intercept_slope_original(self, value):
    """Estimate intercepts and slopes with the original method.

        Default is False.

        :param value: (boolean)

        """
    self._options['original'] = bool(value)
set_intercept_slope_annotationpro

Estimate intercepts and slopes with the method of annotationpro.

Default is True.

Parameters
  • value: (boolean)
View Source
def set_intercept_slope_annotationpro(self, value):
    """Estimate intercepts and slopes with the method of annotationpro.

        Default is True.

        :param value: (boolean)

        """
    self._options['annotationpro'] = bool(value)
syllables_to_timegroups

Create the time group intervals.

Parameters
  • syllables: (sppasTier)
Returns
  • (sppasTier) Time groups
View Source
def syllables_to_timegroups(self, syllables):
    """Create the time group intervals.

        :param syllables: (sppasTier)
        :returns: (sppasTier) Time groups

        """
    intervals = syllables.export_to_intervals(self._tg_separators)
    intervals.set_name('TGA-TimeGroups')
    for i, tg in enumerate(intervals):
        tag_str = self._options['tg_prefix_label']
        tag_str += str(i + 1)
        tg.append_label(sppasLabel(sppasTag(tag_str)))
    return intervals
syllables_to_timesegments

Create the time segments intervals.

Time segments are time groups with serialized syllables.

Parameters
  • syllables
Returns
  • (sppasTier) Time segments
View Source
def syllables_to_timesegments(self, syllables):
    """Create the time segments intervals.

        Time segments are time groups with serialized syllables.

        :param syllables:
        :returns: (sppasTier) Time segments

        """
    intervals = syllables.export_to_intervals(self._tg_separators)
    intervals.set_name('TGA-Segments')
    for i, tg in enumerate(intervals):
        syll_anns = syllables.find(tg.get_lowest_localization(), tg.get_highest_localization())
        tag_str = ''
        for ann in syll_anns:
            tag_str += serialize_labels(ann.get_labels(), separator=' ')
            tag_str += ' '
        tg.append_label(sppasLabel(sppasTag(tag_str)))
    return intervals
timegroups_to_durations

Return a dict with timegroups and the syllable durations.

Parameters
  • syllables: (sppasTier) Syllables
  • timegroups: (sppasTier) Time groups
Returns
  • (dict)
View Source
def timegroups_to_durations(self, syllables, timegroups):
    """Return a dict with timegroups and the syllable durations.

        :param syllables: (sppasTier) Syllables
        :param timegroups: (sppasTier) Time groups
        :returns: (dict)

        """
    tg_dur = dict()
    for tg_ann in timegroups:
        tg_label = serialize_labels(tg_ann.get_labels())
        tg_dur[tg_label] = list()
        syll_anns = syllables.find(tg_ann.get_lowest_localization(), tg_ann.get_highest_localization())
        for syll_ann in syll_anns:
            loc = syll_ann.get_location().get_best()
            dur = loc.duration()
            value = dur.get_value()
            if self._options['with_radius'] < 0:
                value -= dur.get_margin()
            if self._options['with_radius'] > 0:
                value += dur.get_margin()
            tg_dur[tg_label].append(value)
    return tg_dur
tga_to_tier

Create a tier from one of the TGA result.

Parameters
  • tga_result: One of the results of TGA
  • timegroups: (sppasTier) Time groups
  • tier_name: (str) Name of the output tier
  • tag_type: (str) Type of the sppasTag to be included
Returns
  • (sppasTier)
View Source
@staticmethod
def tga_to_tier(tga_result, timegroups, tier_name, tag_type='float'):
    """Create a tier from one of the TGA result.

        :param tga_result: One of the results of TGA
        :param timegroups: (sppasTier) Time groups
        :param tier_name: (str) Name of the output tier
        :param tag_type: (str) Type of the sppasTag to be included

        :returns: (sppasTier)

        """
    tier = sppasTier(tier_name)
    for tg_ann in timegroups:
        tg_label = serialize_labels(tg_ann.get_labels())
        tag_value = tga_result[tg_label]
        if tag_type == 'float':
            tag_value = round(tag_value, 5)
        tier.create_annotation(tg_ann.get_location().copy(), sppasLabel(sppasTag(tag_value, tag_type)))
    return tier
tga_to_tier_reglin

Create tiers of intercept,slope from one of the TGA result.

Parameters
  • tga_result: One of the results of TGA
  • timegroups: (sppasTier) Time groups
  • intercept: (boolean) Export the intercept. If False, export Slope.
Returns
  • (sppasTier)
View Source
@staticmethod
def tga_to_tier_reglin(tga_result, timegroups, intercept=True):
    """Create tiers of intercept,slope from one of the TGA result.

        :param tga_result: One of the results of TGA
        :param timegroups: (sppasTier) Time groups
        :param intercept: (boolean) Export the intercept.
        If False, export Slope.

        :returns: (sppasTier)

        """
    if intercept is True:
        tier = sppasTier('TGA-Intercept')
    else:
        tier = sppasTier('TGA-Slope')
    for tg_ann in timegroups:
        tg_label = serialize_labels(tg_ann.get_labels())
        loc = tg_ann.get_location().copy()
        if intercept is True:
            tag_value = tga_result[tg_label][0]
        else:
            tag_value = tga_result[tg_label][1]
        tag_value = round(tag_value, 5)
        tier.create_annotation(loc, sppasLabel(sppasTag(tag_value, 'float')))
    return tier
convert

Estimate TGA on the given syllables.

Parameters
  • syllables: (sppasTier)
Returns
  • (sppasTranscription)
View Source
def convert(self, syllables):
    """Estimate TGA on the given syllables.

        :param syllables: (sppasTier)
        :returns: (sppasTranscription)

        """
    trs_out = sppasTranscription('TimeGroupAnalyser')
    timegroups = self.syllables_to_timegroups(syllables)
    timegroups.set_meta('timegroups_of_tier', syllables.get_name())
    trs_out.append(timegroups)
    timesegs = self.syllables_to_timesegments(syllables)
    trs_out.append(timesegs)
    tg_dur = self.timegroups_to_durations(syllables, timegroups)
    ts = TimeGroupAnalysis(tg_dur)
    tier = sppasTGA.tga_to_tier(ts.len(), timegroups, 'TGA-Occurrences', 'int')
    trs_out.append(tier)
    tier = sppasTGA.tga_to_tier(ts.total(), timegroups, 'TGA-Total')
    trs_out.append(tier)
    tier = sppasTGA.tga_to_tier(ts.mean(), timegroups, 'TGA-Mean')
    trs_out.append(tier)
    tier = sppasTGA.tga_to_tier(ts.median(), timegroups, 'TGA-Median')
    trs_out.append(tier)
    tier = sppasTGA.tga_to_tier(ts.stdev(), timegroups, 'TGA-StdDev')
    trs_out.append(tier)
    tier = sppasTGA.tga_to_tier(ts.nPVI(), timegroups, 'TGA-nPVI')
    trs_out.append(tier)
    if self._options['original'] is True:
        tier = sppasTGA.tga_to_tier_reglin(ts.intercept_slope_original(), timegroups, True)
        tier.set_name('TGA-Intercept-original')
        trs_out.append(tier)
        tier = sppasTGA.tga_to_tier_reglin(ts.intercept_slope_original(), timegroups, False)
        tier.set_name('TGA-Slope-original')
        trs_out.append(tier)
    if self._options['annotationpro'] is True:
        tier = sppasTGA.tga_to_tier_reglin(ts.intercept_slope(), timegroups, True)
        tier.set_name('TGA-Intercept-timestamps')
        trs_out.append(tier)
        tier = sppasTGA.tga_to_tier_reglin(ts.intercept_slope(), timegroups, False)
        tier.set_name('TGA-Slope-timestamps')
        trs_out.append(tier)
    return trs_out
get_inputs

Return the the tier with aligned tokens.

Parameters
  • input_files: (list)
Raises

NoTierInputError

Returns
  • (sppasTier)
View Source
def get_inputs(self, input_files):
    """Return the the tier with aligned tokens.

        :param input_files: (list)
        :raise: NoTierInputError
        :return: (sppasTier)

        """
    tier = None
    annot_ext = self.get_input_extensions()
    for filename in input_files:
        fn, fe = os.path.splitext(filename)
        if tier is None and fe in annot_ext[0]:
            parser = sppasTrsRW(filename)
            trs_input = parser.read()
            tier = sppasFindTier.aligned_syllables(trs_input)
            if tier is not None:
                return tier
    logging.error('A tier with time-aligned syllables was not found.')
    raise NoTierInputError
run

Run the automatic annotation process on an input.

Parameters
  • input_files: (list of str) Syllabification
  • output: (str) the output file name
Returns
  • (sppasTranscription)
View Source
def run(self, input_files, output=None):
    """Run the automatic annotation process on an input.

        :param input_files: (list of str) Syllabification
        :param output: (str) the output file name
        :returns: (sppasTranscription)

        """
    tier_input = self.get_inputs(input_files)
    trs_output = sppasTranscription(self.name)
    trs_output.set_meta('annotation_result_of', input_files[0])
    trs_output = self.convert(tier_input)
    if output is not None:
        if len(trs_output) > 0:
            output_file = self.fix_out_file_ext(output)
            parser = sppasTrsRW(output_file)
            parser.write(trs_output)
            return [output_file]
        else:
            raise EmptyOutputError
    return trs_output
get_output_pattern

Pattern this annotation uses in an output filename.

View Source
def get_output_pattern(self):
    """Pattern this annotation uses in an output filename."""
    return self._options.get('outputpattern', '-tga')
get_input_patterns

Pattern this annotation expects for its input filename.

View Source
def get_input_patterns(self):
    """Pattern this annotation expects for its input filename."""
    return [self._options.get('inputpattern', '-syll')]