pyreduce-astro 0.7b3__tar.gz → 0.7b4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/CHANGELOG.md +27 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/CLAUDE.md +5 -4
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/PKG-INFO +1 -1
- pyreduce_astro-0.7b4/examples/andes_yjh_example.py +113 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/crires_plus_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/custom_instrument_example.py +2 -2
- pyreduce_astro-0.7b4/examples/debug_single_swath.py +233 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harpn_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harps_example.py +1 -1
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harps_gridsearch.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/just_one_swath.py +15 -3
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/jwst_miri_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/jwst_niriss_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/lick_apf_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/mcdonald_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/metis_ifu_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/metis_lss_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/micado_example.py +2 -2
- pyreduce_astro-0.7b4/examples/mosaic_nir.py +96 -0
- pyreduce_astro-0.7b4/examples/mosaic_preset-slitfunc.py +141 -0
- pyreduce_astro-0.7b4/examples/mosaic_vis.py +92 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/neid_example.py +1 -1
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/nirspec_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/toes_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/uves_callfunc.py +3 -3
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/uves_example.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/xshooter_example.py +2 -3
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyproject.toml +1 -1
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/__main__.py +10 -10
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/cli.py +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_2d_xi_zeta_bd.c +152 -118
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_2d_xi_zeta_bd.h +2 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_bd.c +2 -5
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/combine_frames.py +36 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/configuration.py +18 -4
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/cwrappers.py +251 -23
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/estimate_background_scatter.py +23 -23
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/extract.py +289 -191
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/extraction_height.py +14 -14
- pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/__init__.py +14 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/config.yaml +113 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_h.yaml +9 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_j.yaml +21 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_y.yaml +9 -0
- {pyreduce_astro-0.7b3/pyreduce/instruments/AJ → pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH}/settings.json +4 -3
- pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det1.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det2.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det3.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/settings.json +0 -2
- pyreduce_astro-0.7b4/pyreduce/instruments/HARPN/wavecal_harpn_fibB_2D.npz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/HARPS/mask_blue.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/HARPS/mask_red.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/settings.json +1 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/mask_lrs_slitless.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/mask_gr700xd.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/mask_.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MCDONALD/mask.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/settings.json +1 -4
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/settings.json +1 -4
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/__init__.py +38 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_nir.yaml +92 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis1.yaml +69 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis2.yaml +72 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis3.yaml +87 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis4.yaml +87 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/config.yaml +15 -2
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/mask_nir.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/settings.json +5 -10
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS1.json +22 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS2.json +22 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS3.json +22 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS4.json +22 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_nir.json +22 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/settings.json +0 -1
- pyreduce_astro-0.7b4/pyreduce/instruments/NIRSPEC/mask_nirspec.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/settings.json +0 -2
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_blue.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_blue_binned_2_2.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle_2x2_split.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle_binned_2_2.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_2x2.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_2x2_split.fits.gz +0 -0
- pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_binned_2_2.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/settings.json +2 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/mask_nir.fits.gz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/settings.json +1 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/common.py +3 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/schema.json +50 -142
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/settings.json +7 -9
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/models.py +99 -2
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/pipeline.py +205 -19
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/rectify.py +8 -8
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/reduce.py +366 -126
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/slit_curve.py +18 -88
- pyreduce_astro-0.7b4/pyreduce/trace.py +1709 -0
- pyreduce_astro-0.7b4/tools/mosaic_vis_bundle_plot.py +66 -0
- pyreduce_astro-0.7b4/tools/plot_1d_vs_2d_extraction.py +162 -0
- pyreduce_astro-0.7b4/tools/plot_swath_debug.py +64 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/uv.lock +1 -1
- pyreduce_astro-0.7b3/examples/aj_example.py +0 -209
- pyreduce_astro-0.7b3/examples/mosaic_example.py +0 -171
- pyreduce_astro-0.7b3/pyreduce/instruments/AJ/__init__.py +0 -9
- pyreduce_astro-0.7b3/pyreduce/instruments/AJ/config.yaml +0 -51
- pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/__init__.py +0 -100
- pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/config.yaml +0 -72
- pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/settings.json +0 -16
- pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det1.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det2.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det3.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_blue.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_red.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/mask.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/__init__.py +0 -12
- pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/mask_nirspec.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue_binned_2_2.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_2x2_split.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_binned_2_2.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2_split.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_binned_2_2.fits.gz +0 -0
- pyreduce_astro-0.7b3/pyreduce/trace.py +0 -985
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.gitattributes +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.gitignore +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.pre-commit-config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.python-version +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.readthedocs.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/AGENTS.md +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/ANDES_plan.md +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/LICENSE +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/README.md +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/hatch_build.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/build_extract.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_bd.h +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clipnflip.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/continuum_normalization.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/datasets.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/echelle.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det1.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det2.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det3.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/wavecal_harpn_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_blue_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_blue_pol_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_red_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_red_pol_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/wavecal.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/wavecal_l_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/wavecal_m_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/wavecal_HK_3arcsec_chip5.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/mosaic_fiber_positions.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/settings.json +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/wavecal_K2.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_360nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_390nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_437nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_2x2_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_565nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_580nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_600nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_665nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_860nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_580nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_600nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_665nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_760nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_860nm_2D.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/wavecal_nir.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/thar.fits +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/thar_list.txt +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/une.fits +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/config.yaml +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/filters.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/instrument_info.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/tools/__init__.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/tools/combine.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/util.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/wavelength_calibration.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/argon.line +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/bpm_creator.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/convert_wavecal.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/create_wavelength_guess.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/download_files.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/ipy_startup.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/make_notebook.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/neon.lin +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/neon.line +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/pymultispec.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/thar.npz +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/wavecal_creator.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/wavecal_creator_from_existing.py +0 -0
- {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/xshooter_nir.json +0 -0
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [0.7b4] - 2026-01-22
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
- Per-channel settings support via `settings_{channel}.json` files
|
|
8
|
+
- Fiber grouping configuration for multi-fiber instruments (bundle_centers, fiber_groups)
|
|
9
|
+
- `preset_slitfunc` parameter for single-pass extraction using pre-computed slit function
|
|
10
|
+
- `noise_relative` parameter for trace threshold scaling
|
|
11
|
+
- `extraction_reject` threshold parameter for outlier rejection
|
|
12
|
+
- ANDES_YJH instrument with multi-channel support
|
|
13
|
+
- MOSAIC VIS quadrant support (VIS1-VIS4 channels) and NIR settings
|
|
14
|
+
- HARPN fiber B wavecal file
|
|
15
|
+
- Extraction residual panel in ProgressPlot
|
|
16
|
+
- `tools/plot_swath_debug.py` for analyzing extraction debug data
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- **Mask convention**: Switch to numpy convention (True/1=bad) on Python side; C code uses inverted (1=good)
|
|
20
|
+
- Extraction convergence now based on spectrum change with global RMS for rejection
|
|
21
|
+
- Improved outlier rejection using 6*sigma instead of MAD in 2D extraction
|
|
22
|
+
- Norm_flat step saves slit function with metadata for reuse
|
|
23
|
+
- Refactor Pipeline trace API: add `trace_raw()` and `organize()` methods
|
|
24
|
+
- Remove `extraction_cutoff` parameter (dead code)
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- `smooth_spectrum` normalization (port from cr2res)
|
|
28
|
+
- Masked array handling in swath debug plotting
|
|
29
|
+
- Minimum 4 iterations enforced in curved extraction
|
|
30
|
+
|
|
4
31
|
## [0.7b3] - 2026-01-11
|
|
5
32
|
|
|
6
33
|
### Added
|
|
@@ -31,7 +31,7 @@ pyreduce/
|
|
|
31
31
|
├── reduce.py # Step class implementations
|
|
32
32
|
├── configuration.py # Config loading (settings JSON)
|
|
33
33
|
├── extract.py # Optimal extraction algorithm
|
|
34
|
-
├──
|
|
34
|
+
├── trace.py # Order detection and tracing
|
|
35
35
|
├── wavelength_calibration.py # Wavelength solution fitting
|
|
36
36
|
├── combine_frames.py # Frame combination/calibration
|
|
37
37
|
├── echelle.py # Echelle spectrum I/O
|
|
@@ -158,7 +158,7 @@ Defines HOW to reduce - algorithm parameters per step:
|
|
|
158
158
|
"degree": 4,
|
|
159
159
|
"noise": 100,
|
|
160
160
|
"min_cluster": 500,
|
|
161
|
-
"
|
|
161
|
+
"filter_y": 120
|
|
162
162
|
},
|
|
163
163
|
"norm_flat": {
|
|
164
164
|
"extraction_height": 0.5,
|
|
@@ -217,7 +217,7 @@ pipe = Pipeline(
|
|
|
217
217
|
)
|
|
218
218
|
pipe.bias(bias_files)
|
|
219
219
|
pipe.flat(flat_files)
|
|
220
|
-
pipe.
|
|
220
|
+
pipe.trace()
|
|
221
221
|
pipe.extract(science_files)
|
|
222
222
|
result = pipe.run()
|
|
223
223
|
```
|
|
@@ -260,6 +260,7 @@ uv run reduce list-steps
|
|
|
260
260
|
- `PYREDUCE_PLOT` - Override plot level (0=off, 1=basic, 2=detailed)
|
|
261
261
|
- `PYREDUCE_PLOT_DIR` - Save plots to directory as PNG files
|
|
262
262
|
- `PYREDUCE_PLOT_SHOW` - Display mode: `block` (default), `defer`, or `off`
|
|
263
|
+
- `PYREDUCE_PLOT_ANIMATION_SPEED` - Frame delay in seconds for extraction animation (default: 0.3)
|
|
263
264
|
|
|
264
265
|
Plot modes: `block` shows each plot interactively; `defer` accumulates all plots and shows at end (useful with webagg backend); `off` disables display. Save and display are independent.
|
|
265
266
|
|
|
@@ -303,7 +304,7 @@ After a fresh clone or `rm -rf .venv`, run `uv sync && uv run reduce-build` to s
|
|
|
303
304
|
| `pyreduce/reduce.py` | Step class implementations |
|
|
304
305
|
| `pyreduce/extract.py` | Optimal extraction algorithm |
|
|
305
306
|
| `pyreduce/wavelength_calibration.py` | Wavelength solution fitting |
|
|
306
|
-
| `pyreduce/
|
|
307
|
+
| `pyreduce/trace.py` | Order detection and tracing |
|
|
307
308
|
| `pyreduce/instruments/common.py` | Base Instrument class |
|
|
308
309
|
| `pyreduce/instruments/models.py` | Pydantic config models |
|
|
309
310
|
| `pyreduce/clib/*.c` | C code for slit function decomposition |
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.13"
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
|
+
# ///
|
|
5
|
+
"""
|
|
6
|
+
ANDES_YJH instrument example: Multi-fiber tracing with Pipeline API.
|
|
7
|
+
|
|
8
|
+
Demonstrates tracing fibers illuminated in separate flat field images
|
|
9
|
+
(even/odd pattern) using the Pipeline's trace_raw() and organize() methods.
|
|
10
|
+
|
|
11
|
+
The fiber config in ANDES_YJH/config.yaml handles:
|
|
12
|
+
- order_centers_file: assigns traces to spectral orders by y-position (channel-specific)
|
|
13
|
+
- groups: organizes fibers into logical groups (A, cal, B) within each order
|
|
14
|
+
- merge: average - averages fiber traces within each group
|
|
15
|
+
|
|
16
|
+
ANDES_YJH has three channels: Y, J, H (selected by BAND header in files).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
|
|
21
|
+
import numpy as np
|
|
22
|
+
|
|
23
|
+
from pyreduce.configuration import load_config
|
|
24
|
+
from pyreduce.pipeline import Pipeline
|
|
25
|
+
|
|
26
|
+
# --- Configuration ---
|
|
27
|
+
instrument_name = "ANDES_YJH"
|
|
28
|
+
channel = "J" # Y, J, or H
|
|
29
|
+
data_dir = os.environ.get("REDUCE_DATA", os.path.expanduser("~/REDUCE_DATA"))
|
|
30
|
+
raw_dir = os.path.join(data_dir, "ANDES", channel)
|
|
31
|
+
output_dir = os.path.join(data_dir, "ANDES", "reduced", channel)
|
|
32
|
+
|
|
33
|
+
# Input files (even and odd illuminated flats)
|
|
34
|
+
# File selection is header-based:
|
|
35
|
+
# BAND header determines channel (Y, J, H)
|
|
36
|
+
# SIMTYPE='flat_field' → flat, SIMTYPE='spectrum' → science
|
|
37
|
+
# FIBMODE='even' → even flat, FIBMODE='odd' → odd flat
|
|
38
|
+
file_even = os.path.join(raw_dir, f"{channel}_FF_even_1s.fits")
|
|
39
|
+
file_odd = os.path.join(raw_dir, f"{channel}_FF_odd_1s.fits")
|
|
40
|
+
|
|
41
|
+
# Plot settings
|
|
42
|
+
plot = int(os.environ.get("PYREDUCE_PLOT", "1"))
|
|
43
|
+
|
|
44
|
+
# --- Create Pipeline ---
|
|
45
|
+
config = load_config(None, instrument_name)
|
|
46
|
+
pipe = Pipeline(
|
|
47
|
+
instrument=instrument_name,
|
|
48
|
+
channel=channel,
|
|
49
|
+
output_dir=output_dir,
|
|
50
|
+
target="ANDES_fiber_test",
|
|
51
|
+
config=config,
|
|
52
|
+
plot=plot,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
print(f"Instrument: {pipe.instrument.name}")
|
|
56
|
+
fibers_config = pipe.instrument.config.fibers
|
|
57
|
+
print(f"Per-order grouping: {fibers_config.per_order}")
|
|
58
|
+
print(f"Groups: {list(fibers_config.groups.keys())}")
|
|
59
|
+
|
|
60
|
+
# --- Trace or load from previous run ---
|
|
61
|
+
LOAD_TRACE = True # Set True to load traces from previous run
|
|
62
|
+
|
|
63
|
+
if LOAD_TRACE:
|
|
64
|
+
print("\nLoading traces from previous run...")
|
|
65
|
+
traces, column_range = pipe._run_step("trace", None, load_only=True)
|
|
66
|
+
print(f" Loaded {len(traces)} traces")
|
|
67
|
+
|
|
68
|
+
# Re-run organize with current config (picks up any config changes)
|
|
69
|
+
print("\nRe-organizing traces with current config...")
|
|
70
|
+
pipe.organize(traces, column_range)
|
|
71
|
+
else:
|
|
72
|
+
# Trace each flat independently
|
|
73
|
+
print(f"\nTracing even fibers from {os.path.basename(file_even)}...")
|
|
74
|
+
traces_even, cr_even = pipe.trace_raw([file_even])
|
|
75
|
+
print(f" Found {len(traces_even)} traces")
|
|
76
|
+
|
|
77
|
+
print(f"\nTracing odd fibers from {os.path.basename(file_odd)}...")
|
|
78
|
+
traces_odd, cr_odd = pipe.trace_raw([file_odd])
|
|
79
|
+
print(f" Found {len(traces_odd)} traces")
|
|
80
|
+
|
|
81
|
+
# Organize into fiber groups
|
|
82
|
+
print("\nOrganizing traces into fiber groups...")
|
|
83
|
+
pipe.organize(traces_even, cr_even, traces_odd, cr_odd)
|
|
84
|
+
|
|
85
|
+
# Access organized groups
|
|
86
|
+
if "trace_groups" in pipe._data and pipe._data["trace_groups"][0]:
|
|
87
|
+
group_traces, group_cr = pipe._data["trace_groups"]
|
|
88
|
+
print("Fiber groups:")
|
|
89
|
+
for name, traces_dict in group_traces.items():
|
|
90
|
+
n_traces = len(traces_dict)
|
|
91
|
+
print(f" {name}: {n_traces} traces")
|
|
92
|
+
|
|
93
|
+
# --- Create combined flat for extraction ---
|
|
94
|
+
print("\nCombining even/odd flats...")
|
|
95
|
+
img_even, head = pipe.instrument.load_fits(file_even, channel=channel, extension=0)
|
|
96
|
+
img_odd, _ = pipe.instrument.load_fits(file_odd, channel=channel, extension=0)
|
|
97
|
+
img_combined = np.asarray(img_even, dtype=np.float64) + np.asarray(
|
|
98
|
+
img_odd, dtype=np.float64
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Save combined flat to file for the science step
|
|
102
|
+
from astropy.io import fits
|
|
103
|
+
|
|
104
|
+
combined_file = os.path.join(output_dir, "combined_flat.fits")
|
|
105
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
106
|
+
fits.writeto(combined_file, img_combined.astype(np.float32), head, overwrite=True)
|
|
107
|
+
print(f" Saved combined flat: {combined_file}")
|
|
108
|
+
|
|
109
|
+
# --- Extract using the science step ---
|
|
110
|
+
print("\nExtracting spectra (group A from fiber config)...")
|
|
111
|
+
pipe.instrument.config.fibers.use["science"] = ["ring1"]
|
|
112
|
+
pipe.config["science"]["extraction_height"] = 60
|
|
113
|
+
pipe.extract([combined_file]).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -48,5 +48,5 @@ Pipeline.from_instrument(
|
|
|
48
48
|
base_dir=base_dir,
|
|
49
49
|
input_dir=input_dir,
|
|
50
50
|
output_dir=output_dir,
|
|
51
|
-
#
|
|
51
|
+
# trace_range=(0, 4),
|
|
52
52
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -73,7 +73,7 @@ pipe = Pipeline.from_files(
|
|
|
73
73
|
channel=channel,
|
|
74
74
|
night=night,
|
|
75
75
|
config=config,
|
|
76
|
-
#
|
|
76
|
+
# trace_range=trace_range,
|
|
77
77
|
steps=steps,
|
|
78
78
|
plot=1,
|
|
79
79
|
)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.13"
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
|
+
# ///
|
|
5
|
+
"""
|
|
6
|
+
Debug script for extracting a single swath from a specific trace.
|
|
7
|
+
|
|
8
|
+
Manually loads traces from NPZ, cuts out one swath, runs extraction,
|
|
9
|
+
and saves all intermediate outputs for inspection.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
from os.path import join
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
from astropy.io import fits
|
|
17
|
+
|
|
18
|
+
from pyreduce.cwrappers import slitfunc_curved
|
|
19
|
+
from pyreduce.extract import fix_parameters, make_bins
|
|
20
|
+
from pyreduce.util import make_index
|
|
21
|
+
|
|
22
|
+
# === Configuration ===
|
|
23
|
+
# Which trace and swath to extract
|
|
24
|
+
TRACE_INDEX = 4 # 5th trace (0-indexed), i.e. 5th fiber bundle center
|
|
25
|
+
SWATH_INDEX = 2 # 3rd swath (0-indexed)
|
|
26
|
+
|
|
27
|
+
# Extraction parameters
|
|
28
|
+
EXTRACTION_HEIGHT = 0.5 # fraction of order spacing
|
|
29
|
+
OSAMPLE = 1
|
|
30
|
+
LAMBDA_SF = 0.1
|
|
31
|
+
LAMBDA_SP = 0
|
|
32
|
+
MAXITER = 20
|
|
33
|
+
GAIN = 1.0
|
|
34
|
+
|
|
35
|
+
# === Data paths ===
|
|
36
|
+
data_dir = os.environ.get("REDUCE_DATA", os.path.expanduser("~/REDUCE_DATA"))
|
|
37
|
+
base_dir = join(data_dir, "MOSAIC", "REF_E2E", "NIR")
|
|
38
|
+
output_dir = join(data_dir, "MOSAIC", "reduced", "NIR")
|
|
39
|
+
|
|
40
|
+
flat_file = join(
|
|
41
|
+
base_dir,
|
|
42
|
+
"E2E_FLAT_DIT_20s_MOSAIC_2Cam_c01",
|
|
43
|
+
"E2E_FLAT_DIT_20s_MOSAIC_2Cam_c01_STATIC_FOCAL_PLANE.fits",
|
|
44
|
+
)
|
|
45
|
+
trace_file = join(output_dir, "MOSAIC_NIR.ord_default.npz")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def load_traces(trace_file):
|
|
49
|
+
"""Load traces and column ranges from NPZ."""
|
|
50
|
+
import warnings
|
|
51
|
+
|
|
52
|
+
data = np.load(trace_file, allow_pickle=True)
|
|
53
|
+
if "traces" in data:
|
|
54
|
+
traces = data["traces"]
|
|
55
|
+
elif "orders" in data:
|
|
56
|
+
warnings.warn(
|
|
57
|
+
f"Trace file {trace_file} uses old key 'orders'. "
|
|
58
|
+
"Re-run the trace step to update the file format.",
|
|
59
|
+
DeprecationWarning,
|
|
60
|
+
stacklevel=2,
|
|
61
|
+
)
|
|
62
|
+
traces = data["orders"]
|
|
63
|
+
else:
|
|
64
|
+
raise KeyError("Trace file missing 'traces' key")
|
|
65
|
+
column_range = data["column_range"]
|
|
66
|
+
print(f"Loaded {len(traces)} traces from {trace_file}")
|
|
67
|
+
return traces, column_range
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def load_image(flat_file):
|
|
71
|
+
"""Load and prepare the flat field image."""
|
|
72
|
+
with fits.open(flat_file) as hdul:
|
|
73
|
+
img = hdul[0].data.astype(float)
|
|
74
|
+
print(f"Loaded image {img.shape} from {flat_file}")
|
|
75
|
+
return img
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def extract_single_swath(
|
|
79
|
+
img,
|
|
80
|
+
trace_coef,
|
|
81
|
+
column_range,
|
|
82
|
+
swath_index,
|
|
83
|
+
extraction_height,
|
|
84
|
+
p1=None,
|
|
85
|
+
p2=None,
|
|
86
|
+
):
|
|
87
|
+
"""
|
|
88
|
+
Extract a single swath from one trace.
|
|
89
|
+
|
|
90
|
+
Returns the swath image, extraction results, and metadata.
|
|
91
|
+
"""
|
|
92
|
+
nrow, ncol = img.shape
|
|
93
|
+
xlow, xhigh = column_range
|
|
94
|
+
|
|
95
|
+
# Evaluate trace polynomial
|
|
96
|
+
x = np.arange(ncol)
|
|
97
|
+
ycen = np.polyval(trace_coef, x)
|
|
98
|
+
|
|
99
|
+
# Get extraction height in pixels
|
|
100
|
+
ylow, yhigh = extraction_height
|
|
101
|
+
|
|
102
|
+
# Create swath bins
|
|
103
|
+
nbin, bins_start, bins_end = make_bins(None, xlow, xhigh, ycen)
|
|
104
|
+
nswath = 2 * nbin - 1
|
|
105
|
+
print(f"Order has {nswath} swaths, extracting swath {swath_index}")
|
|
106
|
+
|
|
107
|
+
if swath_index >= nswath:
|
|
108
|
+
raise ValueError(f"Swath index {swath_index} >= number of swaths {nswath}")
|
|
109
|
+
|
|
110
|
+
# Get this swath's column range
|
|
111
|
+
ibeg = bins_start[swath_index]
|
|
112
|
+
iend = bins_end[swath_index]
|
|
113
|
+
print(f"Swath columns: {ibeg} - {iend} (width={iend - ibeg})")
|
|
114
|
+
|
|
115
|
+
# Cut out swath from image
|
|
116
|
+
ycen_int = np.floor(ycen).astype(int)
|
|
117
|
+
index = make_index(ycen_int - ylow, ycen_int + yhigh, ibeg, iend)
|
|
118
|
+
swath_img = img[index].copy()
|
|
119
|
+
swath_ycen = ycen[ibeg:iend]
|
|
120
|
+
|
|
121
|
+
# Fractional y offset within each pixel
|
|
122
|
+
swath_ycen_frac = swath_ycen - np.floor(swath_ycen)
|
|
123
|
+
|
|
124
|
+
print(f"Swath image shape: {swath_img.shape}")
|
|
125
|
+
print(f"Swath ycen range: {swath_ycen.min():.1f} - {swath_ycen.max():.1f}")
|
|
126
|
+
|
|
127
|
+
# Get curvature for this swath
|
|
128
|
+
swath_p1 = p1[ibeg:iend] if p1 is not None else 0
|
|
129
|
+
swath_p2 = p2[ibeg:iend] if p2 is not None else 0
|
|
130
|
+
|
|
131
|
+
# Run extraction
|
|
132
|
+
yrange = (ylow, yhigh)
|
|
133
|
+
spec, slitf, model, unc, mask, info = slitfunc_curved(
|
|
134
|
+
swath_img,
|
|
135
|
+
swath_ycen_frac,
|
|
136
|
+
swath_p1,
|
|
137
|
+
swath_p2,
|
|
138
|
+
lambda_sp=LAMBDA_SP,
|
|
139
|
+
lambda_sf=LAMBDA_SF,
|
|
140
|
+
osample=OSAMPLE,
|
|
141
|
+
yrange=yrange,
|
|
142
|
+
maxiter=MAXITER,
|
|
143
|
+
gain=GAIN,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
"swath_img": swath_img,
|
|
148
|
+
"spec": spec,
|
|
149
|
+
"slitf": slitf,
|
|
150
|
+
"model": model,
|
|
151
|
+
"unc": unc,
|
|
152
|
+
"mask": mask,
|
|
153
|
+
"info": info,
|
|
154
|
+
"ycen": swath_ycen_frac,
|
|
155
|
+
"ibeg": ibeg,
|
|
156
|
+
"iend": iend,
|
|
157
|
+
"yrange": yrange,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def main():
|
|
162
|
+
# Check files exist
|
|
163
|
+
for fpath in [flat_file, trace_file]:
|
|
164
|
+
if not os.path.exists(fpath):
|
|
165
|
+
raise FileNotFoundError(f"File not found: {fpath}")
|
|
166
|
+
|
|
167
|
+
# Load data
|
|
168
|
+
img = load_image(flat_file)
|
|
169
|
+
traces, column_range = load_traces(trace_file)
|
|
170
|
+
nrow, ncol = img.shape
|
|
171
|
+
ntrace = len(traces)
|
|
172
|
+
|
|
173
|
+
print(f"\nImage: {nrow} x {ncol}")
|
|
174
|
+
print(f"Traces: {ntrace}")
|
|
175
|
+
print(f"Extracting trace {TRACE_INDEX}, swath {SWATH_INDEX}\n")
|
|
176
|
+
|
|
177
|
+
# Fix extraction parameters
|
|
178
|
+
xwd, cr, traces = fix_parameters(
|
|
179
|
+
EXTRACTION_HEIGHT, column_range, traces, nrow, ncol, ntrace
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Get the specific trace
|
|
183
|
+
trace_coef = traces[TRACE_INDEX]
|
|
184
|
+
trace_cr = cr[TRACE_INDEX]
|
|
185
|
+
trace_xwd = xwd[TRACE_INDEX]
|
|
186
|
+
|
|
187
|
+
print(f"Trace {TRACE_INDEX}:")
|
|
188
|
+
print(f" Column range: {trace_cr}")
|
|
189
|
+
print(f" Extraction height: {trace_xwd} (below, above)")
|
|
190
|
+
|
|
191
|
+
# Extract single swath
|
|
192
|
+
result = extract_single_swath(
|
|
193
|
+
img,
|
|
194
|
+
trace_coef,
|
|
195
|
+
trace_cr,
|
|
196
|
+
SWATH_INDEX,
|
|
197
|
+
trace_xwd,
|
|
198
|
+
p1=None, # No curvature correction
|
|
199
|
+
p2=None,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Save outputs
|
|
203
|
+
out_file = join(output_dir, f"debug_swath_t{TRACE_INDEX}_s{SWATH_INDEX}.npz")
|
|
204
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
205
|
+
np.savez(
|
|
206
|
+
out_file,
|
|
207
|
+
swath_img=result["swath_img"],
|
|
208
|
+
spec=result["spec"],
|
|
209
|
+
slitf=result["slitf"],
|
|
210
|
+
model=result["model"],
|
|
211
|
+
unc=result["unc"],
|
|
212
|
+
mask=result["mask"],
|
|
213
|
+
ycen=result["ycen"],
|
|
214
|
+
ibeg=result["ibeg"],
|
|
215
|
+
iend=result["iend"],
|
|
216
|
+
yrange=result["yrange"],
|
|
217
|
+
trace_index=TRACE_INDEX,
|
|
218
|
+
swath_index=SWATH_INDEX,
|
|
219
|
+
)
|
|
220
|
+
print(f"\nSaved results to: {out_file}")
|
|
221
|
+
|
|
222
|
+
# Print summary
|
|
223
|
+
print("\n=== Extraction Results ===")
|
|
224
|
+
print(f"Spectrum shape: {result['spec'].shape}")
|
|
225
|
+
print(f"Slitfunction shape: {result['slitf'].shape}")
|
|
226
|
+
print(f"Model shape: {result['model'].shape}")
|
|
227
|
+
print(f"Chi-squared: {result['info'][1]:.3f}")
|
|
228
|
+
print(f"Iterations: {result['info'][0]}")
|
|
229
|
+
print(f"Masked pixels: {result['mask'].sum()}")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
if __name__ == "__main__":
|
|
233
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -43,6 +43,6 @@ Pipeline.from_instrument(
|
|
|
43
43
|
base_dir=base_dir,
|
|
44
44
|
input_dir=input_dir,
|
|
45
45
|
output_dir=output_dir,
|
|
46
|
-
#
|
|
46
|
+
# trace_range=(0, 25),
|
|
47
47
|
plot=1,
|
|
48
48
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
import os.path
|
|
6
6
|
|
|
@@ -71,7 +71,7 @@ kwargs_comb["nstep"] = 0
|
|
|
71
71
|
kwargs["plot"] = False
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
for key in ["extraction_method", "extraction_height"
|
|
74
|
+
for key in ["extraction_method", "extraction_height"]:
|
|
75
75
|
del kwargs_comb[key]
|
|
76
76
|
del kwargs[key]
|
|
77
77
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
import matplotlib.pyplot as plt
|
|
6
6
|
import numpy as np
|
|
@@ -15,8 +15,20 @@ hdu = fits.open(input_dir + "uves_middle.flat.fits")
|
|
|
15
15
|
img = hdu[0].data
|
|
16
16
|
nrow, ncol = img.shape
|
|
17
17
|
|
|
18
|
+
import warnings
|
|
19
|
+
|
|
18
20
|
data = np.load(input_dir + "uves_middle.ord_default.npz", allow_pickle=True)
|
|
19
|
-
|
|
21
|
+
if "traces" in data:
|
|
22
|
+
traces = data["traces"]
|
|
23
|
+
elif "orders" in data:
|
|
24
|
+
warnings.warn(
|
|
25
|
+
"Trace file uses old key 'orders'. Re-run the trace step to update.",
|
|
26
|
+
DeprecationWarning,
|
|
27
|
+
stacklevel=1,
|
|
28
|
+
)
|
|
29
|
+
traces = data["orders"]
|
|
30
|
+
else:
|
|
31
|
+
raise KeyError("Trace file missing 'traces' key")
|
|
20
32
|
column_range = data["column_range"]
|
|
21
33
|
|
|
22
34
|
i = 5
|
|
@@ -24,7 +36,7 @@ ix = np.arange(ncol)
|
|
|
24
36
|
|
|
25
37
|
ylow, yhigh = 50, 50
|
|
26
38
|
ibeg, iend = 1500, 2000
|
|
27
|
-
ycen = np.polyval(
|
|
39
|
+
ycen = np.polyval(traces[i], ix)
|
|
28
40
|
ycen_int = ycen.astype(int)
|
|
29
41
|
# yrange = extract.get_y_scale(ycen, [400, 600], [5, 5], nrow)
|
|
30
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -41,6 +41,6 @@ Pipeline.from_instrument(
|
|
|
41
41
|
base_dir=base_dir,
|
|
42
42
|
input_dir=input_dir,
|
|
43
43
|
output_dir=output_dir,
|
|
44
|
-
#
|
|
44
|
+
# trace_range=(0, 25),
|
|
45
45
|
plot=1,
|
|
46
46
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -41,6 +41,6 @@ Pipeline.from_instrument(
|
|
|
41
41
|
base_dir=base_dir,
|
|
42
42
|
input_dir=input_dir,
|
|
43
43
|
output_dir=output_dir,
|
|
44
|
-
#
|
|
44
|
+
# trace_range=(0, 25),
|
|
45
45
|
plot=0,
|
|
46
46
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -41,6 +41,6 @@ Pipeline.from_instrument(
|
|
|
41
41
|
base_dir=base_dir,
|
|
42
42
|
input_dir=input_dir,
|
|
43
43
|
output_dir=output_dir,
|
|
44
|
-
#
|
|
44
|
+
# trace_range=(0, 25),
|
|
45
45
|
plot=1,
|
|
46
46
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -52,6 +52,6 @@ Pipeline.from_instrument(
|
|
|
52
52
|
input_dir=input_dir,
|
|
53
53
|
output_dir=output_dir,
|
|
54
54
|
configuration=config,
|
|
55
|
-
#
|
|
55
|
+
# trace_range=(0, 25),
|
|
56
56
|
plot=2,
|
|
57
57
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -47,6 +47,6 @@ Pipeline.from_instrument(
|
|
|
47
47
|
base_dir=base_dir,
|
|
48
48
|
input_dir=input_dir,
|
|
49
49
|
output_dir=output_dir,
|
|
50
|
-
#
|
|
50
|
+
# trace_range=(16, 17),
|
|
51
51
|
plot=1,
|
|
52
52
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -47,6 +47,6 @@ Pipeline.from_instrument(
|
|
|
47
47
|
base_dir=base_dir,
|
|
48
48
|
input_dir=input_dir,
|
|
49
49
|
output_dir=output_dir,
|
|
50
|
-
#
|
|
50
|
+
# trace_range=(16, 17),
|
|
51
51
|
plot=1,
|
|
52
52
|
).run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.13"
|
|
3
|
-
# dependencies = ["pyreduce-astro>=0.
|
|
3
|
+
# dependencies = ["pyreduce-astro>=0.7b4"]
|
|
4
4
|
# ///
|
|
5
5
|
"""
|
|
6
6
|
Simple usage example for PyReduce
|
|
@@ -67,6 +67,6 @@ Pipeline.from_instrument(
|
|
|
67
67
|
input_dir=input_dir,
|
|
68
68
|
output_dir=output_dir,
|
|
69
69
|
configuration=config,
|
|
70
|
-
|
|
70
|
+
trace_range=(3, 4),
|
|
71
71
|
plot=1,
|
|
72
72
|
).run()
|