MatchfileLoader
loader.alignment.matchfile.MatchfileLoader(
score_unit=TimeUnit.quarters,
normalize_anacrusis=True,
)Load Vienna Match (.match) alignment files via partitura.
A single MatchfileLoader instance is intended to process all .match files that share the same score (e.g. 22 performances of one piece). It builds a shared score timeline on the first compatible file and verifies subsequent files against it. Incompatible files (snote ID present with different coordinates) are rejected with a warning.
Usage follows the standard loader two-phase pattern:
loader.load(*match_files)— parses all files, builds internal state.loader.create_alignment_bundle()— assembles the result.loader.create_timeline(id)— retrieves individual timelines.
Produces:
- A
ContinuousLogicalTimelinefor the score side (quarter-beat coordinates; MIDI divisions available via the attachedquarters_to_divsScalarMapC-Map). - One
DiscreteLogicalTimelineper performance (MIDI tick coordinates; seconds available via the attachedticks_to_secondsScalarMap). - One
MatchClaimper alignment record per file:- Matched notes produce
MatchClaim.from_events()(synchronous interval claim). - Deletion records produce
MatchClaim.nomatch()(non-synchronous, NOMATCH).
- Matched notes produce
All MatchClaims carry MatchMetadata(agent="vienna_match_v1.0.0", decision_criteria="automatic", certainty=1.0).
Coordinate system and normalisation: Score coordinates are stored as normalised TTA coordinates (shifted so the minimum onset is 0.0). A ShiftMap named "raw_quarters" is attached to the score timeline to convert normalised coordinates back to raw partitura values. The shift amount is computed from the file itself and never hardcoded.
External score timeline: Pass a score timeline previously built by PartituraLoader via the score_timeline= parameter of create_alignment_bundle(). The loader verifies compatibility (matching snote IDs and coordinates) and references the supplied timeline in all MatchClaims. MatchClaims are never rebound after creation.
See Also: timetoalign.MatchClaim timetoalign.AlignmentBundle
Args: score_unit: Primary unit for the score timeline. Default TimeUnit.quarters. normalize_anacrusis: If True (default), attach a ShiftMap that maps raw coordinates to normalised (non-negative) coordinates. Has no effect on the stored event coordinates, which are always the normalised (non-negative) values.
Attributes
| Name | Description |
|---|---|
| anacrusis_offset | The anacrusis offset applied to raw score coordinates. |
| rejected_files | Files rejected due to incompatible score coordinates. |
| sources | All files passed to load() (including rejected ones). |
Methods
| Name | Description |
|---|---|
| create_alignment_bundle | Assemble an AlignmentBundle from the loaded data. |
| create_timeline | Return a single timeline by uid, role string, or partial/regex match. |
| create_timelines | Return all timelines produced from loaded data. |
| load | Load one or more .match files. |
create_alignment_bundle
loader.alignment.matchfile.MatchfileLoader.create_alignment_bundle(
score_timeline=None,
verify=True,
)Assemble an AlignmentBundle from the loaded data.
Returns an AlignmentBundle directly. The bundle contains:
- The score timeline in its own group (
as_group="score") - Each performance timeline as a standalone timeline
- All MatchClaims as cross-group claims
This method takes NO file arguments. Files must be loaded first via load().
When an external score_timeline is supplied and verify is True (the default), the loader cross-checks every internally built score event against the external timeline using Timeline.get_event. A ValueError is raised if any event coordinates are incompatible.
Args: score_timeline: Optional pre-existing score timeline. When supplied, the bundle uses this timeline instead of the loader’s internally built one. MatchClaims are NOT rebound — they still reference the internally built score timeline’s uid. For correct cross-referencing, the external timeline should have the same uid. verify: If True (default) and score_timeline is not None, verify that internally built events are compatible with the external timeline. Set to False to skip verification (e.g. when the external timeline is known to be authoritative and you accept any coordinate differences).
Returns: AlignmentBundle with score group + standalone performances + MatchClaims.
Raises: RuntimeError: If load() has not been called yet. ValueError: If verify is True and the external timeline has incompatible event coordinates.
Examples: >>> loader = MatchfileLoader() >>> loader.load(*match_files) >>> bundle = loader.create_alignment_bundle() >>> len(bundle.timelines) # score + 22 performances 23
create_timeline
loader.alignment.matchfile.MatchfileLoader.create_timeline(id)Return a single timeline by uid, role string, or partial/regex match.
Matching precedence: 1. "score" — returns the shared score timeline. 2. Exact match on score timeline uid. 3. Exact match on performance timeline uid. 4. "perf:N" (1-indexed) — returns the N-th performance timeline. 5. "perf:pNN" — alternative syntax for performance indexing. 6. Partial/regex match on any timeline uid.
Args: id: Timeline uid (e.g. "score:Chopin_op10_no3"), role shorthand ("score", "perf:1"), or partial/regex pattern.
Returns: The matching Timeline.
Raises: KeyError: If no timeline with the given uid or role exists. RuntimeError: If load() has not been called yet.
Examples: >>> loader.create_timeline(“score”) # Role shorthand >>> loader.create_timeline(“perf:1”) # First performance >>> loader.create_timeline(“Chopin”) # Partial match >>> loader.create_timeline(r”^perf:.*p01”) # Regex match
create_timelines
loader.alignment.matchfile.MatchfileLoader.create_timelines()Return all timelines produced from loaded data.
For MatchfileLoader: [score_timeline, perf_p01, ..., perf_pN]. The score timeline is always first.
Returns: List of Timeline objects. Empty if load() has not been called yet.
load
loader.alignment.matchfile.MatchfileLoader.load(*sources)Load one or more .match files.
Parses each file via partitura, builds a shared score timeline from the first compatible file, and verifies subsequent files against it. Incompatible files are logged with a warning and tracked internally.
This method can be called multiple times to add more files incrementally.
Args: *sources: Paths to .match files.
Returns: Self, for method chaining.
Raises: FileNotFoundError: If any source path does not exist. ValueError: If any source is not a .match file.
Examples: >>> loader = MatchfileLoader() >>> loader.load(“Chopin_op10_no3_p01.match”) >>> # or load all at once >>> loader.load(sorted(data_dir.glob(“.match”)))