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.
Files changed (235) hide show
  1. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/CHANGELOG.md +27 -0
  2. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/CLAUDE.md +5 -4
  3. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/PKG-INFO +1 -1
  4. pyreduce_astro-0.7b4/examples/andes_yjh_example.py +113 -0
  5. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/crires_plus_example.py +2 -2
  6. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/custom_instrument_example.py +2 -2
  7. pyreduce_astro-0.7b4/examples/debug_single_swath.py +233 -0
  8. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harpn_example.py +2 -2
  9. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harps_example.py +1 -1
  10. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/harps_gridsearch.py +2 -2
  11. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/just_one_swath.py +15 -3
  12. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/jwst_miri_example.py +2 -2
  13. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/jwst_niriss_example.py +2 -2
  14. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/lick_apf_example.py +2 -2
  15. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/mcdonald_example.py +2 -2
  16. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/metis_ifu_example.py +2 -2
  17. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/metis_lss_example.py +2 -2
  18. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/micado_example.py +2 -2
  19. pyreduce_astro-0.7b4/examples/mosaic_nir.py +96 -0
  20. pyreduce_astro-0.7b4/examples/mosaic_preset-slitfunc.py +141 -0
  21. pyreduce_astro-0.7b4/examples/mosaic_vis.py +92 -0
  22. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/neid_example.py +1 -1
  23. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/nirspec_example.py +2 -2
  24. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/toes_example.py +2 -2
  25. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/uves_callfunc.py +3 -3
  26. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/uves_example.py +2 -2
  27. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/examples/xshooter_example.py +2 -3
  28. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyproject.toml +1 -1
  29. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/__main__.py +10 -10
  30. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/cli.py +2 -2
  31. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_2d_xi_zeta_bd.c +152 -118
  32. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_2d_xi_zeta_bd.h +2 -0
  33. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_bd.c +2 -5
  34. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/combine_frames.py +36 -0
  35. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/configuration.py +18 -4
  36. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/cwrappers.py +251 -23
  37. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/estimate_background_scatter.py +23 -23
  38. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/extract.py +289 -191
  39. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/extraction_height.py +14 -14
  40. pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/__init__.py +14 -0
  41. pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/config.yaml +113 -0
  42. pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_h.yaml +9 -0
  43. pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_j.yaml +21 -0
  44. pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH/order_centers_y.yaml +9 -0
  45. {pyreduce_astro-0.7b3/pyreduce/instruments/AJ → pyreduce_astro-0.7b4/pyreduce/instruments/ANDES_YJH}/settings.json +4 -3
  46. pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det1.fits.gz +0 -0
  47. pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det2.fits.gz +0 -0
  48. pyreduce_astro-0.7b4/pyreduce/instruments/CRIRES_PLUS/mask_det3.fits.gz +0 -0
  49. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/settings.json +0 -2
  50. pyreduce_astro-0.7b4/pyreduce/instruments/HARPN/wavecal_harpn_fibB_2D.npz +0 -0
  51. pyreduce_astro-0.7b4/pyreduce/instruments/HARPS/mask_blue.fits.gz +0 -0
  52. pyreduce_astro-0.7b4/pyreduce/instruments/HARPS/mask_red.fits.gz +0 -0
  53. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/settings.json +1 -2
  54. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/mask_lrs_slitless.fits.gz +0 -0
  55. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/mask_gr700xd.fits.gz +0 -0
  56. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/mask_.fits.gz +0 -0
  57. pyreduce_astro-0.7b4/pyreduce/instruments/MCDONALD/mask.fits.gz +0 -0
  58. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/settings.json +1 -4
  59. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/settings.json +1 -4
  60. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/__init__.py +38 -0
  61. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_nir.yaml +92 -0
  62. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis1.yaml +69 -0
  63. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis2.yaml +72 -0
  64. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis3.yaml +87 -0
  65. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/bundle_centers_vis4.yaml +87 -0
  66. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/config.yaml +15 -2
  67. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/mask_nir.fits.gz +0 -0
  68. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/settings.json +5 -10
  69. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS1.json +22 -0
  70. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS2.json +22 -0
  71. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS3.json +22 -0
  72. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_VIS4.json +22 -0
  73. pyreduce_astro-0.7b4/pyreduce/instruments/MOSAIC/settings_nir.json +22 -0
  74. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/settings.json +0 -1
  75. pyreduce_astro-0.7b4/pyreduce/instruments/NIRSPEC/mask_nirspec.fits.gz +0 -0
  76. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/settings.json +0 -2
  77. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_blue.fits.gz +0 -0
  78. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_blue_binned_2_2.fits.gz +0 -0
  79. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle.fits.gz +0 -0
  80. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle_2x2_split.fits.gz +0 -0
  81. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_middle_binned_2_2.fits.gz +0 -0
  82. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red.fits.gz +0 -0
  83. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_2x2.fits.gz +0 -0
  84. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_2x2_split.fits.gz +0 -0
  85. pyreduce_astro-0.7b4/pyreduce/instruments/UVES/mask_red_binned_2_2.fits.gz +0 -0
  86. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/settings.json +2 -2
  87. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/mask_nir.fits.gz +0 -0
  88. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/settings.json +1 -2
  89. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/common.py +3 -0
  90. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/schema.json +50 -142
  91. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/settings.json +7 -9
  92. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/models.py +99 -2
  93. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/pipeline.py +205 -19
  94. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/rectify.py +8 -8
  95. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/reduce.py +366 -126
  96. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/slit_curve.py +18 -88
  97. pyreduce_astro-0.7b4/pyreduce/trace.py +1709 -0
  98. pyreduce_astro-0.7b4/tools/mosaic_vis_bundle_plot.py +66 -0
  99. pyreduce_astro-0.7b4/tools/plot_1d_vs_2d_extraction.py +162 -0
  100. pyreduce_astro-0.7b4/tools/plot_swath_debug.py +64 -0
  101. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/uv.lock +1 -1
  102. pyreduce_astro-0.7b3/examples/aj_example.py +0 -209
  103. pyreduce_astro-0.7b3/examples/mosaic_example.py +0 -171
  104. pyreduce_astro-0.7b3/pyreduce/instruments/AJ/__init__.py +0 -9
  105. pyreduce_astro-0.7b3/pyreduce/instruments/AJ/config.yaml +0 -51
  106. pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/__init__.py +0 -100
  107. pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/config.yaml +0 -72
  108. pyreduce_astro-0.7b3/pyreduce/instruments/ANDES/settings.json +0 -16
  109. pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det1.fits.gz +0 -0
  110. pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det2.fits.gz +0 -0
  111. pyreduce_astro-0.7b3/pyreduce/instruments/CRIRES_PLUS/mask_det3.fits.gz +0 -0
  112. pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_blue.fits.gz +0 -0
  113. pyreduce_astro-0.7b3/pyreduce/instruments/HARPS/mask_red.fits.gz +0 -0
  114. pyreduce_astro-0.7b3/pyreduce/instruments/MCDONALD/mask.fits.gz +0 -0
  115. pyreduce_astro-0.7b3/pyreduce/instruments/MOSAIC/__init__.py +0 -12
  116. pyreduce_astro-0.7b3/pyreduce/instruments/NIRSPEC/mask_nirspec.fits.gz +0 -0
  117. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue.fits.gz +0 -0
  118. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_blue_binned_2_2.fits.gz +0 -0
  119. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle.fits.gz +0 -0
  120. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_2x2_split.fits.gz +0 -0
  121. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_middle_binned_2_2.fits.gz +0 -0
  122. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red.fits.gz +0 -0
  123. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2.fits.gz +0 -0
  124. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_2x2_split.fits.gz +0 -0
  125. pyreduce_astro-0.7b3/pyreduce/instruments/UVES/mask_red_binned_2_2.fits.gz +0 -0
  126. pyreduce_astro-0.7b3/pyreduce/trace.py +0 -985
  127. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.gitattributes +0 -0
  128. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.gitignore +0 -0
  129. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.pre-commit-config.yaml +0 -0
  130. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.python-version +0 -0
  131. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/.readthedocs.yaml +0 -0
  132. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/AGENTS.md +0 -0
  133. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/ANDES_plan.md +0 -0
  134. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/LICENSE +0 -0
  135. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/README.md +0 -0
  136. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/hatch_build.py +0 -0
  137. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/__init__.py +0 -0
  138. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/__init__.py +0 -0
  139. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/build_extract.py +0 -0
  140. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clib/slit_func_bd.h +0 -0
  141. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/clipnflip.py +0 -0
  142. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/continuum_normalization.py +0 -0
  143. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/datasets.py +0 -0
  144. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/echelle.py +0 -0
  145. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/__init__.py +0 -0
  146. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/config.yaml +0 -0
  147. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det1.npz +0 -0
  148. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det2.npz +0 -0
  149. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/CRIRES_PLUS/wavecal_J1228_det3.npz +0 -0
  150. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/__init__.py +0 -0
  151. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/config.yaml +0 -0
  152. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/settings.json +0 -0
  153. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPN/wavecal_harpn_2D.npz +0 -0
  154. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/__init__.py +0 -0
  155. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/config.yaml +0 -0
  156. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_blue_2D.npz +0 -0
  157. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_blue_pol_2D.npz +0 -0
  158. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_red_2D.npz +0 -0
  159. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/HARPS/wavecal_red_pol_2D.npz +0 -0
  160. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/__init__.py +0 -0
  161. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/config.yaml +0 -0
  162. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_MIRI/settings.json +0 -0
  163. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/__init__.py +0 -0
  164. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/config.yaml +0 -0
  165. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/JWST_NIRISS/settings.json +0 -0
  166. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/__init__.py +0 -0
  167. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/config.yaml +0 -0
  168. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/LICK_APF/settings.json +0 -0
  169. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/__init__.py +0 -0
  170. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/config.yaml +0 -0
  171. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/settings.json +0 -0
  172. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MCDONALD/wavecal.npz +0 -0
  173. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/__init__.py +0 -0
  174. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_IFU/config.yaml +0 -0
  175. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/__init__.py +0 -0
  176. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/config.yaml +0 -0
  177. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/settings.json +0 -0
  178. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/wavecal_l_2D.npz +0 -0
  179. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/METIS_LSS/wavecal_m_2D.npz +0 -0
  180. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/__init__.py +0 -0
  181. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/config.yaml +0 -0
  182. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MICADO/wavecal_HK_3arcsec_chip5.npz +0 -0
  183. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/MOSAIC/mosaic_fiber_positions.npz +0 -0
  184. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/__init__.py +0 -0
  185. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NEID/config.yaml +0 -0
  186. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/__init__.py +0 -0
  187. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/config.yaml +0 -0
  188. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/settings.json +0 -0
  189. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NIRSPEC/wavecal_K2.npz +0 -0
  190. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/__init__.py +0 -0
  191. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/NTE/config.yaml +0 -0
  192. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/__init__.py +0 -0
  193. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/config.yaml +0 -0
  194. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_360nm_2D.npz +0 -0
  195. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_390nm_2D.npz +0 -0
  196. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_blue_437nm_2D.npz +0 -0
  197. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_2x2_2D.npz +0 -0
  198. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_565nm_2D.npz +0 -0
  199. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_580nm_2D.npz +0 -0
  200. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_600nm_2D.npz +0 -0
  201. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_665nm_2D.npz +0 -0
  202. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_middle_860nm_2D.npz +0 -0
  203. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_580nm_2D.npz +0 -0
  204. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_600nm_2D.npz +0 -0
  205. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_665nm_2D.npz +0 -0
  206. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_760nm_2D.npz +0 -0
  207. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/UVES/wavecal_red_860nm_2D.npz +0 -0
  208. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/__init__.py +0 -0
  209. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/config.yaml +0 -0
  210. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/XSHOOTER/wavecal_nir.npz +0 -0
  211. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/__init__.py +0 -0
  212. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/thar.fits +0 -0
  213. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/thar_list.txt +0 -0
  214. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/atlas/une.fits +0 -0
  215. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/defaults/config.yaml +0 -0
  216. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/filters.py +0 -0
  217. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/instruments/instrument_info.py +0 -0
  218. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/tools/__init__.py +0 -0
  219. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/tools/combine.py +0 -0
  220. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/util.py +0 -0
  221. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/pyreduce/wavelength_calibration.py +0 -0
  222. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/argon.line +0 -0
  223. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/bpm_creator.py +0 -0
  224. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/convert_wavecal.py +0 -0
  225. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/create_wavelength_guess.py +0 -0
  226. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/download_files.py +0 -0
  227. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/ipy_startup.py +0 -0
  228. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/make_notebook.py +0 -0
  229. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/neon.lin +0 -0
  230. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/neon.line +0 -0
  231. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/pymultispec.py +0 -0
  232. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/thar.npz +0 -0
  233. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/wavecal_creator.py +0 -0
  234. {pyreduce_astro-0.7b3 → pyreduce_astro-0.7b4}/tools/wavecal_creator_from_existing.py +0 -0
  235. {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
- ├── trace_orders.py # Order detection and tracing
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
- "filter_size": 120
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.trace_orders()
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/trace_orders.py` | Order detection and tracing |
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 |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyreduce-astro
3
- Version: 0.7b3
3
+ Version: 0.7b4
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
@@ -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.7b3"]
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
- # order_range=(0, 4),
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.7b3"]
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
- # order_range=order_range,
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.7b3"]
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
- # order_range=(0, 25),
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.7b3"]
3
+ # dependencies = ["pyreduce-astro>=0.7b4"]
4
4
  # ///
5
5
  """
6
6
  Simple usage example for PyReduce
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7b3"]
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", "extraction_cutoff"]:
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.7b3"]
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
- orders = data["orders"]
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(orders[i], ix)
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.7b3"]
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
- # order_range=(0, 25),
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.7b3"]
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
- # order_range=(0, 25),
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.7b3"]
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
- # order_range=(0, 25),
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.7b3"]
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
- # order_range=(0, 25),
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.7b3"]
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
- # order_range=(16, 17),
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.7b3"]
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
- # order_range=(16, 17),
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.7b3"]
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
- order_range=(3, 4),
70
+ trace_range=(3, 4),
71
71
  plot=1,
72
72
  ).run()