pyreduce-astro 0.7b1__tar.gz → 0.7b3__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.7b1 → pyreduce_astro-0.7b3}/.gitignore +2 -0
- pyreduce_astro-0.7b3/ANDES_plan.md +377 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/CHANGELOG.md +31 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/CLAUDE.md +26 -15
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/PKG-INFO +15 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/README.md +14 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/aj_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/crires_plus_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/custom_instrument_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/harpn_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/harps_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/harps_gridsearch.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/just_one_swath.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/jwst_miri_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/jwst_niriss_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/lick_apf_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/mcdonald_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/metis_ifu_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/metis_lss_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/micado_example.py +10 -12
- pyreduce_astro-0.7b3/examples/mosaic_example.py +171 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/neid_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/nirspec_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/toes_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/uves_callfunc.py +18 -9
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/uves_example.py +1 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/examples/xshooter_example.py +5 -5
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyproject.toml +8 -2
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/__main__.py +19 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/combine_frames.py +3 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/configuration.py +66 -15
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/continuum_normalization.py +2 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/cwrappers.py +4 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/estimate_background_scatter.py +1 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/extract.py +99 -36
- pyreduce_astro-0.7b1/pyreduce/instruments/aj.py → pyreduce_astro-0.7b3/pyreduce/instruments/AJ/__init__.py +1 -1
- pyreduce_astro-0.7b3/pyreduce/instruments/AJ/settings.json +23 -0
- pyreduce_astro-0.7b1/pyreduce/instruments/andes.py → pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/__init__.py +6 -8
- pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/settings.json +16 -0
- pyreduce_astro-0.7b1/pyreduce/instruments/crires_plus.py → pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/__init__.py +6 -8
- pyreduce_astro-0.7b1/pyreduce/settings/settings_CRIRES_PLUS.json → pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/settings.json +16 -9
- pyreduce_astro-0.7b1/pyreduce/instruments/harpn.py → pyreduce_astro-0.7b3/pyreduce/instruments/HARPN/__init__.py +4 -4
- pyreduce_astro-0.7b3/pyreduce/instruments/HARPN/settings.json +21 -0
- pyreduce_astro-0.7b1/pyreduce/instruments/harps.py → pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/__init__.py +5 -8
- pyreduce_astro-0.7b1/pyreduce/settings/settings_HARPS.json → pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/settings.json +9 -7
- pyreduce_astro-0.7b1/pyreduce/instruments/jwst_miri.py → pyreduce_astro-0.7b3/pyreduce/instruments/JWST_MIRI/__init__.py +3 -5
- pyreduce_astro-0.7b1/pyreduce/settings/settings_JWST_MIRI.json → pyreduce_astro-0.7b3/pyreduce/instruments/JWST_MIRI/settings.json +17 -9
- pyreduce_astro-0.7b1/pyreduce/instruments/jwst_niriss.py → pyreduce_astro-0.7b3/pyreduce/instruments/JWST_NIRISS/__init__.py +5 -7
- pyreduce_astro-0.7b1/pyreduce/settings/settings_JWST_NIRISS.json → pyreduce_astro-0.7b3/pyreduce/instruments/JWST_NIRISS/settings.json +16 -8
- pyreduce_astro-0.7b1/pyreduce/instruments/lick_apf.py → pyreduce_astro-0.7b3/pyreduce/instruments/LICK_APF/__init__.py +2 -3
- pyreduce_astro-0.7b1/pyreduce/settings/settings_LICK_APF.json → pyreduce_astro-0.7b3/pyreduce/instruments/LICK_APF/settings.json +23 -15
- pyreduce_astro-0.7b1/pyreduce/instruments/mcdonald.py → pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/__init__.py +3 -5
- pyreduce_astro-0.7b1/pyreduce/settings/settings_MCDONALD.json → pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/settings.json +21 -10
- pyreduce_astro-0.7b1/pyreduce/instruments/metis_ifu.py → pyreduce_astro-0.7b3/pyreduce/instruments/METIS_IFU/__init__.py +3 -6
- pyreduce_astro-0.7b1/pyreduce/settings/settings_METIS_LSS.json → pyreduce_astro-0.7b3/pyreduce/instruments/METIS_IFU/settings.json +13 -11
- pyreduce_astro-0.7b1/pyreduce/instruments/metis_lss.py → pyreduce_astro-0.7b3/pyreduce/instruments/METIS_LSS/__init__.py +3 -6
- pyreduce_astro-0.7b3/pyreduce/instruments/METIS_LSS/settings.json +4 -0
- pyreduce_astro-0.7b1/pyreduce/instruments/micado.py → pyreduce_astro-0.7b3/pyreduce/instruments/MICADO/__init__.py +3 -6
- pyreduce_astro-0.7b1/pyreduce/settings/settings_MICADO.json → pyreduce_astro-0.7b3/pyreduce/instruments/MICADO/settings.json +14 -12
- pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/__init__.py +12 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/config.yaml +48 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/mosaic_fiber_positions.npz +0 -0
- pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/settings.json +30 -0
- pyreduce_astro-0.7b1/pyreduce/instruments/neid.py → pyreduce_astro-0.7b3/pyreduce/instruments/NEID/__init__.py +4 -4
- pyreduce_astro-0.7b1/pyreduce/settings/settings_NEID.json → pyreduce_astro-0.7b3/pyreduce/instruments/NEID/settings.json +17 -9
- pyreduce_astro-0.7b1/pyreduce/instruments/nirspec.py → pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/__init__.py +3 -3
- pyreduce_astro-0.7b1/pyreduce/settings/settings_NIRSPEC.json → pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/settings.json +16 -8
- pyreduce_astro-0.7b1/pyreduce/instruments/nte.py → pyreduce_astro-0.7b3/pyreduce/instruments/NTE/__init__.py +3 -5
- pyreduce_astro-0.7b1/pyreduce/settings/settings_NTE.json → pyreduce_astro-0.7b3/pyreduce/instruments/NTE/settings.json +16 -14
- pyreduce_astro-0.7b1/pyreduce/instruments/uves.py → pyreduce_astro-0.7b3/pyreduce/instruments/UVES/__init__.py +5 -8
- pyreduce_astro-0.7b1/pyreduce/settings/settings_UVES.json → pyreduce_astro-0.7b3/pyreduce/instruments/UVES/settings.json +15 -11
- pyreduce_astro-0.7b1/pyreduce/instruments/xshooter.py → pyreduce_astro-0.7b3/pyreduce/instruments/XSHOOTER/__init__.py +3 -5
- pyreduce_astro-0.7b1/pyreduce/settings/settings_XSHOOTER.json → pyreduce_astro-0.7b3/pyreduce/instruments/XSHOOTER/settings.json +16 -15
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/instruments/common.py +59 -30
- pyreduce_astro-0.7b1/pyreduce/settings/settings_schema.json → pyreduce_astro-0.7b3/pyreduce/instruments/defaults/schema.json +8 -12
- pyreduce_astro-0.7b1/pyreduce/settings/settings_pyreduce.json → pyreduce_astro-0.7b3/pyreduce/instruments/defaults/settings.json +16 -15
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/instruments/instrument_info.py +5 -3
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/pipeline.py +8 -1
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/rectify.py +9 -9
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/reduce.py +72 -34
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/slit_curve.py +22 -20
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/tools/combine.py +1 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/trace.py +49 -43
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/util.py +43 -5
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/wavelength_calibration.py +6 -2
- pyreduce_astro-0.7b3/tools/make_notebook.py +47 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/uv.lock +413 -38
- pyreduce_astro-0.7b1/pyreduce/masks/mask_ctio_chiron.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_elodie.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_feros3.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_flames_giraffe.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_hds_blue.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_hds_red.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_het_hrs_2x5.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_nes.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_sarg.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_sarg_2x2a.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_sarg_2x2b.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/masks/mask_subaru_hds_red.fits.gz +0 -0
- pyreduce_astro-0.7b1/pyreduce/settings/settings_AJ.json +0 -19
- pyreduce_astro-0.7b1/pyreduce/settings/settings_ANDES.json +0 -89
- pyreduce_astro-0.7b1/pyreduce/settings/settings_HARPN.json +0 -73
- pyreduce_astro-0.7b1/pyreduce/settings/settings_METIS_IFU.json +0 -77
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/.gitattributes +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/.pre-commit-config.yaml +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/.python-version +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/.readthedocs.yaml +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/AGENTS.md +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/LICENSE +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/hatch_build.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/__init__.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/cli.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/__init__.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/build_extract.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/slit_func_2d_xi_zeta_bd.c +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/slit_func_2d_xi_zeta_bd.h +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/slit_func_bd.c +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clib/slit_func_bd.h +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/clipnflip.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/datasets.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/echelle.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/extraction_height.py +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/aj.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/AJ/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/andes.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/crires_plus.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_crires_plus_det1.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det1.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_crires_plus_det2.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det2.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_crires_plus_det3.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det3.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/crires_plus_J1228_det1.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det1.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/crires_plus_J1228_det2.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det2.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/crires_plus_J1228_det3.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det3.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/harpn.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPN/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/harpn_harpn_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPN/wavecal_harpn_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/harps.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_harps_blue.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_blue.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_harps_red.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_red.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/harps_blue_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/wavecal_blue_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/harps_blue_pol_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/wavecal_blue_pol_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/harps_red_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/wavecal_red_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/harps_red_pol_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/wavecal_red_pol_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/jwst_miri.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/JWST_MIRI/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_jwst_miri_lrs_slitless.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/JWST_MIRI/mask_lrs_slitless.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/jwst_niriss.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/JWST_NIRISS/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_jwst_niriss_gr700xd.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/JWST_NIRISS/mask_gr700xd.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/lick_apf.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/LICK_APF/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_lick_apf_.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/LICK_APF/mask_.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/mcdonald.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_mcdonald.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/mask.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/mcdonald.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/wavecal.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/metis_ifu.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/METIS_IFU/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/metis_lss.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/METIS_LSS/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/metis_lss_l_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/METIS_LSS/wavecal_l_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/metis_lss_m_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/METIS_LSS/wavecal_m_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/micado.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/MICADO/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/MICADO_HK_3arcsec_chip5.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/MICADO/wavecal_HK_3arcsec_chip5.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/neid.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/NEID/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/nirspec.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_nirspec_nirspec.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/mask_nirspec.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/nirspec_K2.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/wavecal_K2.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/nte.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/NTE/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/uves.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_blue.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_blue_binned_2_2.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue_binned_2_2.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_middle.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_middle_2x2_split.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_2x2_split.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_middle_binned_2_2.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_binned_2_2.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_red.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_red_2x2.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_red_2x2_split.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2_split.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_uves_red_binned_2_2.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_binned_2_2.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_blue_360nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_blue_360nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_blue_390nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_blue_390nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_blue_437nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_blue_437nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_2x2_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_2x2_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_565nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_565nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_580nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_580nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_600nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_600nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_665nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_665nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_middle_860nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_middle_860nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_red_580nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_red_580nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_red_600nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_red_600nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_red_665nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_red_665nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_red_760nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_red_760nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/uves_red_860nm_2D.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/UVES/wavecal_red_860nm_2D.npz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/xshooter.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/XSHOOTER/config.yaml +0 -0
- /pyreduce_astro-0.7b1/pyreduce/masks/mask_xshooter_nir.fits.gz → /pyreduce_astro-0.7b3/pyreduce/instruments/XSHOOTER/mask_nir.fits.gz +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/xshooter_nir.npz → /pyreduce_astro-0.7b3/pyreduce/instruments/XSHOOTER/wavecal_nir.npz +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/instruments/__init__.py +0 -0
- {pyreduce_astro-0.7b1/pyreduce/wavecal → pyreduce_astro-0.7b3/pyreduce/instruments/defaults}/atlas/thar.fits +0 -0
- {pyreduce_astro-0.7b1/pyreduce/wavecal → pyreduce_astro-0.7b3/pyreduce/instruments/defaults}/atlas/thar_list.txt +0 -0
- {pyreduce_astro-0.7b1/pyreduce/wavecal → pyreduce_astro-0.7b3/pyreduce/instruments/defaults}/atlas/une.fits +0 -0
- /pyreduce_astro-0.7b1/pyreduce/instruments/common.yaml → /pyreduce_astro-0.7b3/pyreduce/instruments/defaults/config.yaml +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/instruments/filters.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/instruments/models.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/pyreduce/tools/__init__.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/argon.line +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/bpm_creator.py +0 -0
- /pyreduce_astro-0.7b1/pyreduce/wavecal/convert.py → /pyreduce_astro-0.7b3/tools/convert_wavecal.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/create_wavelength_guess.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/download_files.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/ipy_startup.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/neon.lin +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/neon.line +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/pymultispec.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/thar.npz +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/wavecal_creator.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/wavecal_creator_from_existing.py +0 -0
- {pyreduce_astro-0.7b1 → pyreduce_astro-0.7b3}/tools/xshooter_nir.json +0 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# ANDES Instrument Configuration Design
|
|
2
|
+
|
|
3
|
+
## Background
|
|
4
|
+
|
|
5
|
+
### ANDES Instrument Overview
|
|
6
|
+
|
|
7
|
+
ANDES is a future ELT high-resolution spectrograph with multiple spectrographs, each containing multiple arms:
|
|
8
|
+
|
|
9
|
+
| Spectrograph | Arms | Detector Type |
|
|
10
|
+
|--------------|------|---------------|
|
|
11
|
+
| 1 | U, B, V | Optical CCD |
|
|
12
|
+
| 2 | R, IZ | Red optical CCD |
|
|
13
|
+
| 3 | Y, J, H | Near-IR (H2RG or similar) |
|
|
14
|
+
| 4 | K | Thermal IR |
|
|
15
|
+
|
|
16
|
+
Key characteristics:
|
|
17
|
+
- All arms fed from the same fibers on sky
|
|
18
|
+
- Each arm has its own independent detector
|
|
19
|
+
- FITS files organized **per spectrograph** (one file with arms as extensions)
|
|
20
|
+
- Detectors are similar within each spectrograph
|
|
21
|
+
|
|
22
|
+
### Current State
|
|
23
|
+
|
|
24
|
+
- `andes.yaml` - Multi-channel IR-focused config
|
|
25
|
+
- `settings_ANDES.json` - Inherits from CRIRES_PLUS (IR-tuned)
|
|
26
|
+
- `aj.yaml` / `settings_AJ.json` - Simulation instrument (draft for testing)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## PyReduce Architecture Context
|
|
31
|
+
|
|
32
|
+
### How Channels Work
|
|
33
|
+
|
|
34
|
+
Channels in PyReduce handle multi-extension FITS files. The `getter` class in `instruments/common.py` automatically indexes list values by channel position:
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
# Example: UVES with 3 channels
|
|
38
|
+
channels: [BLUE, MIDDLE, RED]
|
|
39
|
+
extension: [0, 2, 1] # BLUE→ext0, MIDDLE→ext2, RED→ext1
|
|
40
|
+
orientation: [2, 1, 1] # BLUE rotated differently
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
When processing channel "RED" (index 2), PyReduce automatically uses `extension[2]=1`, `orientation[2]=1`.
|
|
44
|
+
|
|
45
|
+
### What MUST Be Shared Across Channels
|
|
46
|
+
|
|
47
|
+
1. **File classification keywords** (`kw_bias`, `kw_flat`, `kw_wave`, `kw_spec`)
|
|
48
|
+
2. **File classification patterns** (`id_bias`, `id_flat`, etc.)
|
|
49
|
+
3. **Reduction settings** - `settings_INSTRUMENT.json` applies to ALL channels
|
|
50
|
+
4. **Header keyword mappings** (date, target, exposure_time, etc.)
|
|
51
|
+
|
|
52
|
+
### What CAN Vary Per Channel
|
|
53
|
+
|
|
54
|
+
1. FITS extension index
|
|
55
|
+
2. Image orientation
|
|
56
|
+
3. Detector-specific header values (gain, readnoise) via `{id[n]}` templates
|
|
57
|
+
4. Output filenames (mask, wavecal)
|
|
58
|
+
|
|
59
|
+
### Critical Limitation: No Per-Channel Settings
|
|
60
|
+
|
|
61
|
+
**YAML instrument configs** support per-channel values via list indexing.
|
|
62
|
+
|
|
63
|
+
**JSON settings do NOT** - all channels share identical reduction parameters:
|
|
64
|
+
- Same `trace.degree`, `trace.noise`, `trace.min_cluster`
|
|
65
|
+
- Same `science.extraction_height`, `science.oversampling`
|
|
66
|
+
- Same `wavecal.degree`, `wavecal.threshold`
|
|
67
|
+
|
|
68
|
+
This means optical CCDs and IR arrays would share the same tuning if in one instrument.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Design Options
|
|
73
|
+
|
|
74
|
+
### Option A: Single ANDES Instrument (9 channels)
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
# andes.yaml
|
|
78
|
+
channels: [U, B, V, R, IZ, Y, J, H, K]
|
|
79
|
+
extension: [1, 2, 3, 1, 2, 1, 2, 3, 1]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Pros | Cons |
|
|
83
|
+
|------|------|
|
|
84
|
+
| Single abstraction level | Cannot tune settings per arm/spectrograph |
|
|
85
|
+
| Simple mental model | Must handle 4 FITS file types in one instrument |
|
|
86
|
+
| One config file | Optical/IR forced to share parameters |
|
|
87
|
+
|
|
88
|
+
**Implementation**: Would follow CRIRES+ pattern (see below).
|
|
89
|
+
|
|
90
|
+
### Option A Implementation: CRIRES+ Pattern
|
|
91
|
+
|
|
92
|
+
CRIRES+ shows how to handle multiple file types with a single instrument:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
class ANDES(Instrument):
|
|
96
|
+
def __init__(self):
|
|
97
|
+
super().__init__()
|
|
98
|
+
# Add spectrograph filter - files tagged by which spectrograph they're from
|
|
99
|
+
self.filters["spectrograph"] = Filter(self.info["kw_spectrograph"])
|
|
100
|
+
self.shared += ["spectrograph"]
|
|
101
|
+
|
|
102
|
+
def get_expected_values(self, target, night, channel):
|
|
103
|
+
expectations = super().get_expected_values(target, night)
|
|
104
|
+
# Map channel to spectrograph: J → YJH, U → UBV, etc.
|
|
105
|
+
spectrograph = self.channel_to_spectrograph(channel)
|
|
106
|
+
for key in expectations.keys():
|
|
107
|
+
expectations[key]["spectrograph"] = spectrograph
|
|
108
|
+
return expectations
|
|
109
|
+
|
|
110
|
+
def get_extension(self, header, channel):
|
|
111
|
+
# Map channel to extension: U→1, B→2, V→3, Y→1, J→2, H→3, etc.
|
|
112
|
+
return self.channel_extensions[channel]
|
|
113
|
+
|
|
114
|
+
def discover_channels(self, input_dir):
|
|
115
|
+
# Scan files, find which spectrographs present, return available channels
|
|
116
|
+
...
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**How file filtering works:**
|
|
120
|
+
1. Files have header keyword identifying spectrograph (UBV, RIZ, YJH, K)
|
|
121
|
+
2. When `channel=J` requested, ANDES maps J → YJH spectrograph
|
|
122
|
+
3. File filter selects only YJH spectrograph files
|
|
123
|
+
4. Extension 2 read from those files
|
|
124
|
+
|
|
125
|
+
**Without specifying channel:**
|
|
126
|
+
- `discover_channels()` scans files to find which spectrographs exist
|
|
127
|
+
- Returns available channels (e.g., if only YJH files exist → `[Y, J, H]`)
|
|
128
|
+
- Pipeline loops over each discovered channel
|
|
129
|
+
|
|
130
|
+
This makes Option A fully viable following an existing pattern.
|
|
131
|
+
|
|
132
|
+
### Option B: Separate Instruments (9 instruments, 1 channel each)
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
ANDES_U channels=[U] extension=1 → inherits pyreduce
|
|
136
|
+
ANDES_B channels=[B] extension=2 → inherits ANDES_U
|
|
137
|
+
ANDES_V channels=[V] extension=3 → inherits ANDES_U
|
|
138
|
+
ANDES_R channels=[R] extension=1 → inherits pyreduce
|
|
139
|
+
ANDES_IZ channels=[IZ] extension=2 → inherits ANDES_R
|
|
140
|
+
ANDES_Y channels=[Y] extension=1 → inherits CRIRES_PLUS
|
|
141
|
+
ANDES_J channels=[J] extension=2 → inherits ANDES_Y
|
|
142
|
+
ANDES_H channels=[H] extension=3 → inherits ANDES_Y
|
|
143
|
+
ANDES_K channels=[K] extension=1 → inherits CRIRES_PLUS
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Pros | Cons |
|
|
147
|
+
|------|------|
|
|
148
|
+
| Single abstraction (instruments only) | 9 YAML + 9 settings files |
|
|
149
|
+
| Maximum per-arm flexibility | File sorting overlap (U,B,V find same file) |
|
|
150
|
+
| Settings inheritance keeps configs DRY | Cannot reduce "all of UBV" in one command |
|
|
151
|
+
| Matches AJ pattern | More instruments to manage |
|
|
152
|
+
|
|
153
|
+
### Option C: Per-Spectrograph Instruments (4 instruments)
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
ANDES_UBV channels=[U,B,V] extension=[1,2,3] → inherits pyreduce
|
|
157
|
+
ANDES_RIZ channels=[R,IZ] extension=[1,2] → inherits ANDES_UBV
|
|
158
|
+
ANDES_YJH channels=[Y,J,H] extension=[1,2,3] → inherits CRIRES_PLUS
|
|
159
|
+
ANDES_K channels=[K] extension=1 → inherits ANDES_YJH
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Pros | Cons |
|
|
163
|
+
|------|------|
|
|
164
|
+
| Matches FITS file structure (1:1) | Two abstraction levels |
|
|
165
|
+
| Cleaner file sorting | Per-spectrograph tuning only (not per-arm) |
|
|
166
|
+
| Per-spectrograph settings tuning | |
|
|
167
|
+
| Follows XSHOOTER/HARPS/UVES pattern | |
|
|
168
|
+
| Can reduce entire spectrograph at once | |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Recommendation
|
|
173
|
+
|
|
174
|
+
**Option C** is recommended because:
|
|
175
|
+
|
|
176
|
+
1. **Matches physical reality**: One instrument = one FITS file type
|
|
177
|
+
2. **Sufficient tuning granularity**: Detectors are similar within spectrograph
|
|
178
|
+
3. **Proven pattern**: XSHOOTER (UVB/VIS/NIR), HARPS (BLUE/RED), UVES work this way
|
|
179
|
+
4. **Clean file handling**: No overlap in file discovery
|
|
180
|
+
|
|
181
|
+
If per-arm tuning becomes necessary, Option B remains viable with settings inheritance minimizing duplication.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## File Structure (Option C)
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
pyreduce/instruments/
|
|
189
|
+
andes_ubv.yaml # channels=[U,B,V], extension=[1,2,3]
|
|
190
|
+
andes_riz.yaml # channels=[R,IZ], extension=[1,2]
|
|
191
|
+
andes_yjh.yaml # channels=[Y,J,H], extension=[1,2,3]
|
|
192
|
+
andes_k.yaml # channels=[K], extension=1
|
|
193
|
+
|
|
194
|
+
pyreduce/settings/
|
|
195
|
+
settings_ANDES_UBV.json # __inherits__: pyreduce (optical CCD tuning)
|
|
196
|
+
settings_ANDES_RIZ.json # __inherits__: ANDES_UBV
|
|
197
|
+
settings_ANDES_YJH.json # __inherits__: CRIRES_PLUS (near-IR tuning)
|
|
198
|
+
settings_ANDES_K.json # __inherits__: ANDES_YJH
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Migration
|
|
202
|
+
|
|
203
|
+
- Rename `andes.yaml` → `andes_yjh.yaml` (or delete and create fresh)
|
|
204
|
+
- Rename `settings_ANDES.json` → `settings_ANDES_YJH.json`
|
|
205
|
+
- Keep `AJ` as simulation/test instrument
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Future Enhancement: Per-Channel Settings
|
|
210
|
+
|
|
211
|
+
Adding per-channel settings would enable Option A (single instrument with full flexibility).
|
|
212
|
+
|
|
213
|
+
### Current Flow
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
configuration.py:load_config()
|
|
217
|
+
→ loads settings_INSTRUMENT.json
|
|
218
|
+
→ merges with defaults via _resolve_inheritance()
|
|
219
|
+
→ returns config dict (same for all channels)
|
|
220
|
+
|
|
221
|
+
reduce.py:Step.__init__()
|
|
222
|
+
→ receives config dict
|
|
223
|
+
→ uses values directly: self.degree = config["degree"]
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Proposed Enhancement
|
|
227
|
+
|
|
228
|
+
Add channel-aware value selection in Step classes, similar to how `getter` works for YAML configs.
|
|
229
|
+
|
|
230
|
+
#### Option 1: Settings-level indexing
|
|
231
|
+
|
|
232
|
+
Modify `_resolve_inheritance()` or add post-processing to index list values:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
def _apply_channel_index(config, channel, channels):
|
|
236
|
+
"""Index list values in settings by channel position."""
|
|
237
|
+
if channel is None or channels is None:
|
|
238
|
+
return config
|
|
239
|
+
try:
|
|
240
|
+
idx = channels.index(channel.upper())
|
|
241
|
+
except (ValueError, AttributeError):
|
|
242
|
+
return config
|
|
243
|
+
|
|
244
|
+
result = {}
|
|
245
|
+
for key, value in config.items():
|
|
246
|
+
if isinstance(value, dict):
|
|
247
|
+
result[key] = _apply_channel_index(value, channel, channels)
|
|
248
|
+
elif isinstance(value, list) and len(value) == len(channels):
|
|
249
|
+
result[key] = value[idx]
|
|
250
|
+
else:
|
|
251
|
+
result[key] = value
|
|
252
|
+
return result
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Call this when creating Step instances in `pipeline.py`.
|
|
256
|
+
|
|
257
|
+
#### Option 2: Step-level helper
|
|
258
|
+
|
|
259
|
+
Add a method to Step base class:
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
class Step:
|
|
263
|
+
def get_config(self, key, default=None):
|
|
264
|
+
"""Get config value, indexing by channel if value is a list."""
|
|
265
|
+
value = self.config.get(key, default)
|
|
266
|
+
if isinstance(value, list) and hasattr(self, 'channel_index'):
|
|
267
|
+
if len(value) > self.channel_index:
|
|
268
|
+
return value[self.channel_index]
|
|
269
|
+
return value
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Settings Format
|
|
273
|
+
|
|
274
|
+
```json
|
|
275
|
+
{
|
|
276
|
+
"__instrument__": "ANDES",
|
|
277
|
+
"trace": {
|
|
278
|
+
"degree": 4,
|
|
279
|
+
"noise": [10, 10, 10, 20, 20, 50, 50, 50, 100],
|
|
280
|
+
"min_cluster": [500, 500, 500, 1000, 1000, 2000, 2000, 2000, 5000]
|
|
281
|
+
},
|
|
282
|
+
"science": {
|
|
283
|
+
"extraction_height": 10,
|
|
284
|
+
"oversampling": [10, 10, 10, 10, 10, 5, 5, 5, 3]
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Values that are scalars apply to all channels. Values that are lists with length matching `channels` are indexed.
|
|
290
|
+
|
|
291
|
+
#### Implementation Scope
|
|
292
|
+
|
|
293
|
+
1. **Minimal**: ~20-30 lines in `configuration.py` or `reduce.py`
|
|
294
|
+
2. **Changes needed**:
|
|
295
|
+
- Pass `channel` and `channels` list to config processing
|
|
296
|
+
- Add indexing logic (one of the options above)
|
|
297
|
+
- Update Step classes to use indexed values
|
|
298
|
+
3. **Backward compatible**: Scalar values work as before; only lists trigger indexing
|
|
299
|
+
4. **Risk**: Low - additive change, doesn't break existing instruments
|
|
300
|
+
|
|
301
|
+
#### Semantic List Parameters (Potential Conflict)
|
|
302
|
+
|
|
303
|
+
Current settings use lists for semantic pairs, not per-channel values:
|
|
304
|
+
|
|
305
|
+
| Parameter | Meaning | Where Used |
|
|
306
|
+
|-----------|---------|------------|
|
|
307
|
+
| `closing_shape` | [x, y] kernel | trace morphology |
|
|
308
|
+
| `opening_shape` | [x, y] kernel | trace morphology |
|
|
309
|
+
| `degree` | [order, column] | 2D fits (wavecal, curvature, freq_comb) |
|
|
310
|
+
| `extraction_height` | [below, above] | rarely as list, usually scalar |
|
|
311
|
+
|
|
312
|
+
**Option 1: Refactor semantic lists away**
|
|
313
|
+
|
|
314
|
+
```json
|
|
315
|
+
// Before
|
|
316
|
+
"closing_shape": [5, 5]
|
|
317
|
+
"degree": [6, 6]
|
|
318
|
+
|
|
319
|
+
// After
|
|
320
|
+
"closing_shape_x": 5,
|
|
321
|
+
"closing_shape_y": 5,
|
|
322
|
+
"degree_order": 6,
|
|
323
|
+
"degree_column": 6
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Pros: Clean separation, no ambiguity
|
|
327
|
+
Cons: Breaking change, migration needed
|
|
328
|
+
|
|
329
|
+
**Option 2: Length-based disambiguation**
|
|
330
|
+
|
|
331
|
+
Per-channel lists must match `len(channels)`. Semantic lists are always 2 elements.
|
|
332
|
+
- ANDES has 9 channels, so `[10, 20, 30, 40, 50, 60, 70, 80, 90]` → per-channel
|
|
333
|
+
- `[6, 6]` → semantic (2 elements ≠ 9 channels)
|
|
334
|
+
|
|
335
|
+
Pros: Backward compatible
|
|
336
|
+
Cons: Fragile if instrument has exactly 2 channels
|
|
337
|
+
|
|
338
|
+
**Option 3: Explicit marker**
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
"noise": {"__per_channel__": [10, 20, 50, 100]}
|
|
342
|
+
// or
|
|
343
|
+
"noise": {"U": 10, "B": 10, "V": 10, "Y": 50, "J": 50, "H": 50, "K": 100}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Pros: Explicit, no ambiguity
|
|
347
|
+
Cons: More verbose
|
|
348
|
+
|
|
349
|
+
**Recommendation**: Option 1 (refactor) for cleanest long-term solution. The semantic lists are:
|
|
350
|
+
- `closing_shape`, `opening_shape`: Rarely changed, easy to split
|
|
351
|
+
- `degree`: Common but well-understood, split to `degree_order`/`degree_column`
|
|
352
|
+
- `extraction_height`: Already scalar in most configs, deprecate list form
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Summary
|
|
357
|
+
|
|
358
|
+
| Approach | Effort | Flexibility | Complexity |
|
|
359
|
+
|----------|--------|-------------|------------|
|
|
360
|
+
| Option A + per-channel settings | Medium | Per-channel | Single instrument, single abstraction |
|
|
361
|
+
| Option B (9 instruments) | Low | Per-arm | 9 instruments, single abstraction |
|
|
362
|
+
| Option C (4 instruments) | Low | Per-spectrograph | 4 instruments, two abstractions |
|
|
363
|
+
|
|
364
|
+
**Revised Recommendation:**
|
|
365
|
+
|
|
366
|
+
**Option A** is now the most attractive if we implement per-channel settings:
|
|
367
|
+
1. Single instrument, single abstraction level
|
|
368
|
+
2. Maximum flexibility (per-channel tuning)
|
|
369
|
+
3. Follows proven CRIRES+ pattern for file handling
|
|
370
|
+
4. Clean long-term solution
|
|
371
|
+
|
|
372
|
+
**Implementation path:**
|
|
373
|
+
1. Refactor semantic list parameters (`degree` → `degree_order`/`degree_column`, etc.)
|
|
374
|
+
2. Add per-channel settings indexing (~30 lines)
|
|
375
|
+
3. Create ANDES instrument with spectrograph filter (like CRIRES+ band filter)
|
|
376
|
+
|
|
377
|
+
If per-channel settings enhancement is deferred, use **Option C** as interim solution.
|
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [0.7b3] - 2026-01-11
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
- MOSAIC instrument support with fiber group detection and curvature step
|
|
8
|
+
- Extraction animation controls: pause/step buttons and speed control (`PYREDUCE_PLOT_ANIMATION_SPEED`)
|
|
9
|
+
- `--plot-dir` and `--plot-show` CLI options for flexible plot output
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Rename `orders` to `traces` in rectify and slit_curve modules for consistency
|
|
13
|
+
- Downgrade extraction max-iterations message from ERROR to WARNING
|
|
14
|
+
- Only warn about missing files for steps that are actually requested
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Handle channel mismatch gracefully in CLI
|
|
18
|
+
- Curvature plotting index error when peaks need int casting
|
|
19
|
+
|
|
20
|
+
## [0.7b2] - 2026-01-09
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **Reorganize instrument files**: All instrument-related files now in per-instrument directories
|
|
24
|
+
- `instruments/{name}.py` → `instruments/{NAME}/__init__.py`
|
|
25
|
+
- `instruments/{name}.yaml` → `instruments/{NAME}/config.yaml`
|
|
26
|
+
- `settings/settings_{NAME}.json` → `instruments/{NAME}/settings.json`
|
|
27
|
+
- `wavecal/{name}_*.npz` → `instruments/{NAME}/wavecal_*.npz`
|
|
28
|
+
- `masks/mask_{name}_*.fits.gz` → `instruments/{NAME}/mask_*.fits.gz`
|
|
29
|
+
- Base settings and schema moved to `instruments/defaults/`
|
|
30
|
+
- Wavelength atlas files moved to `instruments/defaults/atlas/`
|
|
31
|
+
|
|
32
|
+
### Removed
|
|
33
|
+
- Orphan mask files for undefined instruments (elodie, sarg, hds, etc.)
|
|
34
|
+
|
|
4
35
|
## [0.7b1] - 2026-01-06
|
|
5
36
|
|
|
6
37
|
### Changed
|
|
@@ -41,13 +41,19 @@ pyreduce/
|
|
|
41
41
|
├── instruments/ # Instrument definitions
|
|
42
42
|
│ ├── common.py # Base Instrument class
|
|
43
43
|
│ ├── models.py # Pydantic config models
|
|
44
|
+
│ ├── filters.py # File classification filters
|
|
44
45
|
│ ├── instrument_info.py # Instrument loader
|
|
45
|
-
│ ├──
|
|
46
|
-
│
|
|
47
|
-
│
|
|
48
|
-
├──
|
|
49
|
-
│
|
|
50
|
-
│ └──
|
|
46
|
+
│ ├── defaults/ # Base settings and line atlases
|
|
47
|
+
│ │ ├── settings.json # Default reduction parameters
|
|
48
|
+
│ │ ├── schema.json # Settings validation schema
|
|
49
|
+
│ │ ├── config.yaml # Base instrument config
|
|
50
|
+
│ │ └── atlas/ # Wavelength calibration line lists
|
|
51
|
+
│ └── {INSTRUMENT}/ # Per-instrument directory (e.g., UVES/, HARPS/)
|
|
52
|
+
│ ├── __init__.py # Instrument class
|
|
53
|
+
│ ├── config.yaml # Hardware/header config
|
|
54
|
+
│ ├── settings.json # Reduction parameters
|
|
55
|
+
│ ├── wavecal_*.npz # Pre-computed wavelength solutions
|
|
56
|
+
│ └── mask_*.fits.gz # Bad pixel masks
|
|
51
57
|
│
|
|
52
58
|
└── clib/ # C source for extraction
|
|
53
59
|
├── slit_func_bd.c
|
|
@@ -97,7 +103,7 @@ Each step class has:
|
|
|
97
103
|
|
|
98
104
|
### Instrument Configs (YAML)
|
|
99
105
|
|
|
100
|
-
Location: `pyreduce/instruments
|
|
106
|
+
Location: `pyreduce/instruments/{INSTRUMENT}/config.yaml`
|
|
101
107
|
|
|
102
108
|
Defines what the instrument IS - hardware properties and header mappings:
|
|
103
109
|
|
|
@@ -139,7 +145,7 @@ Validated by Pydantic model `InstrumentConfig` in `models.py`.
|
|
|
139
145
|
|
|
140
146
|
### Reduction Settings (JSON)
|
|
141
147
|
|
|
142
|
-
Location: `pyreduce/settings
|
|
148
|
+
Location: `pyreduce/instruments/{INSTRUMENT}/settings.json`
|
|
143
149
|
|
|
144
150
|
Defines HOW to reduce - algorithm parameters per step:
|
|
145
151
|
|
|
@@ -172,7 +178,7 @@ Defines HOW to reduce - algorithm parameters per step:
|
|
|
172
178
|
}
|
|
173
179
|
```
|
|
174
180
|
|
|
175
|
-
Settings cascade: `
|
|
181
|
+
Settings cascade: `instruments/defaults/settings.json` < `instruments/{INSTRUMENT}/settings.json` < runtime overrides.
|
|
176
182
|
|
|
177
183
|
## Python API
|
|
178
184
|
|
|
@@ -251,8 +257,11 @@ uv run reduce list-steps
|
|
|
251
257
|
## Environment Variables
|
|
252
258
|
|
|
253
259
|
- `REDUCE_DATA` - Base data directory (default: `~/REDUCE_DATA`)
|
|
254
|
-
- `PYREDUCE_PLOT` - Override plot level (0, 1, 2)
|
|
255
|
-
- `PYREDUCE_PLOT_DIR` - Save plots to directory
|
|
260
|
+
- `PYREDUCE_PLOT` - Override plot level (0=off, 1=basic, 2=detailed)
|
|
261
|
+
- `PYREDUCE_PLOT_DIR` - Save plots to directory as PNG files
|
|
262
|
+
- `PYREDUCE_PLOT_SHOW` - Display mode: `block` (default), `defer`, or `off`
|
|
263
|
+
|
|
264
|
+
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.
|
|
256
265
|
|
|
257
266
|
## Development
|
|
258
267
|
|
|
@@ -272,10 +281,12 @@ After a fresh clone or `rm -rf .venv`, run `uv sync && uv run reduce-build` to s
|
|
|
272
281
|
|
|
273
282
|
### Adding Instruments
|
|
274
283
|
|
|
275
|
-
1. Create `pyreduce/instruments/
|
|
276
|
-
2.
|
|
277
|
-
3.
|
|
278
|
-
4. Add
|
|
284
|
+
1. Create `pyreduce/instruments/{NAME}/` directory
|
|
285
|
+
2. Add `config.yaml` with detector/header config
|
|
286
|
+
3. Add `settings.json` for reduction parameters (can use `"__inherits__": "defaults"`)
|
|
287
|
+
4. Add `__init__.py` with instrument class if custom logic needed (optional)
|
|
288
|
+
5. Add wavecal/mask files if available
|
|
289
|
+
6. Add example script to `examples/name_example.py`
|
|
279
290
|
|
|
280
291
|
### Test Organization
|
|
281
292
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreduce-astro
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7b3
|
|
4
4
|
Summary: A data reduction package for echelle spectrographs
|
|
5
5
|
Project-URL: Homepage, https://github.com/ivh/PyReduce
|
|
6
6
|
Project-URL: Documentation, https://pyreduce-astro.readthedocs.io
|
|
@@ -94,6 +94,20 @@ Pipeline.from_instrument(
|
|
|
94
94
|
).run()
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
## Plotting
|
|
98
|
+
|
|
99
|
+
Control plotting with environment variables:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Save plots to files (headless/CI)
|
|
103
|
+
PYREDUCE_PLOT=1 PYREDUCE_PLOT_DIR=/tmp/plots PYREDUCE_PLOT_SHOW=off uv run reduce run ...
|
|
104
|
+
|
|
105
|
+
# Show all plots at end (browser via webagg)
|
|
106
|
+
MPLBACKEND=webagg PYREDUCE_PLOT=1 PYREDUCE_PLOT_SHOW=defer uv run reduce run ...
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
See [How To](https://pyreduce-astro.readthedocs.io/en/latest/howto.html#plot-modes) for details.
|
|
110
|
+
|
|
97
111
|
## Documentation
|
|
98
112
|
|
|
99
113
|
Full documentation at [ReadTheDocs](https://pyreduce-astro.readthedocs.io/).
|
|
@@ -53,6 +53,20 @@ Pipeline.from_instrument(
|
|
|
53
53
|
).run()
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
## Plotting
|
|
57
|
+
|
|
58
|
+
Control plotting with environment variables:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Save plots to files (headless/CI)
|
|
62
|
+
PYREDUCE_PLOT=1 PYREDUCE_PLOT_DIR=/tmp/plots PYREDUCE_PLOT_SHOW=off uv run reduce run ...
|
|
63
|
+
|
|
64
|
+
# Show all plots at end (browser via webagg)
|
|
65
|
+
MPLBACKEND=webagg PYREDUCE_PLOT=1 PYREDUCE_PLOT_SHOW=defer uv run reduce run ...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See [How To](https://pyreduce-astro.readthedocs.io/en/latest/howto.html#plot-modes) for details.
|
|
69
|
+
|
|
56
70
|
## Documentation
|
|
57
71
|
|
|
58
72
|
Full documentation at [ReadTheDocs](https://pyreduce-astro.readthedocs.io/).
|