pyreduce-astro 0.7a7__tar.gz → 0.7b1__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 (200) hide show
  1. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/CHANGELOG.md +22 -0
  2. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/CLAUDE.md +5 -1
  3. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/PKG-INFO +1 -2
  4. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/aj_example.py +1 -1
  5. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/crires_plus_example.py +3 -4
  6. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/custom_instrument_example.py +1 -1
  7. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/harpn_example.py +1 -1
  8. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/harps_example.py +1 -1
  9. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/harps_gridsearch.py +1 -1
  10. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/just_one_swath.py +1 -1
  11. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/jwst_miri_example.py +1 -1
  12. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/jwst_niriss_example.py +1 -1
  13. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/lick_apf_example.py +5 -5
  14. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/mcdonald_example.py +1 -1
  15. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/metis_ifu_example.py +1 -1
  16. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/metis_lss_example.py +1 -1
  17. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/micado_example.py +1 -1
  18. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/neid_example.py +1 -1
  19. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/nirspec_example.py +1 -1
  20. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/toes_example.py +1 -1
  21. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/uves_callfunc.py +1 -1
  22. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/uves_example.py +1 -1
  23. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/examples/xshooter_example.py +2 -2
  24. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyproject.toml +4 -2
  25. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/__main__.py +102 -25
  26. pyreduce_astro-0.7b1/pyreduce/clib/build_extract.py +80 -0
  27. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/cwrappers.py +26 -40
  28. pyreduce_astro-0.7b1/pyreduce/datasets.py +190 -0
  29. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/extract.py +57 -58
  30. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/common.py +36 -19
  31. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/crires_plus.py +25 -0
  32. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/jwst_niriss.py +2 -10
  33. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/pipeline.py +1 -5
  34. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/rectify.py +5 -5
  35. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/reduce.py +84 -59
  36. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_ANDES.json +1 -1
  37. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_CRIRES_PLUS.json +6 -8
  38. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_HARPN.json +1 -1
  39. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_HARPS.json +3 -2
  40. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_LICK_APF.json +6 -5
  41. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_METIS_IFU.json +3 -3
  42. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_METIS_LSS.json +3 -3
  43. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_MICADO.json +3 -3
  44. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_NEID.json +1 -1
  45. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_NTE.json +2 -2
  46. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_UVES.json +1 -1
  47. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_XSHOOTER.json +2 -2
  48. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_pyreduce.json +5 -4
  49. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_schema.json +18 -4
  50. pyreduce_astro-0.7b1/pyreduce/slit_curve.py +739 -0
  51. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/uv.lock +132 -129
  52. pyreduce_astro-0.7a7/pyreduce/clib/build_extract.py +0 -75
  53. pyreduce_astro-0.7a7/pyreduce/datasets.py +0 -238
  54. pyreduce_astro-0.7a7/pyreduce/make_shear.py +0 -607
  55. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/.gitattributes +0 -0
  56. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/.gitignore +0 -0
  57. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/.pre-commit-config.yaml +0 -0
  58. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/.python-version +0 -0
  59. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/.readthedocs.yaml +0 -0
  60. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/AGENTS.md +0 -0
  61. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/LICENSE +0 -0
  62. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/README.md +0 -0
  63. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/hatch_build.py +0 -0
  64. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/__init__.py +0 -0
  65. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/cli.py +0 -0
  66. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clib/__init__.py +0 -0
  67. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clib/slit_func_2d_xi_zeta_bd.c +0 -0
  68. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clib/slit_func_2d_xi_zeta_bd.h +0 -0
  69. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clib/slit_func_bd.c +0 -0
  70. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clib/slit_func_bd.h +0 -0
  71. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/clipnflip.py +0 -0
  72. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/combine_frames.py +0 -0
  73. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/configuration.py +0 -0
  74. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/continuum_normalization.py +0 -0
  75. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/echelle.py +0 -0
  76. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/estimate_background_scatter.py +0 -0
  77. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/extraction_height.py +0 -0
  78. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/__init__.py +0 -0
  79. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/aj.py +0 -0
  80. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/aj.yaml +0 -0
  81. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/andes.py +0 -0
  82. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/andes.yaml +0 -0
  83. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/common.yaml +0 -0
  84. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/crires_plus.yaml +0 -0
  85. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/filters.py +0 -0
  86. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/harpn.py +0 -0
  87. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/harpn.yaml +0 -0
  88. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/harps.py +0 -0
  89. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/harps.yaml +0 -0
  90. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/instrument_info.py +0 -0
  91. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/jwst_miri.py +0 -0
  92. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/jwst_miri.yaml +0 -0
  93. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/jwst_niriss.yaml +0 -0
  94. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/lick_apf.py +0 -0
  95. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/lick_apf.yaml +0 -0
  96. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/mcdonald.py +0 -0
  97. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/mcdonald.yaml +0 -0
  98. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/metis_ifu.py +0 -0
  99. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/metis_ifu.yaml +0 -0
  100. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/metis_lss.py +0 -0
  101. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/metis_lss.yaml +0 -0
  102. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/micado.py +0 -0
  103. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/micado.yaml +0 -0
  104. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/models.py +0 -0
  105. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/neid.py +0 -0
  106. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/neid.yaml +0 -0
  107. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/nirspec.py +0 -0
  108. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/nirspec.yaml +0 -0
  109. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/nte.py +0 -0
  110. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/nte.yaml +0 -0
  111. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/uves.py +0 -0
  112. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/uves.yaml +0 -0
  113. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/xshooter.py +0 -0
  114. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/instruments/xshooter.yaml +0 -0
  115. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_crires_plus_det1.fits.gz +0 -0
  116. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_crires_plus_det2.fits.gz +0 -0
  117. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_crires_plus_det3.fits.gz +0 -0
  118. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_ctio_chiron.fits.gz +0 -0
  119. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_elodie.fits.gz +0 -0
  120. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_feros3.fits.gz +0 -0
  121. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_flames_giraffe.fits.gz +0 -0
  122. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_harps_blue.fits.gz +0 -0
  123. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_harps_red.fits.gz +0 -0
  124. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_hds_blue.fits.gz +0 -0
  125. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_hds_red.fits.gz +0 -0
  126. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_het_hrs_2x5.fits.gz +0 -0
  127. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_jwst_miri_lrs_slitless.fits.gz +0 -0
  128. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_jwst_niriss_gr700xd.fits.gz +0 -0
  129. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_lick_apf_.fits.gz +0 -0
  130. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_mcdonald.fits.gz +0 -0
  131. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_nes.fits.gz +0 -0
  132. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_nirspec_nirspec.fits.gz +0 -0
  133. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_sarg.fits.gz +0 -0
  134. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_sarg_2x2a.fits.gz +0 -0
  135. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_sarg_2x2b.fits.gz +0 -0
  136. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_subaru_hds_red.fits.gz +0 -0
  137. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_blue.fits.gz +0 -0
  138. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_blue_binned_2_2.fits.gz +0 -0
  139. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_middle.fits.gz +0 -0
  140. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_middle_2x2_split.fits.gz +0 -0
  141. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_middle_binned_2_2.fits.gz +0 -0
  142. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_red.fits.gz +0 -0
  143. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_red_2x2.fits.gz +0 -0
  144. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_red_2x2_split.fits.gz +0 -0
  145. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_uves_red_binned_2_2.fits.gz +0 -0
  146. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/masks/mask_xshooter_nir.fits.gz +0 -0
  147. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_AJ.json +0 -0
  148. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_JWST_MIRI.json +0 -0
  149. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_JWST_NIRISS.json +0 -0
  150. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_MCDONALD.json +0 -0
  151. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/settings/settings_NIRSPEC.json +0 -0
  152. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/tools/__init__.py +0 -0
  153. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/tools/combine.py +0 -0
  154. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/trace.py +0 -0
  155. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/util.py +0 -0
  156. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/MICADO_HK_3arcsec_chip5.npz +0 -0
  157. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/atlas/thar.fits +0 -0
  158. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/atlas/thar_list.txt +0 -0
  159. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/atlas/une.fits +0 -0
  160. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/convert.py +0 -0
  161. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/crires_plus_J1228_det1.npz +0 -0
  162. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/crires_plus_J1228_det2.npz +0 -0
  163. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/crires_plus_J1228_det3.npz +0 -0
  164. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/harpn_harpn_2D.npz +0 -0
  165. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/harps_blue_2D.npz +0 -0
  166. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/harps_blue_pol_2D.npz +0 -0
  167. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/harps_red_2D.npz +0 -0
  168. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/harps_red_pol_2D.npz +0 -0
  169. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/mcdonald.npz +0 -0
  170. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/metis_lss_l_2D.npz +0 -0
  171. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/metis_lss_m_2D.npz +0 -0
  172. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/nirspec_K2.npz +0 -0
  173. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_blue_360nm_2D.npz +0 -0
  174. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_blue_390nm_2D.npz +0 -0
  175. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_blue_437nm_2D.npz +0 -0
  176. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_2x2_2D.npz +0 -0
  177. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_565nm_2D.npz +0 -0
  178. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_580nm_2D.npz +0 -0
  179. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_600nm_2D.npz +0 -0
  180. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_665nm_2D.npz +0 -0
  181. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_middle_860nm_2D.npz +0 -0
  182. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_red_580nm_2D.npz +0 -0
  183. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_red_600nm_2D.npz +0 -0
  184. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_red_665nm_2D.npz +0 -0
  185. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_red_760nm_2D.npz +0 -0
  186. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/uves_red_860nm_2D.npz +0 -0
  187. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavecal/xshooter_nir.npz +0 -0
  188. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/pyreduce/wavelength_calibration.py +0 -0
  189. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/argon.line +0 -0
  190. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/bpm_creator.py +0 -0
  191. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/create_wavelength_guess.py +0 -0
  192. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/download_files.py +0 -0
  193. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/ipy_startup.py +0 -0
  194. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/neon.lin +0 -0
  195. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/neon.line +0 -0
  196. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/pymultispec.py +0 -0
  197. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/thar.npz +0 -0
  198. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/wavecal_creator.py +0 -0
  199. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/wavecal_creator_from_existing.py +0 -0
  200. {pyreduce_astro-0.7a7 → pyreduce_astro-0.7b1}/tools/xshooter_nir.json +0 -0
