Skip to content

Sync Python API with TypeScript codebase (Feb 2026 audit) #61

@jon-myers

Description

@jon-myers

Overview

An audit of the TypeScript (UCSC-IDTAP/idtap) and Python (UCSC-IDTAP/Python-API) codebases as of Feb 17, 2026 reveals several sync gaps. The most significant is the absence of polyphonic (dual-string) support in the Python API, along with missing instruments and recent chikari/raga changes.


Critical: Polyphonic Individual Instrumentality Missing

TS commits: bd55a2d (Sep 2025) and subsequent work
Python status: Not implemented at all

The TypeScript codebase has extensive dual-string support for Sitar (main + jor string) and Sarangi (main + second string):

  • Piece.ensureStringSynchronization() — maintains temporal alignment between strings
  • Piece.stringFromTraj() — determines which string contains a trajectory
  • Piece.allTrajectories(inst, stringIdx) — accepts stringIdx parameter
  • Piece.trajStartTimes(inst, stringIdx) — string-aware timing
  • Phrase.trajectoryGrid — 2D: [stringIdx][trajectoryIdx]
  • Display methods accept stringIdx parameter

Python impact: all_trajectories(inst) has no string_idx parameter. Second-string data on Sitar/Sarangi transcriptions is completely inaccessible. Any analysis silently misses half the melodic content on polyphonic transcriptions.

Tasks

  • Add string_idx parameter to Piece.all_trajectories(), traj_start_times(), and related methods
  • Add ensure_string_synchronization() and string_from_traj() to Piece
  • Support 2D trajectory_grid indexing in Phrase (already partially supported via list-of-lists)
  • Update display methods to accept string_idx
  • Add tests with dual-string Sitar/Sarangi data

Important: 12 Instruments Missing from Enum

TS: 16 instruments in shared/enums.ts
Python: Only 4 in idtap/enums.py (Sitar, Vocal M, Vocal F, Sarangi)

Missing instruments:

Bansuri, Esraj, Rabab, Santoor, Sarod, Shehnai, Surbahar, Veena (Saraswati), Veena (Vichitra), Veena (Rudra Bin), Violin, Harmonium

Related: possible_trajs only defined for 3 instruments

Piece.possible_trajs (piece.py ~line 119) returns empty [] for any instrument not in its dictionary. TS defines mappings for all 16 instruments.

Tasks

  • Add all 12 missing instruments to Instrument enum in enums.py
  • Add possible_trajs mappings for all 16 instruments in Piece

Important: Raga-Derived Chikari Pitches Not Synced

TS commit: 29b99e4a (Feb 17, 2026) — "feat: derive chikari pitches from raga instead of hardcoded intervals"
Python status: Still uses hardcoded pitches

What changed in TS:

Raga.chikariPitches now returns 4 raga-aware pitches:

  1. Sa (oct 2) — always present
  2. Sa (oct 1) — always present
  3. Pa (oct 1) — derived from raga rule set; null (silent) if Pa absent from raga
  4. Ga (oct 1) — derived from raga; null (silent) if both komal and tivra Ga present (ambiguous)

Python Raga.chikari_pitches returns only [Sa oct=2, Sa oct=1] — just 2 pitches, no raga awareness.

Also affected:

Chikari.toJSON() in TS no longer serializes pitches (they're derived from raga at runtime, ~95% smaller output). Python to_json() still serializes full pitch data.

Piece.chikariFreqs() in TS returns 4 raga-aware frequencies. Python returns 2 frequencies via [f * 2, f * 4] fallback.

Tasks

  • Update Raga.chikari_pitches to derive 4 pitches from rule set (match TS logic)
  • Update Chikari.to_json() to only serialize fundamental and unique_id (match TS)
  • Update Chikari.from_json() to handle new format (pitches absent in JSON)
  • Update Piece.chikari_freqs() to return 4 raga-aware frequencies
  • Add tests for raga-derived chikari (ragas without Pa, ragas with both Ga variants)

Important: section_starts_grid Architecture Divergence

TS commit: 057f8f0 (Oct 2025)
Python PR: #48 added is_section_start to Phrase, but didn't complete the migration

In TypeScript, sectionStartsGrid is now a computed property derived from phrase.isSectionStart. It is no longer serialized in toJSON().

In Python, section_starts_grid is still a stored property and is still serialized in to_json(). The is_section_start flag exists on phrases (from PR #48) but isn't the source of truth.

Tasks

  • Make section_starts_grid a computed property derived from phrase.is_section_start
  • Remove section_starts_grid from to_json() output
  • Ensure from_json() handles both old (with grid) and new (without grid) formats

Minor: Duplicate init_sec_categorization in query_types.py

query_types.py has its own SecCatType with snake_case keys (pre_chiz_alap, composition_type, etc.) that don't match the actual database keys used in piece.py ("Pre-Chiz Alap", "Composition Type", etc.). This could cause subtle bugs if the wrong version is used for query construction.

Tasks

  • Reconcile query_types.py SecCatType keys with actual database format

Already In Sync (No Action Needed)

These areas are confirmed to be in parity:

Area Status
TalaName enum (14 talas) Fully synced
Trajectory types (14 types, id0-id13) Fully synced
Meter/Tala system Synced via PR #60
PhraseCatType categorization Fully synced
SecCatType categorization (in piece.py) Fully synced
CategoryType, DesignatorType, SegmentationType Fully synced
Core Raga methods (get_pitches, tuning, rule sets) Fully synced
is_section_start on Phrase Present (PR #48)
track_titles on Piece Present (PR #45)

Suggested Priority Order

  1. Instrument enum + possible_trajs — Quick win, broad impact
  2. Raga-derived chikari pitches — Recent TS change, should sync while fresh
  3. Chikari serialization format — Goes with Implement Comprehensive Parameter Validation Across All Classes #2
  4. section_starts_grid migration — Complete the architectural alignment
  5. Polyphonic string support — Largest effort, most impactful for data access
  6. query_types.py cleanup — Low priority

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions