One of the types of objects in Praat. A TextGridNavigator is a multi-tier search machine.

What is a multi-tier search machine?

A multi-tier search machine enables you to find an interval (or a point) on a tier, based on criteria that can have a specified relation with intervals (or points) on the same tier or on other tiers of the TextGrid. Matches on each tier are based on the labels in a tier. Matches found on different tiers are combined based on time. The match criteria for each tier are specified in the tier's NavigationContext.

Example 1: Single-tier topic search:

We create a TextGridNavigator that searches for the occurrence in tier 1 of one of the labels in a topic set that consists of the labels { "a", "e", "i", "o", "u" }. If a label in tier 1 equals one of the labels in this topic set we have a match. The command to create the TextGridNavigator for the selected TextGrid is:

    To TextGridNavigator (topic search): 1,
    ... { "a", "e", "i", "o", "u" }, "is equal to", "OR",
    ... "Match start to Match end"

In this case the tier's NavigationContext is very simple as the searching / matching only involves labels of the topic set. After the TextGridNavigator has been created it doesn't need the TextGrid anymore because tier 1 has been copied into the navigator object. The following code would find all the intervals that match and get their start time, end time and label.

    Find first
    index = Get index: tierNumber, "topic"
    while index > 0
       selectObject: textgrid
       startTime = Get start time: tierNumber, "topic"
       endTime = Get end time: tierNumber, "topic"
       label$ = Get label: tierNumber, "topic"
       selectObject: navigator
       Find next
       index = Get index: tierNumber, "topic"

The Find first command finds the index of the first interval (or point) in the tier that matches. The Get index command returns this index. Besides giving the index of the topic match it can also return indices of before or after matches. If no match was found it returns zero. Find next finds the next interval that matches.

Instead of finding the indices one at a time in a while loop until we are done, we could use alternatives and query for a list of all indices or times where the labels match. We then know beforehand how many matches we have and therefore we can use a for loop.

    tierNumber = 1
    navigator = To TextGridNavigator (topic search): tierNumber,
    ... { "a", "e", "i", "u", "o" }, "is equal to", "OR",
    ... "Match start to Match end"
    startTimes# = List start times: "topic"
    labels$# = List labels: "Topic"
    endTimes# = List end times: "topic"
    for index to size (startTimes#)
       duration = endTimes# [index] - startTimes# [index]
       <your code>

We could also combine the start and end times into one query list:

    domains## = List domains: "Topic start to Topic end"
    numberOfMatches = numberOfRows (domains##)

and use it in a loop as, for example,

    for index to numberOfMatches
       duration = domains## [index, 2] - domains## [index, 1]
       <your code>

Example 2: Single-tier before + topic + after search

A more complex example could query for a vowel from the same topic set as we used above but only matches if additionally it is immediately preceded by an unvoiced plosive from a Before set, like e.g. { "p", "t", "k" }, and also is immediately followed by a nasal from an After set, like { "m", "n" }. The command to create this navigator once the TextGrid is selected is:

    tierNumber = 1
    To TextGridNavigator: tierNumber,
    ... { "a", "e", "i", "o", "u" }, "is equal to", "OR",
    ... { "p", "t", "k" }, "is equal to", "OR",
    ... { "m", "n" }, "is equal to", "OR",
    ... "before and after", "false", "Topic start to Topic end"

This example and the one above involve only searches on one tier and both follow the same scheme: they search for a topic label which may be preceded by a before label and/or followed by an after label. The topic, before and after label belong to different sets (the three sets may of course have labels in common). With a choice from a number of use criterions like Before or After, not both or Before and After you specify how the corresponding label sets will be used during the matching.

For each tier in the TextGrid, we can define a tier search based on tier-specific sets of topic labels, and/ or tier-specific before and after labels. Besides these maximally three sets of labels, we also need to specify the kind of match that we want. This is all specified in a tier's NavigationContext.

Example 3: Multi-tier search by combining single-tier searches

A multi-tier search navigator can be created by successively adding one or more single tier searches to an already existing TextGridNavigator. Each tier added for searching should have a unique tier number. To combine the matches on different tiers we have to chose how to relate these matches on the basis of time because time is the only feature that all tiers have in common as they all have the same time domain. Suppose the TextGrid has two tiers: the first is a phoneme tier like we used in the previous example and the second is a syntactic tier where intervals may be labeled as "Noun", "Determiner", "Verb" etc. We want to restrict the vowel search on tier 1 to only those vowels that are within an interval at tier 2 that is labeled as "Noun" and is preceded by an interval labeled "Determiner". The only complexity of a multi-tier TextGrid navigator is within its creation process. The following script shows how to create the two-tier navigator.

    phonemeTierNumber = 1
    syntaxTierNumber = 2
    selectObject: texgrid
    navigator = To TextGridNavigator: phonemeTierNumber,
    ... { "a", "e", "i", "o", "u" }, "is equal to", "OR",
    ... { "p", "t", "k" }, "is equal to", "OR",
    ... { "m", "n" }, "is equal to", "OR",
    ... "before and after", "false", "Topic start to Topic end"
    selectObject: texgrid, navigator
    Add search tier: syntaxTierNumber,
    ... { "Noun" }, "is equal to", "OR",
    ... { "Determiner" }, "is equal to", "OR",
    ... { }, "is equal to", "OR",
    ... "before", "false", "Topic start to Topic end",
    ... overlaps before and after

The script starts by creating the navigator for the topic tier, tier number 1, that we already discussed in Example 2 which searches for vowels in a plosive-nasal context. The match domain, i.e. that time interval in the topic tier that will be used as the anchor for the comparisons with the match domains of other tiers, is chosen as Topic start to Topic end. This means that, in case of a match on this tier, the start and end times of the match equal the start and end times of the matched vowel interval, respectively. More options exist for the choice of the match domain. The chosen match domain on the topic tier will always serve as the anchor for the comparisons with matches on other tiers. The Add search tier command adds a tier to the navigator that will be searched for combinations of a "Noun" label preceded by a "Determiner" label. The NavigationContext for this tier therefore consists of only a topic set and a before set and both have only one member. The matches on the added search tier will be used to limit the number of matches on the topic tier by checking if a specified time relation between the match domains on both tiers exist. Suppose that on both tiers we have a match which means that on the topic tier we found a vowel that is preceded by a plosive and followed by a nasal, and, on the syntax tier we found an interval labeled "Noun" that is preceded by an interval labeled "Determiner". The start and end time of the match domain on the topic tier equal the start and end time of the vowel interval; name them tmin1 and tmax1, respectively. The match domain on the syntax tier will be the interval [tmin2, tmax2], where tmin2 and tmax2 are the start and end time of the interval labeled "Noun" because we also have chosen the Topic start to Topic end option as the match domain for the syntax tier. How to combine these two separate matches on the two different tiers will be determined by the last option of the Add search tier command which was chosen as overlaps before and after. Now, only if tmin2 < tmin1 and tmax2 > tmax1 the two intervals have the desired alignment and the match would succeed.

We can, of course, make our match stricter and demand that, for example, the complete three phoneme match of the topic tier is located within the match domain of the syntax tier by issuing the following command:

    selectObject: navigator
    Modify match domain: phonemeTierNumber, "Before start to Topic end"

Even more stricter to exact alignment:

    Modify match domain alignment: syntaxTierNumber, "touches before and after"

Using the TextGridNavigator with other TextGrids

If the TextGrids in your corpus have identical structure, i.e. your search tiers all have the same tier number you can simply reuse your already defined navigator.

    selectObject: navigator, otherTextGrid
    Replace search tiers

Links to this page

© djmw 20230801