TextGridNavigator

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 or on other tiers of the TextGrid. Matches are primarily based on the labels in a tier.

As a simple example consider a TextGridNavigator that searches for the occurrence of one of the symbols in a topic set that consists of the symbols "a e i u o", and you want tier 1 to be searched. A match should occur if a label in tier 1 equals one of the symbols in this topic set. The command to start the search would then probably be Find first. Because of this command the navigator will search for the first occurrence of one of the vowels in the topic set in the labels of tier 1, and, if a match has been found, sets an internal pointer to this location. If you next perform a query with Get index: 1, "topic" it will return the number of the interval (or point) that matched (or 0 if no match could be found). The next match can then be found by using the Find next command and its value can be queried then. This may go on until the last match has been found. A following Find next will not be able to find a match and consequently the query for the index of the match will return 0. See Example 1 below for an example script.

Instead of starting at the beginning of the TextGrid you could also start at the end with Find last and next finding previous matches with Find previous or you could start the search at a certain time with Find next after time or Find previous before time.

A more complex example could query for a vowel from the same topic set as above but matches only if it is preceded by an unvoiced plosive from the Before set "p t k" and also is followed by a nasal from the After set "m n".

The two examples above were both one tier searches and these searches all follow the same scheme: they search for a topic symbol which may be preceded by a before symbol and/or followed by an after symbol. The topic, before and after symbol may belong to different sets. With a choice from a number of Boolean use criterions like Before or After, not both or Before and After you specify how the corresponding symbol sets are to be used during the matching.

For each tier in the TextGrid, we can define a tier search based on tier-specific topic symbols, and/ or tier-specific before and after symbols. Besides these, maximally three, sets of symbols we also need to specify the kind of match that we want. In the first example above we chose the label of the item in the topic tier 1 to have the is equal to relation to one of the symbols in the topic set. Other criteria for a match are possible to guarantee maximum flexibility and ease of use, like is not equal to, contains, does not start with and many more.

Additionally we also need to specify whether it is enough that at least one symbol in the set matches or that all symbols in the set should match. In set theory this translates to whether we have an OR or an AND relation between the individual matches. For example, in the first example above where we wanted to match one of the given vowels, we choose the is equal to match criterion and OR as the match boolean because what we wanted was that for the match to succeed only one of the symbols in the topic set needed to match. We can write this match as (label == topicSymbol1) OR (label == topicSymbol2) OR ... OR (label == topicSymboln), where the OR implies that only one of the matches needs to succeed to make the complete expression true. If on the other hand we did not want to match any of the symbols in the topic set, i.e. if we had chosen is not equal to as criterion, then we should use an AND match boolean because we can now write our match intention as (label != topicSymbol1) AND (label != topicSymbol2) AND ... AND (label != topicSymboln), where the AND implies that all matches have to succeed to make the whole expression true. Most of the time, inclusive searches are based on OR and exclusive searches are based on AND.

A multi-tier search can now be defined by combining a number of single tier searches, where each single tier search searches a different tier number. To combine the matches on each tier we have to know how to relate them which can only be done on the basis of time because this is the only thing common between the tiers: they all have the same time base. We take one tier as the basis for comparing, i.e. this is the comparand or in our terminology the topic tier. The matches on the other tiers, the sub-ordinate tiers, can have a specific relation to the match on the topic tier. Although we can have matches on interval tiers and on point tiers let's for simplicity assume we only use interval tiers. Suppose on the topic tier we have a match on an interval that runs from tmin to tmax. The match location criterion for a match of an interval [tmin2, tmax2] on a sub-ordinate tier can for example be chosen as is before which means that the end time of the sub-ordinate interval has to lie before the start time of the topic interval, i.e. tmax2 < tmin. Another location match criterion is overlaps before and after which translates to tmin2 < tmin and tmax2 > tmax. Of course more than these three location match criteria exist.

This makes the multi-tier search complete as it is a combination of single-tier searches that are combined on the basis of location match criteria.

How to create a TextGridNavigator

Example 1, simple search in one tier

tierNumber = 1
selectObject: <textgrid>
navigator = To TextGridNavigator (topic search): tierNumber, "a e i u o",
..."is equal to", "OR", "Match start to Match end"
Find first
index = Get index: tierNumber, "topic"
while index > 0
    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"
endwhile

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
selectObject: <textgrid>
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>
endfor

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>
endfor

Example 2, search in one tier

Search for one of the vowels "a e i u o" immediately preceded by one of the plosives "p t k" and immediately followed by one of the nasals "m n".

tierNumber = 1
selectObject: <textgrid>
navigator = To TextGridNavigator: tierNumber,
    ... "a e i u o", "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"
domains## = List domains: "Topic start to Topic end"
<your code>

If, for example, the start time should be equal to the start time of the Before match, i.e. the plosive, and the end time should equal the end time of the After match, i.e. the nasal, you could use instead:

domains## = List domains: "Before start to After end"

© djmw, March 8, 2021