"""Shared configuration for the Sickle photometry benchmark. Scope: NIRCam module B only (nrcb1-4 for SW, nrcb5 for LW), 5 filters. """ from pathlib import Path SICKLE_ROOT = Path("/orange/adamginsburg/jwst/sickle") BENCHMARK_ROOT = SICKLE_ROOT / "benchmark" # Tool root directories TOOL_DIRS = { "dolphot": BENCHMARK_ROOT / "dolphot", "crowdsource": BENCHMARK_ROOT / "crowdsource", "starbugii": BENCHMARK_ROOT / "starbugii", "photutils_iter1": BENCHMARK_ROOT / "photutils_iter1", "photutils_iter2": BENCHMARK_ROOT / "photutils_iter2", "photutils_iter3": BENCHMARK_ROOT / "photutils_iter3", } # Level-3 mosaics on NRCB (one per filter, combines all detectors in module B) MOSAICS = { "F187N": SICKLE_ROOT / "F187N" / "pipeline" / "jw03958-o007_t001_nircam_clear-f187n-nrcb_i2d.fits", "F210M": SICKLE_ROOT / "F210M" / "pipeline" / "jw03958-o007_t001_nircam_clear-f210m-nrcb_i2d.fits", "F335M": SICKLE_ROOT / "F335M" / "pipeline" / "jw03958-o007_t001_nircam_clear-f335m-nrcb_i2d.fits", "F470N": SICKLE_ROOT / "F470N" / "pipeline" / "jw03958-o007_t001_nircam_clear-f470n-nrcb_i2d.fits", "F480M": SICKLE_ROOT / "F480M" / "pipeline" / "jw03958-o007_t001_nircam_clear-f480m-nrcb_i2d.fits", } FILTERS = list(MOSAICS.keys()) # Short-wavelength filters use NRCB1-4, long-wavelength use NRCB5 SW_FILTERS = {"F187N", "F210M"} LW_FILTERS = {"F335M", "F470N", "F480M"} # NRCB detectors per filter def detectors(filt: str) -> list[str]: if filt in SW_FILTERS: return ["nrcb1", "nrcb2", "nrcb3", "nrcb4"] return ["nrcb5"] # NIRCam pixel scale (arcsec/pix) — SW ~0.031, LW ~0.063 PIXSCALE = { "F187N": 0.031, "F210M": 0.031, "F335M": 0.063, "F470N": 0.063, "F480M": 0.063, } # Approx FWHM in pixels for each filter (from STScI NIRCam docs, PSF FWHM / pixscale) # Band-merge matching radius defaults to half the smallest FWHM across filters. FWHM_ARCSEC = { "F187N": 0.066, "F210M": 0.071, "F335M": 0.111, "F470N": 0.153, "F480M": 0.162, } def fwhm_pix(filt: str) -> float: return FWHM_ARCSEC[filt] / PIXSCALE[filt] # Cross-matching radius (arcsec) for cross-tool and band-merge MATCH_RADIUS_ARCSEC = 0.08 # ~half the worst FWHM; conservative # Per-exposure _cal.fits globs (for DOLPHOT and any other per-exposure tool) def cal_glob(filt: str) -> str: # nrcb1-4 for SW, nrcb5 for LW dets = "|".join(detectors(filt)) return str(SICKLE_ROOT / filt / "pipeline" / "jw03958007001_*_nrcb*_cal.fits") # Map tool name -> TOOL_DIRS key (some tools have a different package name) _DIR_ALIAS = {"starbug2": "starbugii"} def _tool_dir(tool: str) -> Path: return TOOL_DIRS[_DIR_ALIAS.get(tool, tool)] # Where tools drop their catalogs def tool_catalog_dir(tool: str) -> Path: return _tool_dir(tool) / "catalogs" # Final band-merged catalog per tool def tool_bandmerged(tool: str) -> Path: return _tool_dir(tool) / "bandmerged" / f"{tool}_bandmerged_nrcb.fits" # Existing photutils iter3 cross-filter merged catalog (the "our pipeline" reference) # Lives in SICKLE_ROOT/catalogs; merge_catalogs.py --iteration-label=iter3 is what writes it. # Conventional filename guess (verify before use): PHOTUTILS_ITER3_MERGED = SICKLE_ROOT / "catalogs" / "iterative_iter3_merged_indivexp_photometry_tables_merged.fits" ASTROMETRY_REF = SICKLE_ROOT / "catalogs" / "crowdsource_based_nircam-f405n_reference_astrometric_catalog.fits" # Logs LOG_ROOT = Path("/blue/adamginsburg/adamginsburg/logs/sickle_benchmark")