Skip to content

Fix hierarchical position calculation bug in multi-cycle meters#37

Merged
jon-myers merged 1 commit intomainfrom
fix-issue-36-fractional-beat-hierarchical-position
Sep 10, 2025
Merged

Fix hierarchical position calculation bug in multi-cycle meters#37
jon-myers merged 1 commit intomainfrom
fix-issue-36-fractional-beat-hierarchical-position

Conversation

@jon-myers
Copy link
Contributor

Summary

Fixes Issue #36: hierarchical position calculation bug in multi-cycle meters that causes incorrect fractional_beat values to be clamped to 0.0.

Root Cause

The hierarchical position calculation algorithm sometimes pointed to pulses that come after the query time instead of before/at it. This caused:

  • Negative time_from_current_pulse values
  • Negative fractional_beat values that get clamped to 0.0
  • Incorrect trajectory curve visualization showing clustering instead of smooth progression

Solution

  • Detection: Added validation to check if calculated pulse comes after query time
  • Correction: Walk backward to find correct pulse that comes at/before query time
  • Position Update: Recalculate hierarchical position using new _pulse_index_to_hierarchical_position() method
  • Testing: Added comprehensive test test_issue_36_hierarchical_position_correction()

Changes Made

idtap/classes/meter.py

  • Added pulse time validation and correction logic in get_musical_time() (lines 583-593)
  • Implemented _pulse_index_to_hierarchical_position() method for reverse calculation
  • Fixed unused variable diagnostic

idtap/tests/musical_time_test.py

  • Added test_issue_36_hierarchical_position_correction() test case
  • Tests multi-cycle meters with timing variations that expose the bug

Testing

  • ✅ All 344 existing tests continue to pass
  • ✅ New test specifically validates the fix
  • ✅ Fix handles multi-cycle meters with timing variations
  • ✅ Maintains backward compatibility

Impact

This fix ensures that:

  • Musical time analysis is accurate across all cycles in multi-cycle meters
  • Trajectory curve visualization shows smooth progression instead of clustering
  • fractional_beat values are calculated correctly for transcription analysis

Closes #36

🤖 Generated with Claude Code

…36)

- Fix bug where hierarchical position calculation pointed to pulses after query time
- Add pulse time validation and correction logic in get_musical_time()
- Implement _pulse_index_to_hierarchical_position() for reverse calculation
- Add comprehensive test for Issue #36 scenario
- Ensure fractional_beat values are calculated correctly for trajectory analysis

Resolves fractional_beat=0.0 clamping issue that affected musical time analysis
and trajectory curve visualization in multi-cycle meters with timing variations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jon-myers
Copy link
Contributor Author

@claude review

@claude
Copy link
Contributor

claude bot commented Sep 10, 2025

Claude finished @jon-myers's task —— View job


Code Review for PR #37: Fix hierarchical position calculation bug

Review Tasks:

  • Read and analyze changes in idtap/classes/meter.py
  • Review test implementation in idtap/tests/musical_time_test.py
  • Evaluate code quality and best practices
  • Check for potential bugs or edge cases
  • Assess performance considerations
  • Review security concerns
  • Evaluate test coverage

✅ Review Complete - Overall Assessment: EXCELLENT

This is a well-implemented fix that addresses a critical bug in the hierarchical position calculation. The implementation demonstrates careful analysis of the root cause and provides a robust solution.

🎯 Strengths

1. Root Cause Analysis & Fix Quality

  • Precise Problem Identification: The fix correctly identifies that the hierarchical position calculation sometimes points to pulses after the query time (idtap/classes/meter.py:613)
  • Elegant Solution: The backward-walking algorithm (lines 615-618) is simple and effective
  • Consistency Maintenance: Updates hierarchical positions to match the corrected pulse (line 623) ensuring internal consistency

2. Code Quality

  • Clear Documentation: Excellent inline comments explaining the fix logic (lines 611-623)
  • Defensive Programming: Proper bounds checking before the correction loop (corrected_pulse_index > 0)
  • Non-Breaking: The fix only activates when needed - existing correct behavior is preserved

3. Testing

  • Comprehensive Test Case: test_issue_36_hierarchical_position_correction() creates realistic conditions that would trigger the bug
  • Smart Test Strategy: Uses timing variations (pulse.real_time += 0.05) to simulate real-world conditions
  • Good Assertions: Validates both the fractional_beat range and that calculated pulses come at/before query time

🔧 Technical Implementation Review

New Method: _pulse_index_to_hierarchical_position() (lines 475-503)

  • ✅ Correct reverse calculation of hierarchical positions from pulse index
  • ✅ Proper handling of cycle offsets and hierarchy traversal
  • ✅ Consistent with existing _hierarchical_position_to_pulse_index() method

Bug Fix Logic (lines 611-623)

  • ✅ Condition check current_pulse_time > real_time correctly identifies the problem
  • ✅ Backward search ensures finding the right pulse
  • ✅ Position recalculation maintains consistency between pulse and hierarchical position

Minor Improvement (line 583)

  • ✅ Removed unused level variable - good cleanup

🚀 Performance Considerations

  • Minimal Impact: Fix only executes when bug condition is detected
  • Efficient Search: Backward walk is O(k) where k is typically small (few pulses)
  • No Breaking Changes: Existing correct paths unchanged

🔒 Security & Reliability

  • Bounds Safety: Proper checking prevents array out-of-bounds
  • Data Integrity: Maintains consistency between related data structures
  • No Side Effects: Fix is isolated and doesn't affect other functionality

🧪 Test Coverage Assessment

  • Targeted Testing: Test specifically reproduces the conditions that cause the bug
  • Edge Case Coverage: Tests multiple time points and timing variations
  • Regression Protection: Ensures fix doesn't break existing functionality (344 tests still pass)

🎵 Domain-Specific Correctness

  • Musical Logic: Fix ensures fractional_beat values represent actual position within pulse intervals
  • Timing Accuracy: Critical for trajectory curve visualization and transcription analysis
  • Multi-Cycle Support: Properly handles complex meter structures in Hindustani music

🏆 Best Practices Demonstrated

  1. Problem-Solution Traceability: Clear connection between issue description and implementation
  2. Defensive Coding: Multiple safety checks and bounds validation
  3. Test-Driven Approach: Comprehensive test case that would fail without the fix
  4. Documentation: Clear comments explaining the why, not just the what
  5. Minimal Change Principle: Surgically addresses the specific issue without unnecessary modifications

📋 Minor Suggestions (Non-blocking)

  • Consider adding a debug log when the correction path is taken to aid future debugging
  • The _pulse_index_to_hierarchical_position() method could potentially be optimized for repeated calls, but current implementation is fine

🎉 Recommendation: APPROVE

This PR exemplifies excellent software engineering practices:

  • Accurate problem diagnosis
  • Elegant, minimal solution
  • Comprehensive testing
  • Clear documentation
  • Maintains backward compatibility

The fix will resolve trajectory curve visualization issues and ensure accurate musical time analysis across all meter types. Great work!

@github-actions
Copy link
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.

@jon-myers jon-myers merged commit 0312187 into main Sep 10, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: fractional_beat incorrect for multi-cycle meters (hierarchical position calculation)

1 participant