Timelines, Events, and Maps

Loading, EventStore, Coordinate, ConversionMap

Timelines, Events, and Maps

Load real musical data, explore it as an EventStore, create a Timeline, and attach a ConversionMap to translate between units.

from pathlib import Path

from timetoalign.loader.score.partitura import PartituraLoader
from timetoalign.maps import TicksToQuarters
/home/laser/miniconda3/envs/timetoalign/lib/python3.11/site-packages/partitura/__init__.py:9: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  import pkg_resources

Load Events from a Score

DATA_DIR = Path(".").resolve().parents[1] / "tests" / "data" / "vienna_1x22"

loader = PartituraLoader()
loader.load(DATA_DIR / "Chopin_op10_no3.musicxml")
loader.store
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~/miniconda3/envs/timetoalign/lib/python3.11/site-packages/IPython/core/formatters.py:406, in BaseFormatter.__call__(self, obj)
    404     method = get_real_method(obj, self.print_method)
    405     if method is not None:
--> 406         return method()
    407     return None
    408 else:

File ~/git/tta/timetoalign/timetoalign/storage/store.py:249, in EventStore._repr_html_(self)
    247 rows = []
    248 for name, info in summary.items():
--> 249     unit = info.get("unit", "unknown")
    250     count = info.get("count", 0)
    251     coord_range = info.get("range", (0.0, 0.0))

AttributeError: 'int' object has no attribute 'get'
ScoreStore(notes=498, measures=22, controls=22, annotations=5)

Create a Timeline

tl = loader.create_timeline(uid="chopin_etude")
tl
ContinuousLogicalTimeline[chopin_etude] (547 events, 4 children, 3 cmaps)
                      0 ________________________________ 41.5 quarters
  ├─ notes            0 ________________________________ 41.5 (498 events)
  ├─ measures         0 ________________________________ 41.5 (22 events)
  ├─ controls         0 ______________________________   40 (22 events)
  └─ annotations      0 _________________________        32.5 (5 events)

Access Events

The loader creates child timelines for each event category (notes, measures, controls). Access them via get_child().

tl.get_child("notes").get_events(event_type="Note").to_dataframe().head()
id name temporal_type event_type start end duration mc mn mc_onset ... specific_pitch midi tpc octave tied gracenote chord_id voice staff part_id
0 notes:note:000001 B3 interval Note 0 0.50 1/2 1 1 0 ... {'step': 'B', 'alter': 0, 'octave': 3, 'cents'... 59 5 3 0 NaN NaN 1 1 P1
1 notes:note:000002 E4 interval Note 1/2 1.00 1/2 2 2 0 ... {'step': 'E', 'alter': 0, 'octave': 4, 'cents'... 64 4 4 0 NaN NaN 1 1 P1
2 notes:note:000003 G♯3 interval Note 1/2 0.75 1/4 2 2 0 ... {'step': 'G', 'alter': 1, 'octave': 3, 'cents'... 56 8 3 0 NaN NaN 3 1 P1
3 notes:note:000004 E2 interval Note 1/2 0.75 1/4 2 2 0 ... {'step': 'E', 'alter': 0, 'octave': 2, 'cents'... 40 4 2 0 NaN NaN 4 2 P1
4 notes:note:000005 E2 interval Note 1/2 1.50 1 2 2 0 ... {'step': 'E', 'alter': 0, 'octave': 2, 'cents'... 40 4 2 0 NaN NaN 7 2 P1

5 rows × 21 columns

Coordinates

A Coordinate binds a number to a unit, ensuring type-safe arithmetic.

coord = tl.make_coordinate(8)
coord
Coordinate(8, quarters)

Conversion Maps (C-Maps)

Attach a map to translate the timeline’s native quarters into MIDI ticks (at 480 pulses per quarter).

q2t = TicksToQuarters(ppq=480).inverse()
tl.add_conversion_map(q2t)

ticks_coord = tl.convert_to(coord, target_unit="ticks")
{
    "input": f"{coord.value} {coord.unit.name}",
    "output": f"{ticks_coord}",
}
{'input': '8 quarters', 'output': '3840 ticks'}

Next: Children, Regions & Timestamps