@@ -1,6 +1,28 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## [0.7b1] - 2026-01-06
5
+
6
+ ### Changed
7
+ - **Curvature algorithm rewrite**: Replace 2D model fitting with row-tracking method for better robustness
8
+ - Rename `make_shear.py` to `slit_curve.py`
9
+ - Rename curvature coefficients: `tilt`/`shear` → `p1`/`p2` throughout codebase
10
+ - Rename `arc_extraction` to `simple_extraction`
11
+ - Split curvature `extraction_height` into separate `extraction_height` and `curve_height` parameters
12
+ - Save file renamed from `.shear.npz` to `.curve.npz`
13
+
14
+ ### Added
15
+ - `discover_channels()` for automatic channel detection from data files
16
+ - CLI: `--target` is now optional; loops over all targets if not specified
17
+ - CLI: Uses `$REDUCE_DATA` for base_dir, reads default input_dir from config
18
+ - Comprehensive CLI test coverage
19
+
20
+ ### Fixed
21
+ - Curvature step index error when traces are removed during processing
22
+ - Validate base_dir and input_dir exist with clear error messages
23
+ - File sorting to correctly loop over all nights when not specified
24
+ - CLI dynamic dependency loading for step commands
25
+
4
26
  ## [0.7a7] - 2026-01-04
