Fix fractional_beat clustering with reference_level=0 (Issue #28)#29
Merged
Fix fractional_beat clustering with reference_level=0 (Issue #28)#29
Conversation
- Added bounds checking in _calculate_level_start_time to handle pulse indices that exceed the all_pulses array bounds - When pulse index exceeds bounds, gracefully return meter end time instead of crashing with IndexError - Added comprehensive test cases for boundary conditions and edge cases - All existing tests continue to pass Fixes #26: IndexError in get_musical_time() with reference_level=0
Fixes Issue #28 where fractional_beat values were clustering near 0.000 instead of varying smoothly 0.0-1.0 within beats when using reference_level=0. **Root Cause:** When reference_level=0, the hierarchical position was truncated to only include the beat level before calculating fractional_beat. This removed all subdivision information, causing _calculate_level_start_time to only find beat boundaries rather than precise subdivision positions. **Solution:** - Preserve full hierarchical position for fractional_beat calculation - Only truncate position for final MusicalTime result as expected - Maintains backward compatibility and all existing reference level behavior **Testing:** - All 343 tests pass including comprehensive Issue #28 test suite - Validates fractional_beat distribution, range, and uniqueness - Confirms all reference levels (0, 1, 2+) work correctly - Tests both synthetic and real transcription data patterns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
|
📦 Test Package Built Successfully! This PR has been automatically built and uploaded to TestPyPI for testing. 🔗 TestPyPI Link: https://test.pypi.org/project/idtap/ To test this version: pip install --index-url https://test.pypi.org/simple/ idtap✅ All tests passed and package builds successfully. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
COMPREHENSIVE FIX: Resolves Issue #28 fractional_beat clustering by implementing proportional timing fallback for sparse pulse data in real transcription meters.
Root Cause Analysis
The issue was not in the original position truncation logic, but in the fundamental difference between real and synthetic meter data:
Real Transcription Meters:
_pulses_per_cycle=32,_pulse_dur=0.128s(correct)all_pulses count=2(sparse - only manually annotated pulses!)Synthetic Meters:
_pulses_per_cycle=32,_pulse_dur=0.128sall_pulses count=32(complete pulse grid)This mismatch caused pulse-based timing calculations in
_calculate_level_start_timeand_calculate_level_durationto fail with real data.Solution Implementation
1. Detection Logic
2. Proportional Timing Methods
_calculate_proportional_level_start_time(): Calculates beat boundaries using cycle division instead of pulse indexing_calculate_proportional_level_duration(): Calculates unit durations using hierarchical ratios instead of pulse differences3. Fallback Strategy
Results
Before Fix (Broken)
After Fix (Working)
Consistency Verification
Test Results
Impact
🤖 Generated with Claude Code