Skip to content

AnaCal ingestion - #446

Open
empEvil wants to merge 78 commits into
masterfrom
AnaCal_ingestion
Open

AnaCal ingestion#446
empEvil wants to merge 78 commits into
masterfrom
AnaCal_ingestion

Conversation

@empEvil

@empEvil empEvil commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

This is a pull request for ingesting the DP2 version of AnaCal. currently it is ingesting a DP1 version of the catalog

@mr-superonion

Copy link
Copy Markdown

It seems that i do not have permission to modify the pr here; therefore i opened a pr to correct for some bugs/typo in this pr:
#482

mr-superonion and others added 3 commits July 14, 2026 23:41
Two equivalent bookkeeping conventions give an unbiased shear:

  (A) <e> = Σ(wsel·e) / N
      R   = Σ(de/dg·wsel + dw/dg·e) / N
      → R_sel normalized by count.

  (B) <e> = Σ(wsel·e) / N / <wsel>
      R   = Σ(de/dg·wsel + dw/dg·e) / N / <wsel>
      → R_sel normalized by sum(wsel).

The rest of the code — R_shape, R_weight, and every mean-e
computation — uses convention (B), so R_sel must match with a
sum_weights denominator, not count.

Also: nanojansky_err_to_mag_ab returns NaN for flux <= 0 via
np.divide(where=flux>0) instead of producing negative sigma_mag
and RuntimeWarnings.
@joezuntz

Copy link
Copy Markdown
Collaborator

@mr-superonion I've added you to the team that gives you permissions for future things.

   as a second stage after ingest, with a matching config.yml block:
   delta_gamma: 0.01, mask_threshold: 40, s2n_cut: 5.0, T_cut: 0.1,
   5-bin source_zbin_edges, input_pz: true.
2. Ingested photo-z point estimates. TXIngestAnacal now reads
   zmode_{0,1p,1m,2p,2m} from the merged catalog and exposes them on the
   shear catalog as mean_z, mean_z_{1p,1m,2p,2m} — baseline for
   tomographic binning, the four variants for the R_sel bin-migration
   term.
3. Built ±γ variants of every quantity the selector cuts on. In
   TXSourceSelectorAnaCal.apply_simple_redshift_cut, injected
   s2n_{1p,1m,2p,2m} = s2n ± δγ · ds2n_dg{1,2}, and analogous variants
   of m00, m20 (from dm00_dg, dm20_dg) and zbin (from mean_z_*). All
   four cut quantities now respond to shear via a single uniform
   injection step.
4. Unified the calculator's cut logic under _DataWrapper. Deleted the
   ad-hoc get_submask size-cut machinery in AnaCalCalculator.add_data.
   The selector now applies mask + s2n + size + zbin in one place; the
   calculator just runs the same selector on five wrappers (baseline +
   _1p/_1m/_2p/_2m), and the wrapper's suffix-lookup routes the shifted
   columns automatically. AnaCalCalculator.__init__ dropped its
   mask_threshold argument as a consequence.
5. Consistent response formulae. Rewrote R_shape, R_weight, R_sel_{1,2}
   in the calculator so all three share the same code shape: Σ(w · X) /
   sum_weights for R_shape and R_weight, and [Σ(w·e)|sel_+ −
   Σ(w·e)|sel_−] / (2 δγ · sum_weights) for R_sel. R_shape switched from
   a ParallelMean to a plain scalar sum for parity; det_response_*
   renamed to weight_response_* to match the "R_weight" label; a small
   _reduce helper replaced 30 lines of MPI reduce boilerplate.
6. Promoted the size threshold to config. The AnaCal size cut,
   previously hard-coded as (m00 + m20) / m00 > 0.1, is now > T_cut —
   driven by the base selector's T_cut config option that was previously
   unused for AnaCal. TXSourceSelectorAnaCal.config_options gives it a
   default of 0.1 alongside a new s2n_cut default of 5.0, so a minimal
   yaml block still runs; both can be overridden in the yaml for
   tighter/looser cuts.

@mr-superonion mr-superonion left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a few update to include the selection bias correction for s2n and add selection stage into the example. I will check over the dp1 data to see whether i can get consistent result to the hsc code.