5
27
 
6
28
  ### Added
@@ -74,7 +74,7 @@ The reduction pipeline consists of these steps (in typical order):
74
74
  | `bias` | `Bias` | Combine bias frames into master bias |
75
75
  | `flat` | `Flat` | Combine flat frames, subtract bias |
76
76
  | `trace` | `OrderTracing` | Trace echelle order positions on flat |
77
- | `curvature` | `SlitCurvatureDetermination` | Measure slit tilt/shear from arc lamp |
77
+ | `curvature` | `SlitCurvatureDetermination` | Measure slit curvature from arc lamp |
78
78
  | `scatter` | `BackgroundScatter` | Model inter-order scattered light |
79
79
  | `norm_flat` | `NormalizeFlatField` | Normalize flat, extract blaze function |
80
80
  | `wavecal_master` | `WavelengthCalibrationMaster` | Extract wavelength calibration spectrum |
@@ -260,12 +260,16 @@ uv run reduce list-steps
260
260
 
261
261
  ```bash
262
262
  uv sync # Install dependencies
263
+ uv run reduce-build # Compile C extensions
264
+ uv run reduce-clean # Remove compiled extensions
263
265
  uv run pre-commit install # Setup hooks (once)
264
266
  uv run pytest -m unit # Fast unit tests
265
267
  uv run pytest --instrument=UVES # Test single instrument
266
268
  uv run ruff check --fix . # Lint and fix
267
269
  ```
