Pure E/B: fixed-quadrature operator with exact covariance - #373
Merged
Merged
Conversation
The pure-E/B estimator is one data-independent matrix K = (I_6 ⊗ P)·M on the fine ξ± grid: the Schneider (2022) transform with fixed Gauss-Legendre weights (cosmo-numba get_pure_EB_operator), evaluated at the fine nodes inside the reporting range with [tmin, tmax] at the fine-grid extent, then averaged into the reporting bins with pair-count weights. Its covariance is K C_ξ Kᵀ, exact for an analytic or a jackknife ξ± covariance; `npatch` travels with the results (None for analytic) and sets the Hartlap factor of every χ² built on them, with the combined ξ+/ξ− χ² debiased over its full length. calculate_pure_eb_correlation works from fine-grid arrays; the reported ξ±, θ and variances are the same pair-count average, so ξ± = E ± B + amb holds bin by bin. The adaptive pointwise path, the Monte-Carlo covariance and the separate pure-E/B jackknife are removed. sacc_io gains get_xi_npairs; cosmo-numba is pinned to the fork commit carrying the operator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rule reads only the integration-grid ξ± part (with its pair counts) and the CosmoCov ξ± covariance on that grid, and calls calculate_pure_eb_correlation. The Monte-Carlo parameters and the reporting-part input go; the covariance takes seconds, so the rule's threads and runtime shrink. The summary labels the covariance from the npz's npatch record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…chunks
pure_eb_modes.py replaces the chunk scatter/gather (precompute_pure_eb_chunk,
gather_pure_eb_chunks): one call to calculate_pure_eb_correlation on the
fine ξ± and its Gaussian covariance, written to {version}_pure_eb.npz.
The PTE and data-vector scripts drop the MC Hartlap factor, the n(z)
covariance comparison drops its MC-noise band, and the n_samples /
n_chunks config keys go.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TreeCorr's ξ± and meanr in a bin are averages over pairs weighted by w_i w_j, so pooling fine bins with their `weight` reproduces the reporting-bin measurement exactly when the fine edges nest the reporting edges; npairs does so only for an unweighted catalogue. The operator, calculate_pure_eb_correlation, the mixin, cv_pure_eb and pure_eb_modes.py take `weight_int`; sacc_io.get_xi_npairs becomes get_xi_weight (parts already carry the tag). A new test checks the nesting identity on a weighted catalogue with exact binning; the fixture and operator pins are regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Assigning fine bins to reporting bins by meanr sends a fine bin that straddles a reporting edge wholly to one side, so P cannot reproduce TreeCorr's pair average there. The library now takes the fine-grid edges, snaps each requested reporting edge to the nearest fine edge, pools whole fine bins, and returns the edges it used; the results' left/right edges, the pure-E/B npz and the B-mode summary carry those snapped edges. Edges that snap together or reach outside the fine grid raise. Callers pass the fine edges: the mixin from gg_int's edges, cv_pure_eb and pure_eb_modes.py from the integration grid spec. The reproduction test now covers requested edges that do not nest, measuring each snapped bin directly with exact binning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pure-E/B PTE intermediate now carries the reporting edges its matrices are indexed on, and config_space_pte_matrices resolves the fiducial windows on them rather than on a nominal geomspace grid. A PTE file that records no edges was binned on the nominal grid, which stays its window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e node cosmo-numba's get_pure_EB_operator (schneider2022, local_from_int=True) now builds the fixed-quadrature transform. It is evaluated at every fine node: the zero-padded ξ− window extends from the evaluation grid, so this keeps the transform a function of the fine grid alone. P then selects its rows; NaN rows at the grid edges are dropped first and only a NaN row that P uses raises. The new operator clamps a θ-dependent integration limit to the interpolator's extrapolation bound, as the reference does, where the previous pin extrapolated the stencil polynomial; the operator pins move accordingly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exact containment on snapped reporting edges makes a cut placed on a nominal edge select different bins on different fine grids: [12, 83]′ gave bins 9–15 on a 0.5–300′ grid but 9–14 on cosmo_val's 0.08–300′ one. bins_from_scale_cut snaps each end of a cut to the nearest reporting edge in log θ, the rule the edges themselves were snapped by, so the same cut selects the same bins on every grid. _get_pte_from_scale_cut (hence the B-mode summaries), the pure-E/B plots and papers/bmodes config_space_pte_matrices use it; COSEBIs keep bins_from_edges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cosmo-numba's interpolator places its samples on a regular grid in log θ, so handing it TreeCorr meanr put every sample at its nominal position while the evaluation limit sat at the true meanr; where a spacing exceeded the mean step the limit fell past the extrapolation bound, and the old and new cosmo-numba operators resolved that knife-edge differently. The transform now runs on the geometric centres of the log-uniform fine edges (TreeCorr rnom) and is evaluated there; meanr enters only the reported θ. The edges are checked to be log-uniform, and pure_eb_operator no longer takes theta_int. On rnom the d78a189 and a64cb2e operators agree to round-off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cailmdaley
added a commit
that referenced
this pull request
Oct 2, 2026
Pure E/B takes #373's design: one fixed linear operator on the integration-grid ξ± part with covariance K C Kᵀ; the MC covariance and the chunked precompute go. The blinding stays: cv_pure_eb and calculate_pure_eb read the sealed integration part through sacc_io.xi_correlation (which carries the pair weights, so get_xi_weight is not added), and the pure-E/B part is saved derived_from that part. papers/bmodes/pure_eb_modes.py reads the SACC part; the B-mode blinding test uses the operator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What. The pure-E/B estimator becomes one data-independent matrix on the fine ξ± grid,
K = (I₆⊗P)·M.get_pure_EB_operator), evaluated at every fine node on the regular log grid (TreeCorr rnom) with [tmin, tmax] at their extent.K C_ξ Kᵀfor any ξ± covariance: an analytic one, or the fine-grid jackknife from TreeCorr. The results carrynpatch(None = analytic), which sets the Hartlap factor in every χ²/PTE.Why. The adaptive dqags quadrature chooses its subdivision from the data, so the old estimator was weakly non-linear and its quadrature error rectified noise into spurious B-modes. A fixed rule makes it exactly linear, so the covariance is exact and needs no Monte Carlo. Pooling whole fine bins with the pair weight reproduces what TreeCorr measures on the snapped bins, so ξ± = E ± B + amb holds bin by bin.
Removed.
pure_eb_from_xi(adaptive, pointwise),pure_eb_covariance_mcand its n_samples/chunk plumbing, the separate pure-E/B jackknife, and papers/bmodesprecompute_pure_eb_chunk/gather_pure_eb_chunks(replaced bypure_eb_modes.py).cv_pure_ebnow reads only the integration part.Verified.
Downstream.
cailmdaley/cosmo-numba@a64cb2e(fixed-quadrature + covariance branches, to be proposed upstream to aguinot/cosmo-numba).bins_from_scale_cut), so a cut selects the same bins on every fine grid; COSEBIs keepbins_from_edges.🤖 Generated with Claude Code