Comment thread txpipe/source_selection/anacal.py Outdated
pz_data["s2n_1m"] = s2n - dg * shear_data["ds2n_dg1"]
pz_data["s2n_2p"] = s2n + dg * shear_data["ds2n_dg2"]
pz_data["s2n_2m"] = s2n - dg * shear_data["ds2n_dg2"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is the code to create shifted columns for s2n.

Comment thread txpipe/source_selection/Anacal.py Outdated
shear_cols += ["mean_z"]
# Baseline photo-z + the four shifted variants used to derive
# zbin_{1p,1m,2p,2m} for the selection-response calculation.
shear_cols += ["mean_z", "mean_z_1p", "mean_z_1m", "mean_z_2p", "mean_z_2m"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we need columns for the shifted redshifts to get the selection bias due to the binning.

data_1p = _DataWrapper(data, "_1p")
data_1m = _DataWrapper(data, "_1m")
data_2p = _DataWrapper(data, "_2p")
data_2m = _DataWrapper(data, "_2m")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data wrapper is used here to get different shifted version of the catalog

The indicies of the objects selected from this chunk of data
"""
data = _DataWrapper(data, "")
select = self.selector(data, *args, **kwargs)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the explanation

  1. i am implementing it here (e112dea#r3592442390) to create s2n_1p, s2n_1m, s2n_2p, s2n_2m
  2. then the data wrapper is used here (e112dea#r3592459804) to create different shifted version

# (zmode_{1p,1m,2p,2m}) in xlens' photoZPipe (currently ±0.01 in
# DISTORTIONS).
delta_gamma: 0.01

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i add the selection stage in the example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we don't want to run them at the same time. Sadly from how things are set up on NERSC, we want to run the ingestion stage in one environment and then the rest of the pipeline should be run in a dedicated environment for TXPipe. But we want to be able to run the Selection stage later, where we might be able to use different photo-z's for example

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the comment and i have separated the ingestion from the rest of the task in the examples folder (see commit a21049e)

@empEvil

empEvil commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@mr-superonion Thank you for the additions, I however do not think we should move away from parallel mean if we can avoid it! I am a little confused about what has been moved from the calibration stage to the source-selection, and why?

empEvil and others added 3 commits July 16, 2026 14:38
2. use consistent definition with paper e_mea = e_raw * wsel and g=
   e_mea / R_total wher <R_total> = sum (R_shape + R_detect) / Ngal +
   R_sel; and weight is set to 1. This ensures that treecorr get the
   correct correlation <e_mea_a e_mea_b> / <R_total>^2
@mr-superonion

mr-superonion commented Jul 17, 2026

Copy link
Copy Markdown

Hi @empEvil , thanks for your comments:

I however do not think we should move away from parallel mean if we can avoid it!

Yes. good point and i revert it back to use parallel for all the average computations for shear responses.

I am a little confused about what has been moved from the calibration stage to the source-selection, and why?

my understanding is that the selection was applied twice: once in the selector (for mask_value and s2n cut), once again in the calculator (for trace cut). The trace cut's shear response was computed; however the s2n cut's selection shear response was not included.

My update puts all the code to create sheared variant columns into the selection stage (including variants for s2n, trace and redshift bins). The selection for different sheared variants are in calculator to compute the selection shear response using the shear variant columns provided by the selector.

I think this makes it easy to maintain since all the shear variants preparation code is in one function (#446 (comment)) and we can use the existing wrapper for the selection response calculation following the suggestion: #446 (comment)

zbin variants are only produced under ``input_pz`` (truth-z has no
shear response); s2n and moment variants are always emitted since
the selector applies those cuts in every mode.
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the function to add sheared variant columns that are used to compute selection bias

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds end-to-end support for ingesting and calibrating DP2-style AnaCal shear catalogs in TXPipe, including a new ingest stage, a source selector/tomography stage, and a corresponding shear calibration calculator/calibrator.

Changes:

  • Added a new AnaCal ingest stage that reads merged AnaCal outputs and writes a TXPipe-format shear catalog.
  • Added an AnaCal source selector that builds ±γ selection variants and computes AnaCal calibration statistics.
  • Added AnaCal calibration plumbing (calculator + calibrator), plus tests and example pipelines/config.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
txpipe/utils/conversion.py Makes magnitude-error conversion robust to non-positive flux values.
txpipe/utils/init.py Reformats conversion imports (no behavior change).
txpipe/test/test_cal.py Adds unit tests covering AnaCalCalculator response accumulation behavior.
txpipe/source_selection/anacal.py Introduces AnaCal-specific source selection, shear-variant injection, and response output wiring.
txpipe/source_selection/init.py Exposes TXSourceSelectorAnacal from the package.
txpipe/shear_calibration/calibrators.py Adds AnaCalibrator and registers it in Calibrator.load.
txpipe/shear_calibration/calibration_calculators.py Adds AnaCalCalculator implementation.
txpipe/shear_calibration/init.py Re-exports AnaCalCalibrator/AnaCalCalculator.
txpipe/ingest/dp1_details.py Adds DP1 tract/field constants used by ingest selection.
txpipe/ingest/anacal.py Adds TXIngestAnacal stage to ingest AnaCal merged catalogs into TXPipe HDF5.
txpipe/ingest/init.py Exposes TXIngestAnacal from the ingest package.
txpipe/data_types.py Adds primary shear-column mapping for catalog_type == "anacal".
txpipe/calibrate.py Adds calibrate-stage dispatch for catalog_type == "anacal".
txpipe/init.py Exposes TXSourceSelectorAnacal from top-level txpipe.
examples/anacal/pipeline.yml Adds an example pipeline running the AnaCal source selector.
examples/anacal/ingest.yml Adds an example pipeline running only AnaCal ingest.
examples/anacal/config.yml Adds an example config for AnaCal ingest + selection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +638 to +644
def __init__(self, R, mu, mu_is_weighted=True):
self.R = R
if mu_is_weighted:
self.mu = np.array(mu)
else:
self.mu = np.array(mu) / R
assert("Anacal needs an already calibrated mu.")
Comment on lines +661 to +667
if not subtract_mean:
g1, g2 = weights * [g1, g2] / self.R
elif np.isscalar(g1):
g1, g2 = weights * [g1, g2] / self.R - self.mu
else:
g1, g2 = weights * [g1, g2] / self.R - self.mu[:, np.newaxis]
return g1, g2
Comment on lines +208 to +213
outfile = super().setup_output()
n = outfile["tomography/bin"].size
group = outfile.create_group("response")
group.create_dataset("R", (n, 1, 1), dtype="f")
group.create_dataset("R_2d", (1,), dtype="f")
return outfile
Comment on lines +230 to +234
def write_tomography(self, outfile, start, end, source_bin, r):
super().write_tomography(outfile, start, end, source_bin, r)
group = outfile["response"]
group["R"][start:end] = r

Comment thread txpipe/ingest/anacal.py
Comment on lines +172 to +178
print("Trimming shear columns:")
for col in shear_data.keys():
print(" ", col)
h5py_shorten(shear_outfile["shear"], col, shear_end)

shear_outfile.close()

@empEvil

empEvil commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

So I noticed we are still not ingesting g1/g2 and T for the PSF? @mr-superonion you added those to the catalog right?

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.

4 participants