Remove the PhiDP system phase offset before Bringi KDP processing - #136
Merged
Merged
Conversation
The BNF C-SAPR2 raw differential phase sits on a system phase offset of roughly 220 degrees. The bringi branch passed it to csu_kdp unchanged, so corrected_differential_phase kept the offset, and Py-ART's _prepare_phidp smeared it along each ray with np.maximum.accumulate. Z-PHI then read that plateau as propagation phase: the self consistency number came out at 10.34 instead of order 0.05 to 0.2, and the reflectivity fed to the integral was inflated by about 16 dB. The result was specific differential attenuation up to 2.2 dB/km, roughly 20 times the physical C-band value, with radial streaking where the plateau differed between adjacent rays. Estimate the offset and subtract it, undoing the 0-360 fold in the same step, before calling calc_kdp_bringi. get_sys_phase takes the median over the first meteorological gates of each ray then the median across rays; Py-ART's estimators take a per-ray minimum, which sits well below the true offset when PhiDP noise is order 30 degrees, and both raise IndexError on the BNF RHI files whose sweep_end_ray_index disagrees with the ray count. They are kept as fallbacks. The value used is recorded as a system_phase_offset attribute and can be pinned with the new phidp_sys_phase configuration key. On bnfcsapr2cfrS3.a1.20250520.000009 at 3.5 degrees this takes corrected_differential_phase from 196..257 to -26..36 degrees, ADP max from 2.206 to 0.100 dB/km, and PIDA max from 4.639 to 0.543 dB. Two related corrections: Py-ART's field metadata carries valid_min/valid_max on specific_attenuation but none on specific_differential_attenuation, so AH above the cap was silently masked on read while the ADP derived from that same AH survived, leaving the pair disagreeing by over a thousand gates. Set both, deriving the ADP bound from the AH bound through the same ADP = c * AH ** d relation. calculate_attenuation_zphi defaults to temp_ref='temperature', so the iso0_field argument was silently ignored and the melting layer came from a sounding_temperature copy whose masked gates had been filled with +9999 degC, marking the entire ice region as liquid. Pass temp_ref explicitly and drop the fill. This changes the melting layer mask on 26 percent of gates volume wide but no output gates, since those gates are already excluded by phase_proc_gates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
zssherman
approved these changes
Sep 10, 2026
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.
The phase calculations using Bringi's technique were not being adjusted by the system phase and unfolded first, which was causing some radial artifacts in the outputs. This PR mitigates these artifacts.
Written with Claude Opus 5's help.