Alignment Bundles

MatchfileLoader, AlignmentBundle, cross-group transfer

Alignment Bundles

An AlignmentBundle manages multiple timelines and the groups that connect them. We load the Vienna 1x22 corpus (one score, 22 performances) using the MatchfileLoader to illustrate the pattern.

from pathlib import Path

from timetoalign import MatchfileLoader

DATA_DIR = Path(".").resolve().parent.parent / "tests" / "data" / "vienna_1x22"

Load All Match Files at Once

A single MatchfileLoader instance processes all .match files that share the same score.

match_files = sorted(DATA_DIR.glob("*.match"))
loader = MatchfileLoader()
loader.load(*match_files)

{
    "files loaded": len(match_files),
    "timelines": len(loader.create_timelines()),
}
{'files loaded': 22, 'timelines': 23}

Create the Bundle

bundle = loader.create_alignment_bundle()
bundle
AlignmentBundle[bundle:AlignmentBundle_1]

  TimelineGroup[score] (1 timelines, 2 timestamps)
  ┌────────────────────────────────────────────────────────────────────────────┐
  │ ContinuousLogicalTimeline[score:Chopin_op10_no3] (454 events, 2 cmaps)     │
  │                       0 ____________________________________ 41.5 quarters │
  └────────────────────────────────────────────────────────────────────────────┘
  Timestamps: 2

  Standalone timelines (22):
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 79900 ticks (451 ev)
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 72365 ticks (448 ev)
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 76999 ticks (452 ev)
    ... (16 more)
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 86143 ticks (447 ev)
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 83149 ticks (451 ev)
    perf:Chop...     0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 77497 ticks (452 ev)

  MatchClaims: 9988

Explore Timelines

score_tl = bundle.get_timeline("score")
score_tl
ContinuousLogicalTimeline[score:Chopin_op10_no3] (454 events, 2 cmaps)
                      0 ________________________________ 41.5 quarters
score_tl.get_events(event_type="Note").to_dataframe().head()
id name temporal_type event_type start end duration

Query Coordinates Across Groups

get_timestamp_at() returns coordinates on all connected timelines.

perf_id = [uid for uid in bundle.timeline_ids if uid != "score"][0]

ts = bundle.get_timestamp_at(100.0, "score")
ts
{'score/score (quarters)': 100.0}

Next: Flow Control and Grids