Skip to content

Conversation

@connorhough
Copy link
Collaborator

@connorhough connorhough commented Dec 31, 2025

Overview

This PR introduces a phase unwrapping mechanism to the EclipsingBinaryBinner to resolve issues where eclipses crossing the phase boundary ([0, 1]) were incorrectly binned. By shifting
phases during initialization, we ensure that both primary and secondary eclipses are contiguous in phase space before any binning logic is applied.

Key Changes

  • Automatic Unwrapping: Modified init to detect wrapped eclipses (start > end) and apply a calculated phase shift to all data points.
  • Unified Binning Logic: Simplified calculate_eclipse_bins and calculate_out_of_eclipse_bins by removing complex wrapping-aware slicing. All binning now occurs in a guaranteed
    unwrapped phase space.
  • Transparent Rewrapping: Results (bin centers and edges) are automatically rewrapped to the original [0, 1] phase space by default, maintaining backward compatibility.
  • Robustness Improvements:
    • Added duplicates='drop' to pd.qcut calls to handle edge cases with duplicate bin edges.
    • Implemented a graceful degradation tolerance (2%) for bin count differences.
    • Added a final deduplication step in calculate_bins for region boundaries.
  • Visualization: Updated plotting methods (plot_binned_light_curve and plot_unbinned_light_curve) to rewrap data back to the original phase space for display.

Testing & Verification

  • New Tests: Added test_detect_phase_wrapping, test_primary_wrapped_eclipse, and test_both_eclipses_near_boundary to verify various wrapping scenarios.

Add _detect_wrapped_eclipse and _calculate_unwrap_shift methods to detect
and handle eclipses that wrap around the phase 0/1 boundary. Includes test
to verify detection of wrapped secondary eclipse.
- Modified __init__ to detect and unwrap wrapped eclipses at initialization
- Added _unwrap_phases() method to apply phase shift and re-sort data
- Improved _calculate_unwrap_shift() to properly unwrap eclipses without wrapping the other
- Recalculate eclipse boundaries in unwrapped phase space
- All eclipse detection and binning now happens in unwrapped phase space

This eliminates the numerical discontinuity problem when eclipses cross the 0/1 phase boundary.
Replaces shift_bin_edges with _rewrap_to_original_phase method.

- Add _rewrap_to_original_phase() to reverse unwrapping
- Update calculate_bins() to use rewrapping with return_in_original_phase parameter
- Perform binning in unwrapped space, optionally return in original space
- Fix bin count checking logic (np.any instead of np.all)
- Add minlength parameter to bincount for correct sizing

This is a cleaner approach than the old shift_bin_edges which shifted
bins so the rightmost edge = 1.0 and created shifted_phases in data dict.
- Update plot_binned_light_curve to use _rewrap_to_original_phase for eclipse boundaries
- Update plot_unbinned_light_curve to rewrap phases and boundaries for display
- Remove use_shifted_phases parameter from all methods:
  - find_minimum_flux_phase
  - find_secondary_minimum_phase
  - get_eclipse_boundaries
  - _find_eclipse_boundaries
  - _find_eclipse_boundary
  - _helper_secondary_minimum_mask
- Simplify all methods to work only with unwrapped phases
- Eclipse boundaries stored in unwrapped space, rewrapped for plotting
- Update helper_eclipse_detection to expect proper ordering for all eclipses after unwrapping
- Simplify helper_find_eclipse_minima by using direct property access
- Remove helper_shift_bins test helper (no longer needed)
- Remove calls to shift_bin_edges and use_shifted_phases (deprecated)
- Update test calls to pass None for wrapped parameter (kept for compatibility)
- Add tests for primary wrapped eclipse and both eclipses near boundaries
- Update CLAUDE.md with phase unwrapping documentation
- Fix duplicate bin edge issues by adding duplicates='drop' to pd.qcut calls
- Add final deduplication step in calculate_bins to handle boundary duplicates
- Allow graceful degradation tolerance (2%) for bin count differences
- Skip pathological parameter combinations (high nbins + low fraction_in_eclipse)
- Ensure unique bin edges before passing to scipy.stats.binned_statistic
- Format eclipsebin/binning.py and tests/test_eclipsing_binary_binner.py with black
- Remove temporary verification scripts created during development
- Add .venv/ to .gitignore to prevent accidental commits
@jackieblaum jackieblaum merged commit 3401f98 into main Jan 4, 2026
8 checks 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.

3 participants