from aligned_textgrid import AlignedTextGrid, \
TierGroup, \
SequenceTier, \
custom_classes
Word, Phone = custom_classes(["Word", "Phone"])Building an AlignedTextGrid
In this recipe, we’ll build an AlignedTextGrid “by hand.” The principles will be similar if you were building one programmatically from other kinds of timing and label data.
Use append
The safest way to go about building an AlignedTextGrid so that you don’t inadvertently start creating copies of your intervals and tiers is to stick to the .append() methods for these various objects.
Interval-first approach
One way you could go about doing things is to
build up some intervals and set up their super/subset relationships
then add the intervals to tiers
add the tiers to tiergroups
add the tiergroups to textgrids
First, we’ll set up with our imports.
Creating the intervals
Next, we’ll build some words and their phones.
the = Word((0, 10, "the"))
dog = Word((10, 25, "dog"))
DH = Phone((0, 5, "DH"))
AH0 = Phone((5, 10, "AH0"))
D = Phone((10, 15, "D"))
AO1 = Phone((15, 20, "A01"))
G = Phone((20, 25, "G"))Setting subset membership
Now, we can append the appropriate phones to their words.
for phone in [DH, AH0]:
the.append(phone)
for phone in [D, AO1, G]:
dog.append(phone)We can check to make sure everything got appended right.
# the first phone of 'the' is DH
the.first is DHTrue
# the last phone of 'dog' is G
dog.last is GTrue
Set up the tiers
Now, we’ll create an empty TierGroup that has a Word and Phone tier.
tier_group = TierGroup([
SequenceTier(entry_class=Word),
SequenceTier(entry_class=Phone)
])Appending the intervals
If we append the and dog to the Word tier, their phones will now be automatically added to the phone tier.
tier_group.Word.append(the)
tier_group.Word.append(dog)We’ll double check that the phones were automatically appended.
tier_group.Phone.labels['DH', 'AH0', 'D', 'A01', 'G']
Creating the AlignedTextGrid
Now, we can wrap this in an AlignedTextGrid so we can save it to a new TextGrid file, or any other analysis purpose.
atg = AlignedTextGrid([tier_group])
atgAlignedTextGrid with 1 groups named ['group_0'] each with [2] tiers. [['Word', 'Phone']]
Reference is maintained
Just to confirm that the reference to all objects has been maintained, let’s double check that our original words and phones are in the textgrid.
the in atg.group_0.WordTrue
AO1 in atg.group_0.PhoneTrue
TextGrid first approach
We could also take a TextGrid first approach, and then add each component piece by piece.
Initializing the TextGrid
atg = AlignedTextGrid()
atgAlignedTextGrid with 0 groups named [] each with [] tiers. []
Adding the TierGroup
tier_group = TierGroup([
SequenceTier(entry_class=Word),
SequenceTier(entry_class=Phone)
])
atg.append(tier_group)
atgAlignedTextGrid with 1 groups named ['group_0'] each with [2] tiers. [['Word', 'Phone']]
Adding the Intervals
For this part, I’m going to use some pythony tricks to make things a little easier. First the words.
word_times = [0,10,25]
word_labels = ["the", "dog"]
word_generator = zip(
word_times[0:-1],
word_times[1:],
word_labels)
for start, end, label in word_generator:
atg.group_0.Word.append(
Word((start, end, label))
)Now the phones
phone_times = [0, 5, 10, 15, 20, 25]
phone_labels = ["DH", "AH0", "D", "AO1", "G"]
phone_generator = zip(
phone_times[0:-1],
phone_times[1:],
phone_labels
)
for start, end, label in phone_generator:
atg.group_0.Phone.append(
Phone((start, end, label))
)Double checking
We can double check that everything is properly related.
new_the = atg.group_0.Word.first
new_dog = atg.group_0.Word.last
new_the.sub_labels['DH', '', 'AH0', '', '']
new_dog.sub_labels['', '', 'D', '', 'AO1', '', 'G', '', '', '', '']
Session Info
Code
import sys
import aligned_textgrid
print(
(
f"Python version: {sys.version}\n"
f"aligned-textgrid version: {aligned_textgrid.__version__}"
)
)Python version: 3.11.13 (main, Jun 4 2025, 04:12:12) [GCC 13.3.0]
aligned-textgrid version: 0.8.0