1.0 — ECDFS spec-z sample and golden catalog match¶
Authors: Xiangchong Li, Tianqing Zhang, Eric Charles, Sam Schmidt
LSST Science Pipelines: Weekly 2025_49
Kernel: Python-dp1
Purpose¶
End-to-end preparation of the DP1 ECDFS spec-z + shape training/test sample, plus quick sky-coverage diagnostics for the other DP1 fields.
Steps¶
- Read the spec-z parquet
comcam_ecdfs_redshift_catalog_20250618.parquetand the AnaCal shape cataloganacal_catalog_ecdfs.fits. - Overlay
(RA, Dec)of both as a scatter plot — measurement (blue) vs. spec-z (red) — to show field coverage. - Sky-match within 0.75 arcsec using
utils.sky_match, append the four spec-z columns (redshift,confidence,type,source) to the measurement table viautils.append_specz_columns. - Apply the basic golden selection (
utils.golden_selection): per-band magnitude cuts + trace > 0.10 + spec-z confidence > 0.82. - Write
rail_training/match.fitscontaining only matched + golden rows (every original AnaCal column + the four appended spec-z columns) — this is the input for thescripts_pz/step2_prepare_train_test.pytrain/test split. - Additional
(RA, Dec)scatter plots for the Abell 360 and EDFS measurement catalogs.
Inputs¶
specz/comcam_ecdfs_redshift_catalog_20250618.parquetcatalogs/anacal_catalog_ecdfs.fitscatalogs/anacal_catalog_a360.fitscatalogs/anacal_catalog_edfs.fitsutils/(local importable package; wrapsspecz/match.py)
Outputs¶
rail_training/match.fits— matched + golden sample.- Three inline scatter figures (ECDFS, Abell 360, EDFS).
In [1]:
import numpy as np
import tables_io
from astropy.table import Table
import matplotlib.pyplot as plt
In [2]:
specz_path = "/gpfs/mnt/gpfs02/astro/workarea/xli6/work/DP1/specz/comcam_ecdfs_redshift_catalog_20250618.parquet"
meas_path = "/gpfs/mnt/gpfs02/astro/workarea/xli6/work/DP1/catalogs/anacal_catalog_ecdfs.fits"
specz = tables_io.read(specz_path, tType="astropyTable")
meas = Table.read(meas_path)
print(f"spec-z catalog : {len(specz):,} rows")
print(f"measurement catalog : {len(meas):,} rows")
column_list None
spec-z catalog : 104,078 rows measurement catalog : 128,542 rows
In [3]:
fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(
np.asarray(meas["ra"]), np.asarray(meas["dec"]),
s=2, alpha=0.25, color="C0",
label=f"measurement ({len(meas):,})",
)
ax.scatter(
np.asarray(specz["RA"]), np.asarray(specz["DEC"]),
s=6, alpha=0.7, color="C3",
label=f"spec-z ({len(specz):,})",
)
ax.set_xlabel("RA [deg]")
ax.set_ylabel("Dec [deg]")
ax.set_title("ECDFS spec-z sample vs. measurement catalog")
ax.legend(loc="best", frameon=False)
ax.set_aspect("equal")
ax.grid(True, alpha=0.25)
fig.tight_layout()
Match spec-z to measurement catalog¶
Sky-match within 0.75 arcsec, append the four spec-z columns
(redshift, confidence, type, source), apply the basic golden
selection (per-band mag cuts + trace + confidence > 0.9), and write a
new matched catalog.
In [4]:
from utils import sky_match, append_specz_columns, golden_selection
idx, sepcheck = sky_match(meas, specz)
append_specz_columns(meas, specz, idx)
In [5]:
sel = golden_selection(meas, sepcheck)
print(f"matched: {int(sepcheck.sum()):,} / {len(meas):,}")
print(f"+ basic selection (mag/trace/conf): {int(sel.sum()):,} / {len(meas):,}")
matched: 14,174 / 128,542 + basic selection (mag/trace/conf): 8,314 / 128,542
In [ ]:
import os
# Keep only matched + basic-selection rows; carry every original column plus
# the four new spec-z columns. Lands in rail_training/ alongside the train/test
# split inputs.
matched_dir = "/gpfs/mnt/gpfs02/astro/workarea/xli6/work/DP1/rail_training"
os.makedirs(matched_dir, exist_ok=True)
matched_path = os.path.join(matched_dir, "match.fits")
meas[sel].write(matched_path, overwrite=True)
print(f"wrote {matched_path} ({int(sel.sum()):,} rows)")
Other-field sky coverage¶
Quick (ra, dec) scatter for the two other measurement catalogs:
Abell 360 and EDFS.
In [7]:
a360 = Table.read(
"/gpfs/mnt/gpfs02/astro/workarea/xli6/work/DP1/catalogs/anacal_catalog_a360.fits"
)
print(f"a360 catalog: {len(a360):,} rows")
fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(
np.asarray(a360["ra"]), np.asarray(a360["dec"]),
s=2, alpha=0.25, color="C2",
label=f"a360 ({len(a360):,})",
)
ax.set_xlabel("RA [deg]")
ax.set_ylabel("Dec [deg]")
ax.set_title("Abell 360 measurement catalog")
ax.legend(loc="best", frameon=False)
ax.set_aspect("equal")
ax.grid(True, alpha=0.25)
fig.tight_layout()
a360 catalog: 113,945 rows
In [8]:
edfs = Table.read(
"/gpfs/mnt/gpfs02/astro/workarea/xli6/work/DP1/catalogs/anacal_catalog_edfs.fits"
)
print(f"edfs catalog: {len(edfs):,} rows")
fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(
np.asarray(edfs["ra"]), np.asarray(edfs["dec"]),
s=2, alpha=0.25, color="C4",
label=f"edfs ({len(edfs):,})",
)
ax.set_xlabel("RA [deg]")
ax.set_ylabel("Dec [deg]")
ax.set_title("EDFS measurement catalog")
ax.legend(loc="best", frameon=False)
ax.set_aspect("equal")
ax.grid(True, alpha=0.25)
fig.tight_layout()
edfs catalog: 89,354 rows