268
270
 
271
+ After a fresh clone or `rm -rf .venv`, run `uv sync && uv run reduce-build` to set up.
272
+
269
273
  ### Adding Instruments
270
274
 
271
275
  1. Create `pyreduce/instruments/name.yaml` with detector/header config
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyreduce-astro
3
- Version: 0.7a7
3
+ Version: 0.7b1
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
@@ -37,7 +37,6 @@ Requires-Dist: scikit-image>=0.22.0
37
37
  Requires-Dist: scipy>=1.11.0
38
38
  Requires-Dist: spectres>=2.2.0
39
39
  Requires-Dist: tqdm>=4.66.0
40
- Requires-Dist: wget>=3.2
41
40
  Description-Content-Type: text/markdown
42
41
 
43
42
  [![CI](https://github.com/ivh/PyReduce/actions/workflows/python-publish.yml/badge.svg)](https://github.com/ivh/PyReduce/actions/workflows/python-publish.yml)
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  AJ instrument example: Fiber bundle tracing with direct function calls.
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  Simple usage example for PyReduce
@@ -21,14 +21,14 @@ steps = (
21
21
  # "bias",
22
22
  # "flat",
23
23
  # "trace",
24
- # "curvature",
24
+ "curvature",
25
25
  # "scatter",
26
26
  # "norm_flat",
27
27
  # "wavecal_master",
28
28
  # "wavecal_init",
29
29
  # "wavecal",
30
30
  # "freq_comb_master",
31
- "freq_comb",
31
+ # "freq_comb",
32
32
  # "science",
33
33
  # "continuum",
34
34
  # "finalize",
@@ -48,6 +48,5 @@ Pipeline.from_instrument(
48
48
  base_dir=base_dir,
49
49
  input_dir=input_dir,
50
50
  output_dir=output_dir,
51
- allow_calibration_only=True,
52
51
  # order_range=(0, 4),
53
52
  ).run()
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  import os.path
6
6
 
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  import matplotlib.pyplot as plt
6
6
  import numpy as np
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  Simple usage example for PyReduce
@@ -17,9 +17,9 @@ night = None
17
17
  channel = ""
18
18
  steps = (
19
19
  "bias",
20
- # "flat",
21
- # "trace",
22
- # "norm_flat",
20
+ "flat",
21
+ "trace",
22
+ "norm_flat",
23
23
  # "wavecal",
24
24
  # "curvature",
25
25
  "science",
@@ -42,5 +42,5 @@ Pipeline.from_instrument(
42
42
  input_dir=input_dir,
43
43
  output_dir=output_dir,
44
44
  # order_range=(0, 25),
45
- plot=0,
45
+ plot=1,
46
46
  ).run()
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  NEID reduction example
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  import numpy as np
6
6
 
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  Example showing direct function calls for each step.
@@ -1,6 +1,6 @@
1
1
  # /// script
2
2
  # requires-python = ">=3.13"
3
- # dependencies = ["pyreduce-astro>=0.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
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.7a7"]
3
+ # dependencies = ["pyreduce-astro>=0.7b1"]
4
4
  # ///
5
5
  """
6
6
  Simple usage example for PyReduce
@@ -41,7 +41,7 @@ input_dir = "raw"
41
41
  output_dir = "reduced"
42
42
 
43
43
  config = get_configuration_for_instrument(instrument)
44
- # config["science"]["extraction_method"] = "arc"
44
+ # config["science"]["extraction_method"] = "simple"
45
45
  # config["science"]["extraction_cutoff"] = 0
46
46
 
47
47
  Pipeline.from_instrument(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyreduce-astro"
3
- version = "0.7a7"
3
+ version = "0.7b1"
4
4
  requires-python = ">=3.13"
5
5
  description = "A data reduction package for echelle spectrographs"
6
6
  readme = "README.md"
@@ -42,7 +42,6 @@ dependencies = [
42
42
  "python-dateutil>=2.8.0",
43
43
  "scikit-image>=0.22.0",
44
44
  "tqdm>=4.66.0",
45
- "wget>=3.2",
46
45
  "Pillow>=10.0.0",
47
46
  ]
48
47
 
@@ -55,6 +54,7 @@ dev = [
55
54
  "sphinx>=7.2.0",
56
55
  "ipython>=9.8.0",
57
56
  "myst-parser",
57
+ "setuptools",
58
58
  ]
59
59
 
60
60
  [project.urls]
@@ -65,6 +65,8 @@ Issues = "https://github.com/ivh/PyReduce/issues"
65
65
 
66
66
  [project.scripts]
67
67
  reduce = "pyreduce.__main__:main"
68
+ reduce-build = "pyreduce.clib.build_extract:build"
69
+ reduce-clean = "pyreduce.clib.build_extract:clean"
68
70
 
69
71
  [build-system]
70
72
  requires = ["hatchling>=1.25.0", "cffi>=1.17.1", "setuptools"]
@@ -38,7 +38,7 @@ def cli():
38
38
 
39
39
  @cli.command()
40
40
  @click.argument("instrument")
41
- @click.argument("target")
41
+ @click.option("--target", "-t", default=None, help="Target star name or regex pattern")
42
42
  @click.option("--night", "-n", default=None, help="Observation night (YYYY-MM-DD)")
43
43
  @click.option("--channel", "-c", default=None, help="Instrument channel")
44
44
  @click.option(
@@ -54,7 +54,7 @@ def cli():
54
54
  help="Base directory for data (default: $REDUCE_DATA or ~/REDUCE_DATA)",
55
55
  )
56
56
  @click.option(
57
- "--input-dir", "-i", default="raw", help="Input directory relative to base"
57
+ "--input-dir", "-i", default=None, help="Input directory relative to base"
58
58
  )
59
59
  @click.option(
60
60
  "--output-dir", "-o", default="reduced", help="Output directory relative to base"
@@ -89,7 +89,6 @@ def run(
89
89
  """Run the reduction pipeline.
90
90
 
91
91
  INSTRUMENT: Name of the instrument (e.g., UVES, HARPS, XSHOOTER)
92
- TARGET: Target star name or regex pattern
93
92
  """
94
93
  from .configuration import get_configuration_for_instrument, load_settings_override
95
94
  from .reduce import main as reduce_main
@@ -111,19 +110,22 @@ def run(
111
110
  config = load_settings_override(config, settings)
112
111
 
113
112
  # Run reduction
114
- reduce_main(
115
- instrument=instrument,
116
- target=target,
117
- night=night,
118
- channels=channel,
119
- steps=steps,
120
- base_dir=base_dir or "",
121
- input_dir=input_dir,
122
- output_dir=output_dir,
123
- configuration=config,
124
- order_range=order_range,
125
- plot=plot,
126
- )
113
+ try:
114
+ reduce_main(
115
+ instrument=instrument,
116
+ target=target,
117
+ night=night,
118
+ channels=channel,
119
+ steps=steps,
120
+ base_dir=base_dir,
121
+ input_dir=input_dir,
122
+ output_dir=output_dir,
123
+ configuration=config,
124
+ order_range=order_range,
125
+ plot=plot,
126
+ )
127
+ except FileNotFoundError as e:
128
+ raise click.ClickException(str(e)) from None
127
129
 
128
130
 
129
131
  @cli.command()
@@ -345,31 +347,96 @@ def make_step_command(step_name):
345
347
  config = get_configuration_for_instrument(instrument)
346
348
  if settings:
347
349
  config = load_settings_override(config, settings)
348
- step_config = config.get(step_name, {})
349
- step_config["plot"] = plot
350
350
 
351
- # Get the step class
351
+ # Step classes that support --file (take raw files as input)
352
352
  step_classes = {
353
353
  "bias": reduce_module.Bias,
354
354
  "flat": reduce_module.Flat,
355
355
  "trace": reduce_module.OrderTracing,
356
356
  "curvature": reduce_module.SlitCurvatureDetermination,
357
357
  "scatter": reduce_module.BackgroundScatter,
358
- "norm_flat": reduce_module.NormalizeFlatField,
359
358
  "wavecal_master": reduce_module.WavelengthCalibrationMaster,
360
- "wavecal_init": reduce_module.WavelengthCalibrationInitialize,
361
- "wavecal": reduce_module.WavelengthCalibrationFinalize,
362
359
  "freq_comb_master": reduce_module.LaserFrequencyCombMaster,
363
- "freq_comb": reduce_module.LaserFrequencyCombFinalize,
364
360
  "science": reduce_module.ScienceExtraction,
365
- "continuum": reduce_module.ContinuumNormalization,
366
361
  }
367
362
 
363
+ # Steps that don't take raw files - --file makes no sense
364
+ no_file_steps = {
365
+ "mask",
366
+ "norm_flat",
367
+ "wavecal_init",
368
+ "wavecal",
369
+ "freq_comb",
370
+ "continuum",
371
+ "finalize",
372
+ "rectify",
373
+ }
374
+
375
+ if step_name in no_file_steps:
376
+ raise click.ClickException(
377
+ f"Step '{step_name}' does not accept raw files. "
378
+ f"Run without --file to use the pipeline."
379
+ )
380
+
368
381
  if step_name not in step_classes:
369
382
  raise click.ClickException(
370
383
  f"Step '{step_name}' does not support --file option"
371
384
  )
372
385
 
386
+ def make_step(name):
387
+ """Create a step instance."""
388
+ step_class = {
389
+ "mask": reduce_module.Mask,
390
+ "bias": reduce_module.Bias,
391
+ "flat": reduce_module.Flat,
392
+ "trace": reduce_module.OrderTracing,
393
+ "curvature": reduce_module.SlitCurvatureDetermination,
394
+ "scatter": reduce_module.BackgroundScatter,
395
+ "norm_flat": reduce_module.NormalizeFlatField,
396
+ "wavecal_master": reduce_module.WavelengthCalibrationMaster,
397
+ "freq_comb_master": reduce_module.LaserFrequencyCombMaster,
398
+ "science": reduce_module.ScienceExtraction,
399
+ }.get(name)
400
+ if not step_class:
401
+ return None
402
+ step_config = config.get(name, {}).copy()
403
+ step_config["plot"] = 0 # No plots for dependency loading
404
+ return step_class(
405
+ inst,
406
+ channel,
407
+ target=target or "",
408
+ night=night,
409
+ output_dir=output_dir_full,
410
+ order_range=None,
411
+ **step_config,
412
+ )
413
+
414
+ def load_dependency(name, loaded):
415
+ """Load a dependency from disk."""
416
+ if name in loaded:
417
+ return loaded[name]
418
+ if name == "config":
419
+ loaded["config"] = config
420
+ return config
421
+ dep_step = make_step(name)
422
+ if dep_step is None:
423
+ return None
424
+ # Load this step's dependencies first
425
+ for sub_dep in dep_step.loadDependsOn:
426
+ load_dependency(sub_dep, loaded)
427
+ # Build kwargs for load()
428
+ load_kwargs = {
429
+ d: loaded[d] for d in dep_step.loadDependsOn if d in loaded
430
+ }
431
+ try:
432
+ loaded[name] = dep_step.load(**load_kwargs)
433
+ except FileNotFoundError:
434
+ loaded[name] = None
435
+ return loaded[name]
436
+
437
+ # Create the target step
438
+ step_config = config.get(step_name, {}).copy()
439
+ step_config["plot"] = plot
373
440
  step_class = step_classes[step_name]
374
441
  step = step_class(
375
442
  inst,
@@ -380,7 +447,17 @@ def make_step_command(step_name):
380
447
  order_range=None,
381
448
  **step_config,
382
449
  )
383
- step.run(files=np.array([file]), mask=None, bias=None)
450
+
451
+ # Load all dependencies
452
+ loaded = {}
453
+ for dep in step.dependsOn:
454
+ load_dependency(dep, loaded)
455
+
456
+ # Build kwargs for run()
457
+ run_kwargs = {d: loaded.get(d) for d in step.dependsOn}
458
+ run_kwargs["files"] = np.array([file])
459
+
460
+ step.run(**run_kwargs)
384
461
  else:
385
462
  config = get_configuration_for_instrument(instrument)
386
463
  if settings:
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python3
2
+ """Build script for CFFI C extensions (development only).
3
+
4
+ Usage:
5
+ uv run reduce-build # compile extensions
6
+ uv run reduce-clean # remove compiled files
7
+
8
+ This compiles the C extraction libraries in-place for development.
9
+ For production, extensions are built automatically during wheel creation
10
+ via hatch_build.py.
11
+ """
12
+
13
+ import glob
14
+ import os
15
+
16
+ from cffi import FFI
17
+
18
+ CWD = os.path.dirname(__file__)
19
+ CWD = os.path.abspath(CWD)
20
+ release_path = os.path.join(CWD, "Release")
21
+
22
+
23
+ def clean():
24
+ """Remove compiled extension files."""
25
+ patterns = ["*.so", "*.o", "*.pyd"]
26
+ removed = []
27
+ for pattern in patterns:
28
+ for f in glob.glob(os.path.join(CWD, pattern)):
29
+ os.remove(f)
30
+ removed.append(os.path.basename(f))
31
+ if removed:
32
+ print(f"Removed: {', '.join(removed)}")
33
+ else:
34
+ print("Nothing to clean.")
35
+
36
+
37
+ def build():
38
+ """Build the C slitfunc libraries in-place."""
39
+ print("Building CFFI extensions for development...")
40
+ print(f" Source dir: {CWD}")
41
+
42
+ old_cwd = os.getcwd()
43
+ os.chdir(CWD)
44
+
45
+ try:
46
+ # Vertical extraction
47
+ ffibuilder_vertical = FFI()
48
+ with open("slit_func_bd.h") as f:
49
+ ffibuilder_vertical.cdef(f.read())
50
+ with open("slit_func_bd.c") as f:
51
+ ffibuilder_vertical.set_source(
52
+ "_slitfunc_bd",
53
+ f.read(),
54
+ include_dirs=[CWD, release_path],
55
+ depends=["slit_func_bd.h"],
56
+ )
57
+ ffibuilder_vertical.compile(verbose=True)
58
+ print("[OK] _slitfunc_bd")
59
+
60
+ # Curved extraction
61
+ ffibuilder_curved = FFI()
62
+ with open("slit_func_2d_xi_zeta_bd.h") as f:
63
+ ffibuilder_curved.cdef(f.read())
64
+ with open("slit_func_2d_xi_zeta_bd.c") as f:
65
+ ffibuilder_curved.set_source(
66
+ "_slitfunc_2d",
67
+ f.read(),
68
+ include_dirs=[CWD, release_path],
69
+ depends=["slit_func_2d_xi_zeta_bd.h"],
70
+ )
71
+ ffibuilder_curved.compile(verbose=True)
72
+ print("[OK] _slitfunc_2d")
73
+
74
+ print("Done.")
75
+ finally:
76
+ os.chdir(old_cwd)
77
+
78
+
79
+ if __name__ == "__main__":
80
+ build()