spectro-kernel 0.6.2__tar.gz → 0.7.0__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.
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/.gitignore +1 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/CHANGELOG.md +240 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/PKG-INFO +11 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/README.md +10 -0
- spectro_kernel-0.7.0/docs/.drafts/README.md +7 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/concepts/pipelines.md +6 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/be-star-variability.md +2 -2
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/claude-mcp-end-to-end.md +1 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/full-reduction-walkthrough.md +30 -20
- spectro_kernel-0.7.0/docs/recipes/format.md +163 -0
- spectro_kernel-0.7.0/docs/recipes/index.md +125 -0
- spectro_kernel-0.7.0/docs/recipes/share.md +88 -0
- spectro_kernel-0.7.0/docs/tutorials/long-slit-reduction.md +299 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/usage/cli.md +20 -5
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/usage/mcp.md +2 -2
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/why.md +1 -1
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity/_bands.py +128 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity/activity_index_caii_hk.py +313 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity/activity_index_halpha.py +160 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity/ccf_bisector.py +404 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/catalogs/standard_star.py +426 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_edges.py +7 -2
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_max.py +10 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_percentile.py +11 -4
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_polynomial.py +11 -12
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_region.py +7 -2
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/continuum/normalize_spline.py +286 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/corrections/atmospheric_extinction.py +483 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/corrections/deredden_interstellar.py +187 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/io/read_fits.py +153 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/kinematics/vsini_fourier.py +425 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/nebular/balmer_decrement_extinction.py +333 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/quality/measure_resolving_power.py +281 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/smoothing/_kernel_uncertainty.py +122 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/smooth_gaussian.py +28 -5
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/smooth_savgol.py +22 -5
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/stacking/stack.py +213 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/timeseries/_light_curve.py +60 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/timeseries/box_least_squares.py +265 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/timeseries/phase_dispersion_minimization.py +226 -0
- spectro_kernel-0.7.0/src/spectro_kernel/algorithms/timeseries/temporal_variance_spectrum.py +287 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/combine_arithmetic.py +79 -9
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/resample.py +23 -3
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/cli.py +122 -5
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/errors.py +4 -0
- spectro_kernel-0.7.0/src/spectro_kernel/io/fits.py +914 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/pipeline.py +97 -13
- spectro_kernel-0.7.0/src/spectro_kernel/presets/__init__.py +37 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/balmer_quick.yaml +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/embed_quick.yaml +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/quality_report.yaml +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/rv_quick.yaml +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/snr_check.yaml +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/time_series_overview.yaml +2 -0
- spectro_kernel-0.7.0/src/spectro_kernel/presets/catalog/reduction/full_reduction_easyspec.yaml +113 -0
- spectro_kernel-0.7.0/src/spectro_kernel/presets/loader.py +351 -0
- spectro_kernel-0.7.0/src/spectro_kernel/presets/preset.schema.json +65 -0
- spectro_kernel-0.7.0/src/spectro_kernel/presets/variables.py +265 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/enums.py +2 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/version.py +1 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/auto_tools.py +18 -6
- spectro_kernel-0.7.0/src/spectro_mcp/py.typed +0 -0
- spectro_kernel-0.7.0/tests/unit/test_activity_bisector.py +174 -0
- spectro_kernel-0.7.0/tests/unit/test_activity_caii_hk.py +144 -0
- spectro_kernel-0.7.0/tests/unit/test_activity_halpha.py +81 -0
- spectro_kernel-0.7.0/tests/unit/test_combine.py +236 -0
- spectro_kernel-0.7.0/tests/unit/test_flux_atmospheric_extinction.py +270 -0
- spectro_kernel-0.7.0/tests/unit/test_flux_balmer_decrement.py +170 -0
- spectro_kernel-0.7.0/tests/unit/test_flux_deredden_interstellar.py +134 -0
- spectro_kernel-0.7.0/tests/unit/test_flux_standard_star_reference.py +373 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_io.py +33 -0
- spectro_kernel-0.7.0/tests/unit/test_io_fits_zoo.py +476 -0
- spectro_kernel-0.7.0/tests/unit/test_normalize_spline.py +124 -0
- spectro_kernel-0.7.0/tests/unit/test_presets.py +366 -0
- spectro_kernel-0.7.0/tests/unit/test_resolving_power.py +151 -0
- spectro_kernel-0.7.0/tests/unit/test_timeseries_bls.py +157 -0
- spectro_kernel-0.7.0/tests/unit/test_timeseries_pdm.py +133 -0
- spectro_kernel-0.7.0/tests/unit/test_timeseries_tvs.py +210 -0
- spectro_kernel-0.7.0/tests/unit/test_uncertainty_propagation.py +331 -0
- spectro_kernel-0.7.0/tests/unit/test_vsini_fourier.py +200 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/build.py +16 -4
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/generate.py +3 -1
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/generate_catalogue.py +4 -1
- spectro_kernel-0.7.0/tools/docs/generate_recipes.py +300 -0
- spectro_kernel-0.6.2/docs/cookbook/bess-dashboard.md +0 -118
- spectro_kernel-0.6.2/docs/tutorials/long-slit-reduction.md +0 -171
- spectro_kernel-0.6.2/src/spectro_kernel/algorithms/io/read_fits.py +0 -53
- spectro_kernel-0.6.2/src/spectro_kernel/algorithms/stacking/stack.py +0 -110
- spectro_kernel-0.6.2/src/spectro_kernel/io/fits.py +0 -345
- spectro_kernel-0.6.2/src/spectro_kernel/presets/__init__.py +0 -7
- spectro_kernel-0.6.2/src/spectro_kernel/presets/catalog/reduction/full_reduction_easyspec.yaml +0 -68
- spectro_kernel-0.6.2/src/spectro_kernel/presets/loader.py +0 -83
- spectro_kernel-0.6.2/tests/unit/test_combine.py +0 -118
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/LICENSE +0 -0
- {spectro_kernel-0.6.2/docs → spectro_kernel-0.7.0/docs/.drafts}/notebooks/aurora-line-monitor.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/concepts/algorithms.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/concepts/architecture.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/concepts/data-types.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/contributing.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/cookbook/multi-star-viewer.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/cookbook/web-playground.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/getting-started.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_ew_timeseries.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_halpha_phase_stack.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_halpha_timeseries.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_overlay.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pc1_vs_phase.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pca_2d.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pca_3d.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_periodogram.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_phase_folded.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_rv_timeseries.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_similarity.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_similarity_date.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_halpha_phase_stack.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pc1_vs_phase.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pca_2d.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pca_3d.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_periodogram.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_phase_folded.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_rv_timeseries.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_similarity_date.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_similarity_phase.png +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/index.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/alpha-cyg-time-series.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/alpha-dra-binary-period.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/exoplanet-transit-rv.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/native-vs-easyspec-showdown.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/notebooks/your-first-sb2.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/reference.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/tutorials/add-an-algorithm.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/tutorials/analyse-a-spectrum.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/tutorials/discover-the-catalogue.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/tutorials/first-spectrum.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/docs/usage/library.md +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/pyproject.toml +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/adapters/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/adapters/easyspec.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/_common.py +0 -0
- {spectro_kernel-0.6.2/src/spectro_kernel/algorithms/classification → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity}/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/aperture_photometry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/disentangle_sb2.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/doppler_tomogram.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/gaia.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/simbad.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/vizier.py +0 -0
- {spectro_kernel-0.6.2/src/spectro_kernel/algorithms/embedding → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/classification}/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/classification/classify_template_chi2.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/classification/pickles_atlas.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/compare_normalisations.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/subtract_continuum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/air_vacuum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/barycentric.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/doppler_shift.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/extinction_correct_easyspec.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/fit_telluric_scaling.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/flux_calibrate_easyspec.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/remove_telluric.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/response_from_standard.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/synth_telluric.py +0 -0
- {spectro_kernel-0.6.2/src/spectro_kernel/algorithms/kinematics → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/embedding}/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_band_power.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_continuum_subtracted.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_lick_indices.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_log_lambda.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_pretrained.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_remote.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_spectrum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_wavelets.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/_bess_contract.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_csv.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_fits.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_fits_bess.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_hdf5.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_votable.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/boxcar.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/detect_trace.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/easyspec_extract.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/optimal.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/sky_lateral_bands.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_ascii.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_echelle.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_sdss.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_votable.py +0 -0
- {spectro_kernel-0.6.2/src/spectro_kernel/algorithms/nebular → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/kinematics}/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/kinematics/rotation_curve.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/_line_flux.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/_profiles.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/catalogs.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/compare_line_fits.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/detect.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/equivalent_width.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_gaussian.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_lorentzian.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_voigt.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/vr_ratio.py +0 -0
- /spectro_kernel-0.6.2/src/spectro_kernel/py.typed → /spectro_kernel-0.7.0/src/spectro_kernel/algorithms/nebular/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/bpt_line_ratios.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/oiii_electron_temperature.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/sii_electron_density.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/compare_snr_methods.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_der.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_edge.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_linear_fit.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/validate_bess_header.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/_easyspec_apply.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/_easyspec_helpers.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/bias_combine.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/clip_cosmic_rays.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/dark_combine.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/dark_subtract.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/denoise_2d.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_bias.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_cosmic_ray.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_dark.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_flat.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_flat_normalize.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_subtract_bias.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_subtract_dark.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/extract_spectrum_sum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/flat_combine.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/flat_normalize.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/geometry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/subtract_sky_2d.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/wavelength_calibrate.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/cross_correlate.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/fit_keplerian_orbit.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/measure.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/precision_bouchy.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/redshift_lines.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/_nan_bridge.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/compare_smoothings.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/stacking/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/stacking/merge_echelle_orders.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/lomb_scargle.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/phase_fold.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/clip_sigma.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/extract_region.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/mask_range.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/resample_flux_conserving.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_3d_surface.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_animation.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_dynamic_spectrum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_plotly.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/arc_geometry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/easyspec_wavelength.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/in_situ.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/lamp_atlas.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/match_lamp.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/reidentify.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/solar.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/base.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/embeddings.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/io/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/io/ascii.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/io/votable.py +0 -0
- {spectro_kernel-0.6.2/src/spectro_mcp → spectro_kernel-0.7.0/src/spectro_kernel}/py.typed +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/registry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/catalog.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/context.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/history.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/image.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/line.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/spectrum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/types/timeseries.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_kernel/url_safety.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/__main__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/auth.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/observability.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/server.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/session.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/src/spectro_mcp/url_safety.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/conftest.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/reference/conftest.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/reference/test_known_answers.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/reference/test_sun.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/reference/test_vega.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_aperture_photometry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_barycentric_bjd.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_base.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_catalog_queries_mocked.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_classify_template_chi2.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_cli.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_combine_arithmetic.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_continuum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_corrections.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_cross_correlate_extension.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_dark_flat_combine.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_denoise_2d.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_detect_lines_blind.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_detect_trace.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_disentangle_sb2.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_doppler_tomogram.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_apply_staging.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_sessions.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_wrappers.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_embedding.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_embedding_pretrained.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_embedding_remote_lick.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_embedding_tier1.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_export_fits_bess.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_export_hdf5.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_extract_boxcar.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_extract_optimal.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_extract_spectrum_sum.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_flux_calibrate_easyspec.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_geometry_corrections.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_lamp_atlas_match.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_line_profiles.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_lines.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp_http_entry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp_param_guard.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp_production.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp_security.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_mcp_tools_extra.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_measure_arc_geometry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_misc_algorithms.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_nebular_diagnostics.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_no_circular_imports.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_normalize_to_region.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_output_produces_contract.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_pipeline.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_quality.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_read_sdss.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_redshift_lines.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_registry.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_reidentify.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_resample_flux_conserving.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_response_from_standard.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_rotation_curve.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_rv_precision_bouchy.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_sky_lateral_bands.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_smoothing.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_timeseries.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_transforms.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_types.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_url_safety_kernel.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_validate_bess_header.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_viz.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_vr_ratio.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_wavelength_calibration_in_situ.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tests/unit/test_wavelength_calibration_solar.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/__init__.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/generate_llms.py +0 -0
- {spectro_kernel-0.6.2 → spectro_kernel-0.7.0}/tools/docs/netlify.toml +0 -0
|
@@ -6,6 +6,246 @@ Until `1.0.0` the public API may change between minor versions.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.7.0] — 2026-09-26
|
|
10
|
+
|
|
11
|
+
The release that turns presets into **recipes** : a measurement written once,
|
|
12
|
+
with its conventions fixed and everything instrument-dependent declared as a
|
|
13
|
+
variable, so that observers with different spectrographs produce comparable
|
|
14
|
+
numbers. It also lands the bricks those recipes need for pro-am campaigns
|
|
15
|
+
(time-series line-profile analysis, the flux-calibration chain, stellar
|
|
16
|
+
activity and rotation indicators, resolving power, spline continuum) and a
|
|
17
|
+
FITS reader that copes with the amateur "zoo". Numerical changes are carried
|
|
18
|
+
by MAJOR bumps of the bricks concerned and listed below.
|
|
19
|
+
|
|
20
|
+
### Added — recipes, variables and profiles (presets v2)
|
|
21
|
+
|
|
22
|
+
- A preset may declare a `variables` block (`type` among `str`, `int`,
|
|
23
|
+
`float`, `bool`, `path`, `list`; `default`, `required`, `description`,
|
|
24
|
+
`choices`) and reference them as `"${name}"` in step parameters. The
|
|
25
|
+
values come from a **profile** (`spectro pipeline <recipe> --profile
|
|
26
|
+
file.yaml`), from `--set name=value` (converted to the declared type),
|
|
27
|
+
from `PipelineBuilder().from_preset(name, variables={...})` /
|
|
28
|
+
`from_config(config, variables)`, or from the `variables` argument of
|
|
29
|
+
the MCP `run_preset` tool. Defaults fill the gaps ; a missing required
|
|
30
|
+
variable, an undeclared token or a value of the wrong type is refused
|
|
31
|
+
before anything runs, with the variable's description in the message.
|
|
32
|
+
A preset without `variables` is unchanged.
|
|
33
|
+
- `requires: ">=0.7, <1.0"` : the kernel range a recipe was validated for
|
|
34
|
+
(plain comparison operators) ; a recipe outside the range refuses to build.
|
|
35
|
+
- Standard metadata vocabulary : `kind` (`analysis`, `reduction`,
|
|
36
|
+
`campaign`, `template`), `status` (`draft`, `reviewed`, `reference`),
|
|
37
|
+
`references` (mandatory for a campaign recipe), `conventions`.
|
|
38
|
+
- **Discovery** : besides the bundled catalogue, the kernel lists recipes
|
|
39
|
+
from every directory in `SPECTRO_PRESET_PATH` and from installed
|
|
40
|
+
packages registering the `spectro_kernel.presets` entry point (a
|
|
41
|
+
`Path` to a directory of YAML files). `list_presets()` reports each
|
|
42
|
+
recipe's `source` ; a bundled name wins over an external one.
|
|
43
|
+
- **Validation** : `spectro preset validate <file-or-name>...` (also
|
|
44
|
+
`--profile` / `--set` to type-check values) reports every problem at
|
|
45
|
+
once : name not snake_case, missing or malformed version, missing
|
|
46
|
+
description, unknown `kind` / `status`, campaign recipe without
|
|
47
|
+
references, unsatisfied `requires`, unknown algorithm, unknown parameter,
|
|
48
|
+
required parameter neither set nor bound, undeclared token, unused
|
|
49
|
+
variable, `depends_on` matching no step. `spectro preset show <name>`
|
|
50
|
+
prints a recipe's variables and steps ; `spectro presets` shows the
|
|
51
|
+
source and the number of variables. Python : `validate_preset`,
|
|
52
|
+
`validate_preset_file`, `preset_sources`, `find_preset`.
|
|
53
|
+
- **Provenance** : every named pipeline built from a file or a config
|
|
54
|
+
closes its run with a `pipeline:<name>` `ProcessingStep` carrying the
|
|
55
|
+
recipe version, the bound variables, the kernel version and the source,
|
|
56
|
+
so a result states which recipe produced it. Ad-hoc pipelines assembled
|
|
57
|
+
in Python without a name are unchanged.
|
|
58
|
+
- The bundled `full_reduction_easyspec` template (2.0.0) replaces its
|
|
59
|
+
`__REPLACE__` placeholders by ten declared variables (`bias_dir`,
|
|
60
|
+
`dark_dir`, `flat_dir`, `science_path`, `exposure_seconds`, `airmass`,
|
|
61
|
+
`gain`, `readnoise`, `target_name`, `combine_method`) ; the six analysis
|
|
62
|
+
presets gain `kind` and `status` metadata. The preset file format is
|
|
63
|
+
published as `preset.schema.json`.
|
|
64
|
+
- The curated collection lives in a separate repository,
|
|
65
|
+
[spectro-kernel-recipes](https://github.com/matthieulel/spectro-kernel-recipes)
|
|
66
|
+
(`pip install spectro-kernel-recipes`), starting with `be_halpha_ew`,
|
|
67
|
+
`binary_rv_ccf`, `solar_long_slit` and `stellar_long_slit` (all `draft`).
|
|
68
|
+
|
|
69
|
+
### Added — time-series line-profile analysis (category `timeseries`, `stacking`)
|
|
70
|
+
|
|
71
|
+
- **`temporal_variance_spectrum` v1.0.0** (scipy) — Fullerton, Gies & Bolton
|
|
72
|
+
1996, ApJS 103, 475, §3 : N ≥ 3 continuum-normalised epochs in
|
|
73
|
+
`ctx.spectra`, resampled on the finest common grid over the overlap ;
|
|
74
|
+
per-epoch noise σ_ic from `uncertainty` or DER_SNR on a continuum window
|
|
75
|
+
(`continuum_lo` / `continuum_hi`) ; weights w_i = (σ_0/σ_ic)² with
|
|
76
|
+
σ_0 = [(1/N) Σ σ_ic⁻²]^(−1/2) ; (TVS)_j = (N−1)⁻¹ Σ_i w_i (S_ij − S̄_j)² ;
|
|
77
|
+
reported as (TVS)^{1/2} with the χ²_(N−1) significance threshold at
|
|
78
|
+
`confidence` (0.99). Writes `extras.tvs` and the `tvs_*` metrics, the
|
|
79
|
+
bounds of the longest significant run as `tvs_variable_lo_aa` /
|
|
80
|
+
`tvs_variable_hi_aa`. Caveat documented : the pixel-dependent
|
|
81
|
+
photon-noise term α_ij of the paper is not applied (uniform noise across
|
|
82
|
+
the profile). Tests : variability confined to |v| < 120 km/s → 71 % of
|
|
83
|
+
pixels flagged inside, 2.2 % beyond 200 km/s ; no variability → 1.2 %
|
|
84
|
+
above the 99 % threshold ; threshold exact to 1e-12.
|
|
85
|
+
- **`phase_dispersion_minimization` v1.0.0** (numpy) — Stellingwerf 1978,
|
|
86
|
+
ApJ 224, 953 : Θ = s²/σ² over M = N_b·N_c overlapping phase samples
|
|
87
|
+
(`n_bins` 10, `n_covers` 3), uniform frequency grid (`n_periods` 2000),
|
|
88
|
+
light-curve input exactly as `lomb_scargle`. `ctx.periodograms[key]`
|
|
89
|
+
carries Θ with `meta.lower_is_better` ; metrics `pdm_best_period_days`,
|
|
90
|
+
`pdm_theta_min`. No false-alarm probability on purpose
|
|
91
|
+
(Schwarzenberg-Czerny 1997, ApJ 489, 941). Tests : eclipse and sawtooth
|
|
92
|
+
signals at 3.7 d over 60 d recovered to 0.11 % ; pure noise → Θ ≈ 1.00.
|
|
93
|
+
- **`box_least_squares` v1.0.0** (astropy) — Kovács, Zucker & Mazeh 2002,
|
|
94
|
+
A&A 391, 369, wrapping `astropy.timeseries.BoxLeastSquares` ;
|
|
95
|
+
`duration_hours` list, `objective` likelihood / snr ; periodogram plus
|
|
96
|
+
`extras.bls_model` and the `bls_*` metrics. Without uncertainties the
|
|
97
|
+
noise is 1.4826·MAD (Rousseeuw & Croux 1993) instead of astropy's
|
|
98
|
+
implicit σ = 1 (which gave a 41-σ transit an SNR of 0.09). Tests :
|
|
99
|
+
P = 2.5 d, depth 1 %, 3 h box on a 30 d series → period to 0.012 %,
|
|
100
|
+
depth to 1.8 %, SNR 41.
|
|
101
|
+
- **`stack_spectra` 2.0.0 → 2.1.0** (additive) : `method: "weighted"`, the
|
|
102
|
+
Bevington & Robinson inverse-variance mean with the stack uncertainty
|
|
103
|
+
(Σ w)^(−1/2) ; weights from the `weights` parameter, else from every
|
|
104
|
+
spectrum's `uncertainty`, else from DER_SNR² (Tody 1993, IRAF `scombine`).
|
|
105
|
+
mean / median / sum are bit-identical to v2.0.0. Test : σ = 1 and 2 →
|
|
106
|
+
weights 4:1, output σ = 1/√1.25.
|
|
107
|
+
|
|
108
|
+
### Added — flux-calibration chain (categories `correction`, `catalog`, `nebular`)
|
|
109
|
+
|
|
110
|
+
- **`atmospheric_extinction_correct` v1.0.0** (numpy) — F_0 = F·10^{0.4 k(λ) X}
|
|
111
|
+
(Hayes & Latham 1975, ApJ 197, 593 ; Hardie 1962). Built-in `curve`
|
|
112
|
+
`"kpno"`, the IRAF `onedstds$kpnoextinct.dat` mean extinction table
|
|
113
|
+
(3200–10400 Å, Tody 1986 ; all 82 nodes checked against the IRAF source,
|
|
114
|
+
the last four being CTIO values), or a user table in `ctx.extras`. Airmass from
|
|
115
|
+
`airmass`, else from the header / site with Kasten & Young 1989, Appl.
|
|
116
|
+
Opt. 28, 4735, eq. 3. Uncertainty scaled with the flux. Metrics
|
|
117
|
+
`airmass`, `k_mag_median`, `n_outside_curve`.
|
|
118
|
+
- **`deredden_interstellar` v1.0.0** (dust_extinction, optional extra
|
|
119
|
+
`reduction`) — F_0 = F / 10^{−0.4 A(λ)} with CCM89 (Cardelli, Clayton &
|
|
120
|
+
Mathis 1989, ApJ 345, 245 ; default), F99 (Fitzpatrick 1999, PASP 111,
|
|
121
|
+
63) or G23 (Gordon et al. 2023, ApJ 950, 86) ; `ebv`, `rv` (3.1) ; fails
|
|
122
|
+
outside a law's validity range. Test : CCM89, R_V = 3.1, E(B−V) = 0.1 at
|
|
123
|
+
5500 Å → factor 10^{0.4·0.31} = 1.330, checked against the package.
|
|
124
|
+
- **`standard_star_reference` v1.0.0** (astropy ; network, lazy) — loads a
|
|
125
|
+
CALSPEC standard (Bohlin, Gordon & Tremblay 2014, PASP 126, 711 ; Bohlin,
|
|
126
|
+
Hubeny & Rauch 2020, AJ 160, 21) by name or `filename` from the STScI
|
|
127
|
+
reference-atlas archive through the SSRF-guarded fetch with timeout and
|
|
128
|
+
size cap, or a Pickles 1998 (PASP 110, 863) template ; vacuum → air with
|
|
129
|
+
Morton 2000 (`to_air`) ; writes `extras.catalog_spectrum` (rename with
|
|
130
|
+
`output_key`, e.g. to `reference_spectrum` for `response_from_standard`).
|
|
131
|
+
Pickles templates are normalised to unity at 5556 Å by construction
|
|
132
|
+
(Pickles 1998, §3 and §5) and passed through unchanged ; the brick reports
|
|
133
|
+
`flux_at_5556_aa` so the caller can see it.
|
|
134
|
+
- **`balmer_decrement_extinction` v1.0.0** (scipy) — c(Hβ), E(B−V) and A_V
|
|
135
|
+
from the observed Hα/Hβ ratio against Case B 2.86 (Osterbrock & Ferland
|
|
136
|
+
2006, Table 4.4, §7.2) with the CCM89 f(λ) ; negative extinction clamped
|
|
137
|
+
to 0 with a note ; metrics `balmer_ratio_observed`, `c_hbeta`,
|
|
138
|
+
`ebv_balmer`, `a_v_balmer`, `flux_halpha`, `flux_hbeta`.
|
|
139
|
+
|
|
140
|
+
### Changed — uncertainties are now propagated (MAJOR bumps ; flux byte-identical)
|
|
141
|
+
|
|
142
|
+
Until now every one of these bricks copied the input `uncertainty` array
|
|
143
|
+
unchanged, which is wrong after any of them. Each now documents its rule ;
|
|
144
|
+
a spectrum without uncertainty is processed exactly as before.
|
|
145
|
+
|
|
146
|
+
- `smooth_gaussian` 1.0.1 → 2.0.0 and `smooth_savgol` 1.0.1 → 2.0.0 :
|
|
147
|
+
σ_out,i = sqrt(Σ_k w_k² σ²) with the very kernel applied (Gaussian
|
|
148
|
+
truncated at 4σ ; Savitzky-Golay coefficients incl. the edge polynomials).
|
|
149
|
+
White noise, sigma = 2 px → σ_out = 0.376 σ in the interior and 0.641 σ
|
|
150
|
+
at the first and last samples (the 'nearest' edge weights add before
|
|
151
|
+
squaring) ; window 11 / order 3 → 0.4555 σ. Both checked against the full
|
|
152
|
+
linear operator to 1e-9 and by Monte-Carlo. Correlated noise is not
|
|
153
|
+
tracked (documented).
|
|
154
|
+
- `normalize_polynomial` 1.1.1 → 2.0.0, `normalize_to_region` 1.0.1 →
|
|
155
|
+
2.0.0, `normalize_max` 1.0.2 → 2.0.0, `normalize_percentile` 1.0.2 →
|
|
156
|
+
2.0.0, `normalize_edges` 1.0.2 → 2.0.0 : σ_out = σ_in / |continuum|,
|
|
157
|
+
continuum treated as noise-free.
|
|
158
|
+
- `resample_linear` 1.0.1 → 2.0.0 : σ_out = sqrt(interp(σ²)) (linear
|
|
159
|
+
interpolation of the variance ; v1 interpolated σ itself).
|
|
160
|
+
- `combine_spectra_arithmetic` 1.0.1 → 2.0.0 : add/sub in quadrature ;
|
|
161
|
+
mul/div with the relative errors in quadrature when the reference
|
|
162
|
+
carries an uncertainty (Bevington & Robinson §3.2), else σ·|r| or σ/|r|.
|
|
163
|
+
|
|
164
|
+
### Added — stellar activity, rotation, resolution, continuum (new category `activity`)
|
|
165
|
+
|
|
166
|
+
- **`activity_index_caii_hk` v1.0.0** (numpy, `activity`) — the Mount
|
|
167
|
+
Wilson S index, S = α (H + K)/(R + V) with the HKP-2 triangular 1.09 Å
|
|
168
|
+
H and K bands and the 20 Å R and V bands (Vaughan, Preston & Wilson 1978,
|
|
169
|
+
PASP 90, 267 ; Duncan et al. 1991, ApJS 76, 383), `alpha` 2.3 (échelle
|
|
170
|
+
convention, Lovis et al. 2011) with an optional linear calibration to the
|
|
171
|
+
Mount Wilson scale ; log R'_HK when `b_v` is given (Noyes et al. 1984,
|
|
172
|
+
ApJ 279, 763 ; Middelkoop 1982, A&A 107, 31). Fails outside 3890–4011 Å.
|
|
173
|
+
- **`activity_index_halpha` v1.0.0** (numpy, `activity`) — Gomes da Silva
|
|
174
|
+
et al. 2011, A&A 534, A30 (after Boisse et al. 2009, A&A 495, 959) : 1.6 Å
|
|
175
|
+
core at 6562.808 Å over the 6550.87 ± 5.375 Å and 6580.31 ± 4.375 Å
|
|
176
|
+
reference bands ; `halpha_index` and its error.
|
|
177
|
+
- **`ccf_bisector` v1.0.0** (numpy, `activity`) — bisector of the CCF
|
|
178
|
+
written by `cross_correlate_rv` (or of one line of the spectrum) after
|
|
179
|
+
Toner & Gray 1988, ApJ 334, 1008, and the bisector inverse slope BIS =
|
|
180
|
+
v_top(10–40 %) − v_bottom(55–90 %) of Queloz et al. 2001, A&A 379, 279 ;
|
|
181
|
+
`bis_kms`, `bisector_span_kms`, `extras.ccf_bisector`. Symmetric profile
|
|
182
|
+
→ BIS = 0 within 0.01 km/s.
|
|
183
|
+
- **`vsini_fourier` v1.0.0** (scipy, `kinematics`) — v sin i from the first
|
|
184
|
+
zero of the Fourier transform of a line profile (Carroll 1933, MNRAS 93,
|
|
185
|
+
478 ; Gray 2005, ch. 18) with q₁(ε) from Dravins, Lindegren & Nordlund
|
|
186
|
+
1990, A&A 228, 203 (`epsilon` 0.6 → q₁ = 0.660) ; the first zero is
|
|
187
|
+
accepted only when the side lobe stands above the Fourier noise floor
|
|
188
|
+
(`metrics.fourier_noise_floor`, `fourier_sidelobe_ratio`), and unresolved,
|
|
189
|
+
emission or noise-dominated lines fail explicitly. Tests : 30, 80 and
|
|
190
|
+
150 km/s recovered within 5 % at 0.5 % noise. Reference to the modern
|
|
191
|
+
recipe : Díaz, González, Levato & Grosso 2011, A&A 531, A143.
|
|
192
|
+
- **`measure_resolving_power` v1.0.0** (scipy, `quality`) — R = λ/FWHM from
|
|
193
|
+
Gaussian fits of the `n_lines` strongest isolated lamp / sky lines
|
|
194
|
+
(isolation by `min_separation_aa`), median and scatter of R, instrumental
|
|
195
|
+
FWHM in Å and km/s (Gray 2005, ch. 12 ; Tody 1986, IRAF `splot`). Test :
|
|
196
|
+
12 lines of FWHM = λ/5000 → R = 5000 ± 2 %.
|
|
197
|
+
- **`normalize_spline` v1.0.0** (scipy, `continuum`) — the IRAF
|
|
198
|
+
`continuum` recipe (Tody 1986 ; Tody 1993) : iteratively clipped cubic
|
|
199
|
+
spline (`n_knots`, `low_reject` 2.0, `high_reject` 3.0, `niterate` 10,
|
|
200
|
+
`grow` 0), `extras.continuum_spline`, σ/continuum propagated ;
|
|
201
|
+
cross-references `normalize_polynomial`.
|
|
202
|
+
|
|
203
|
+
### Changed — FITS reading and writing (`read_fits` 2.0.0 → 3.0.0, `io/fits.py`)
|
|
204
|
+
|
|
205
|
+
The reader now takes explicit, documented decisions on the FITS "zoo"
|
|
206
|
+
(audit items C6 / C7) ; 37 new tests in `test_io_fits_zoo.py`.
|
|
207
|
+
|
|
208
|
+
- `CD1_1` wins over `CDELT1` when both exist (Greisen & Calabretta 2002 ;
|
|
209
|
+
v2 preferred `CDELT1`), `PC1_1` scales `CDELT1` ; `CUNIT1` (or IRAF
|
|
210
|
+
`WAT1` units) in nm / µm / m converted to Å with the original label in
|
|
211
|
+
`meta["wavelength_unit_original"]` ; WAVE-LOG (Paper III) and IRAF
|
|
212
|
+
`DC-FLAG` handling unchanged.
|
|
213
|
+
- No dispersion keywords → 0-based pixel axis, `wavelength_unit="pixel"`,
|
|
214
|
+
`meta["wcs"]="none"` (v2 labelled the pixel index "Angstrom").
|
|
215
|
+
- A genuine 2-D image is refused unless the new `row` parameter selects a
|
|
216
|
+
row (v2 silently returned row 0) ; length-1 axes are squeezed ; IRAF
|
|
217
|
+
multispec / échelle markers redirect to `read_echelle_fits` ; 3-D cubes
|
|
218
|
+
are refused.
|
|
219
|
+
- Extension selection : a data-bearing PRIMARY wins over tables (v2
|
|
220
|
+
preferred any table) ; otherwise the first table with recognisable
|
|
221
|
+
wavelength / flux columns (incl. SDSS `loglam`) ; the new `hdu`
|
|
222
|
+
parameter (index or EXTNAME) overrides ; when nothing is readable the
|
|
223
|
+
error lists the HDUs found.
|
|
224
|
+
- `ERROR` / `ERR` / `ERRS` / `SIGMA` / `UNCERT(AINTY)` (1σ) and `IVAR`
|
|
225
|
+
(1/√ivar) image extensions and error / ivar table columns fill
|
|
226
|
+
`uncertainty` ; `MASK` extensions and `mask` / `and_mask` columns fill
|
|
227
|
+
`mask` ; `BUNIT` becomes the flux unit ; descending axes are kept and
|
|
228
|
+
flagged `meta["wavelength_descending"]`.
|
|
229
|
+
- `write_fits` : the linear layout now appends `ERROR` and `MASK`
|
|
230
|
+
extensions when the spectrum carries them, read back by `read_fits`
|
|
231
|
+
(round-trip tested) ; a spectrum without either is still a single HDU.
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
### Documentation
|
|
235
|
+
|
|
236
|
+
- A new **Recipes** section (the recipe / profile idea, the format
|
|
237
|
+
reference, how to share a recipe) and a generated recipe catalogue with
|
|
238
|
+
one page per recipe plus `/ai/presets.json` ; the CLI, MCP, pipelines and
|
|
239
|
+
reduction-walkthrough pages updated accordingly.
|
|
240
|
+
|
|
241
|
+
- The long-slit tutorial is now worked on a **solar** spectrum (Fraunhofer
|
|
242
|
+
wavelength calibration, no lamp) with a **stellar** arc-lamp variant ;
|
|
243
|
+
the aurora example is gone. Its code samples were also corrected : the
|
|
244
|
+
2-D reduction runs from Python (`spectro pipeline` loads 1-D spectra) and
|
|
245
|
+
the lamp hand-off uses the real `lamp_identifications` keys.
|
|
246
|
+
- The BeSS-dashboard cookbook page is removed ; the aurora line-monitor
|
|
247
|
+
notebook is parked in `docs/.drafts/` (not published) for a later return.
|
|
248
|
+
|
|
9
249
|
## [0.6.2] — 2026-09-19
|
|
10
250
|
|
|
11
251
|
A documentation and web release : the docs move to a generated,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: spectro-kernel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A shared catalogue of astronomical spectroscopy algorithms, composable into reproducible pipelines, usable as a Python library, a CLI, or an MCP server.
|
|
5
5
|
Project-URL: Homepage, https://github.com/matthieulel/spectro-kernel
|
|
6
6
|
Project-URL: Documentation, https://docs.spectrokernel.io/
|
|
@@ -210,6 +210,16 @@ by environment variable (none of these affect stdio mode) :
|
|
|
210
210
|
| `SPECTRO_MCP_S3_BUCKET`, `SPECTRO_MCP_S3_ENDPOINT`, … | unset | Presigned-URL uploads (`request_upload_url`). |
|
|
211
211
|
| `SENTRY_DSN` | unset | Error reporting. |
|
|
212
212
|
|
|
213
|
+
## Recipes and profiles
|
|
214
|
+
|
|
215
|
+
A recipe (preset) is a measurement written once with its conventions fixed;
|
|
216
|
+
what depends on your instrument is a variable, bound by a profile at run
|
|
217
|
+
time: `spectro pipeline be_halpha_ew --input obs.fits --profile my_setup.yaml`.
|
|
218
|
+
Generic recipes ship with the kernel; campaign recipes live in the curated
|
|
219
|
+
[spectro-kernel-recipes](https://github.com/matthieulel/spectro-kernel-recipes)
|
|
220
|
+
collection (`pip install spectro-kernel-recipes`). See the
|
|
221
|
+
[Recipes](https://docs.spectrokernel.io/recipes/) documentation.
|
|
222
|
+
|
|
213
223
|
## Architecture
|
|
214
224
|
|
|
215
225
|
```
|
|
@@ -121,6 +121,16 @@ by environment variable (none of these affect stdio mode) :
|
|
|
121
121
|
| `SPECTRO_MCP_S3_BUCKET`, `SPECTRO_MCP_S3_ENDPOINT`, … | unset | Presigned-URL uploads (`request_upload_url`). |
|
|
122
122
|
| `SENTRY_DSN` | unset | Error reporting. |
|
|
123
123
|
|
|
124
|
+
## Recipes and profiles
|
|
125
|
+
|
|
126
|
+
A recipe (preset) is a measurement written once with its conventions fixed;
|
|
127
|
+
what depends on your instrument is a variable, bound by a profile at run
|
|
128
|
+
time: `spectro pipeline be_halpha_ew --input obs.fits --profile my_setup.yaml`.
|
|
129
|
+
Generic recipes ship with the kernel; campaign recipes live in the curated
|
|
130
|
+
[spectro-kernel-recipes](https://github.com/matthieulel/spectro-kernel-recipes)
|
|
131
|
+
collection (`pip install spectro-kernel-recipes`). See the
|
|
132
|
+
[Recipes](https://docs.spectrokernel.io/recipes/) documentation.
|
|
133
|
+
|
|
124
134
|
## Architecture
|
|
125
135
|
|
|
126
136
|
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Drafts (not published)
|
|
2
|
+
|
|
3
|
+
Pages parked here are excluded from the site: both Zensical and MkDocs skip
|
|
4
|
+
dot-directories. Move a page back under `docs/` (and add it to the `nav` in
|
|
5
|
+
`mkdocs.yml`) to publish it again.
|
|
6
|
+
|
|
7
|
+
- `notebooks/aurora-line-monitor.md` - parked on 2026-09-19, to be reinstated later.
|
|
@@ -90,7 +90,12 @@ spectro pipeline balmer_quick --input obs.fits # run one
|
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
Presets are why an analysis can be cited and reproduced: *"this measurement used the
|
|
93
|
-
`balmer_quick` v1.0.0 preset"* is a precise, checkable statement.
|
|
93
|
+
`balmer_quick` v1.0.0 preset"* is a precise, checkable statement. Since v0.7.0 a
|
|
94
|
+
preset can declare **variables** (the instrument- or observer-dependent values)
|
|
95
|
+
that a **profile** supplies at run time, and every run closes with a
|
|
96
|
+
`pipeline:<name>` record in the history naming the recipe, its version and the
|
|
97
|
+
bound values. The [Recipes](../recipes/index.md) section explains the idea and
|
|
98
|
+
the [format](../recipes/format.md) page is the reference.
|
|
94
99
|
|
|
95
100
|
## Reproducibility {#reproducibility}
|
|
96
101
|
|
|
@@ -63,8 +63,8 @@ natural answer; today the cleanest path is the Python snippet above.)
|
|
|
63
63
|
|
|
64
64
|
## Going further
|
|
65
65
|
|
|
66
|
-
- Replace the synthetic spectra with real BeSS extractions
|
|
67
|
-
[
|
|
66
|
+
- Replace the synthetic spectra with real BeSS extractions: `read_fits` reads
|
|
67
|
+
them directly (see [As a Python library](../usage/library.md)).
|
|
68
68
|
- Add `compare_normalisations` (Tier 2+) before stacking when continuum
|
|
69
69
|
variations between nights are suspect.
|
|
70
70
|
- Couple it with `lomb_scargle` on a per-epoch line-strength metric to look for
|
|
@@ -136,7 +136,7 @@ beyond `spectro-mcp --http`.
|
|
|
136
136
|
workflows (e.g. "always run `compare_normalisations` before measuring a
|
|
137
137
|
line").
|
|
138
138
|
- Wrap the agent in a periodic task (cron + a Claude API call) for nightly
|
|
139
|
-
monitoring - Be-star variability alerts,
|
|
139
|
+
monitoring - Be-star variability alerts, solar line monitoring,
|
|
140
140
|
exoplanet RV drift.
|
|
141
141
|
- Pair with the [web playground](../cookbook/web-playground.md) for human-in-the-loop
|
|
142
142
|
debugging when the agent picks the wrong tool.
|
|
@@ -109,30 +109,40 @@ run_algorithm(
|
|
|
109
109
|
# → ctx.spectrum.flux is now in erg/s/cm²/Å.
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
## The same as a
|
|
112
|
+
## The same as a recipe
|
|
113
|
+
|
|
114
|
+
The whole chain (steps 1-3, the file-driven portion) is the bundled recipe
|
|
115
|
+
`full_reduction_easyspec`. Everything that depends on your night is a
|
|
116
|
+
variable of the recipe; you supply the values with a profile:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
# night_2026-06-09.yaml
|
|
120
|
+
bias_dir: /data/biases
|
|
121
|
+
dark_dir: /data/darks
|
|
122
|
+
flat_dir: /data/flats
|
|
123
|
+
science_path: /data/science/alf_cyg_001.fits
|
|
124
|
+
exposure_seconds: 300
|
|
125
|
+
airmass: 1.18
|
|
126
|
+
target_name: alf Cyg
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
spectro preset show full_reduction_easyspec # the variables and their meaning
|
|
131
|
+
spectro pipeline full_reduction_easyspec --profile night_2026-06-09.yaml
|
|
132
|
+
```
|
|
113
133
|
|
|
114
|
-
|
|
115
|
-
templated in the bundled preset
|
|
116
|
-
[`full_reduction_easyspec`](https://github.com/matthieulel/spectro-kernel/blob/main/src/spectro_kernel/presets/catalog/reduction/full_reduction_easyspec.yaml).
|
|
117
|
-
It is a *template*: the `__REPLACE__` placeholders are the runtime paths you fill
|
|
118
|
-
in before building the pipeline. A typical usage:
|
|
134
|
+
Or from Python:
|
|
119
135
|
|
|
120
136
|
```python
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if isinstance(value, str) and value.startswith("__REPLACE_WITH_BIAS_DIR__"):
|
|
129
|
-
p[key] = "/data/biases"
|
|
130
|
-
elif isinstance(value, str) and value.startswith("__REPLACE_WITH_DARK_DIR__"):
|
|
131
|
-
p[key] = "/data/darks"
|
|
132
|
-
# … etc.
|
|
133
|
-
|
|
134
|
-
pipeline = PipelineBuilder().from_config(config).build()
|
|
137
|
+
import yaml
|
|
138
|
+
|
|
139
|
+
from spectro_kernel import WorkContext
|
|
140
|
+
from spectro_kernel.pipeline import PipelineBuilder
|
|
141
|
+
|
|
142
|
+
profile = yaml.safe_load(open("night_2026-06-09.yaml"))
|
|
143
|
+
pipeline = PipelineBuilder().from_preset("full_reduction_easyspec", profile).build()
|
|
135
144
|
result = pipeline.execute(WorkContext())
|
|
145
|
+
print(result.history[-1]) # pipeline:full_reduction_easyspec v2.0.0, the bound variables
|
|
136
146
|
```
|
|
137
147
|
|
|
138
148
|
Steps 4-6 (wavelength + extinction + flux) stay separate calls because their
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Reference for the recipe (preset) file, its variables, profiles, validation and provenance.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Recipe format
|
|
6
|
+
|
|
7
|
+
A recipe is one YAML file. The schema is published at
|
|
8
|
+
[`/ai/schemas/preset.schema.json`](../ai/schemas/preset.schema.json) and
|
|
9
|
+
`spectro preset validate` checks a file against the running kernel: format,
|
|
10
|
+
metadata vocabulary, algorithm names, parameter names, variables, and the
|
|
11
|
+
kernel version range.
|
|
12
|
+
|
|
13
|
+
## The file
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
name: be_halpha_ew # lowercase snake_case; the identifier users cite
|
|
17
|
+
version: 1.0.0 # semantic version of the recipe itself
|
|
18
|
+
description: >-
|
|
19
|
+
What is measured and how, in one paragraph.
|
|
20
|
+
requires: ">=0.7, <1.0" # spectro-kernel range the recipe was validated for
|
|
21
|
+
metadata:
|
|
22
|
+
kind: campaign # analysis | reduction | campaign | template
|
|
23
|
+
status: reviewed # draft | reviewed | reference
|
|
24
|
+
references: # mandatory for a campaign recipe
|
|
25
|
+
- "Vollmann & Eversberg 2006, AN 327, 862"
|
|
26
|
+
conventions: "continuum band 6500-6520 Å, 40 Å window around H-alpha"
|
|
27
|
+
author: "BeSS working group"
|
|
28
|
+
variables: # what depends on the instrument or the observer
|
|
29
|
+
tilt_deg: {type: float, required: true, description: "slit tilt (deg)"}
|
|
30
|
+
half_width: {type: int, default: 6}
|
|
31
|
+
steps: # the pipeline, in order
|
|
32
|
+
- name: Straighten the slit
|
|
33
|
+
algorithm: correct_tilt_affine
|
|
34
|
+
params: {tilt_deg: "${tilt_deg}"}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`name`, `version`, `description` and `steps` are required. A recipe with no
|
|
38
|
+
`variables` block is a plain preset and runs as is; every preset written
|
|
39
|
+
before v0.7.0 is still valid.
|
|
40
|
+
|
|
41
|
+
## Variables
|
|
42
|
+
|
|
43
|
+
Each variable has a `type`, an optional `default`, a `description`, and
|
|
44
|
+
optionally a list of `choices`. A variable without a default is required.
|
|
45
|
+
The shorthand `half_width: 6` declares an optional integer with that default.
|
|
46
|
+
|
|
47
|
+
| Type | Accepts | Example values |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| `int` | integers, or strings such as `"12"` from the command line | `6` |
|
|
50
|
+
| `float` | numbers | `0.4` |
|
|
51
|
+
| `bool` | booleans, or `true/false`, `yes/no`, `on/off`, `1/0` | `true` |
|
|
52
|
+
| `str` | text | `"alf Cyg"` |
|
|
53
|
+
| `path` | a file or directory path, kept as text | `/data/bias` |
|
|
54
|
+
| `list` | a YAML list, a JSON list such as `"[1, 2]"`, or `"a, b"` | `[5852.49, 6266.50]` |
|
|
55
|
+
|
|
56
|
+
Values coming from `--set name=value` are strings and are converted to the
|
|
57
|
+
declared type; a value outside `choices` or of the wrong type is refused
|
|
58
|
+
with the variable's name and description in the message.
|
|
59
|
+
|
|
60
|
+
## Substitution rules
|
|
61
|
+
|
|
62
|
+
The rules are deliberately small:
|
|
63
|
+
|
|
64
|
+
- a parameter whose value is exactly `${name}` receives the variable's typed
|
|
65
|
+
value (a number stays a number, a list stays a list);
|
|
66
|
+
- a string that contains `${name}` among other text is interpolated as text
|
|
67
|
+
(`label: "H-${line}"`), useful for labels and file names;
|
|
68
|
+
- lists and mappings are walked recursively;
|
|
69
|
+
- every `${name}` must be declared in `variables`, and every declared variable
|
|
70
|
+
must be used, otherwise validation fails.
|
|
71
|
+
|
|
72
|
+
Write the token in quotes, `"${name}"`: YAML would otherwise read the braces
|
|
73
|
+
of `{tilt_deg: ${tilt_deg}}` as a nested mapping. The quotes change nothing
|
|
74
|
+
for the kernel, which still passes the typed value.
|
|
75
|
+
|
|
76
|
+
## Profiles
|
|
77
|
+
|
|
78
|
+
A profile is any YAML mapping of variable name to value. It carries no
|
|
79
|
+
science, only what is true of one instrument and one observer:
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
# lhires_lyon.yaml
|
|
83
|
+
tilt_deg: 1.1
|
|
84
|
+
half_width: 4
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Ways to bind values, in increasing priority:
|
|
88
|
+
|
|
89
|
+
| From | How |
|
|
90
|
+
|---|---|
|
|
91
|
+
| the recipe | `default` of each variable |
|
|
92
|
+
| a profile file | `spectro pipeline <recipe> --profile lhires_lyon.yaml` |
|
|
93
|
+
| the command line | `--set tilt_deg=1.1` (repeatable) |
|
|
94
|
+
| Python | `PipelineBuilder().from_preset("be_halpha_ew", {"tilt_deg": 1.1})` |
|
|
95
|
+
| MCP | `run_preset(session_id, "be_halpha_ew", variables={"tilt_deg": 1.1})` |
|
|
96
|
+
|
|
97
|
+
Keep your profiles next to your data, one per instrument setup, and reuse
|
|
98
|
+
them across every recipe: the same `alpy600_toulouse.yaml` serves the Be
|
|
99
|
+
star recipe tonight and the nova recipe next month.
|
|
100
|
+
|
|
101
|
+
## `requires`
|
|
102
|
+
|
|
103
|
+
The kernel version range the recipe was validated for, with the plain
|
|
104
|
+
comparison operators (`>=`, `>`, `<=`, `<`, `==`, `!=`, comma-separated). A
|
|
105
|
+
recipe whose range excludes the running kernel refuses to build. When a
|
|
106
|
+
brick used by a recipe changes its own major version (its numbers changed),
|
|
107
|
+
the recipe author re-validates and bumps the recipe.
|
|
108
|
+
|
|
109
|
+
## Metadata vocabulary
|
|
110
|
+
|
|
111
|
+
| Key | Values | Meaning |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `kind` | `analysis`, `reduction`, `campaign`, `template` | what the recipe is for; a *campaign* recipe fixes a measurement convention for a community |
|
|
114
|
+
| `status` | `draft`, `reviewed`, `reference` | how far the review went (see [Share a recipe](share.md)) |
|
|
115
|
+
| `references` | list of strings | the papers the conventions rest on; mandatory for `campaign` |
|
|
116
|
+
| `conventions` | text | the choices that are not fixed by the literature, stated plainly |
|
|
117
|
+
| `author`, `notes`, `expects`, `category` | text | free information shown on the recipe page |
|
|
118
|
+
|
|
119
|
+
## Validation
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
spectro preset validate be_halpha_ew.yaml # the file alone
|
|
123
|
+
spectro preset validate be_halpha_ew.yaml --profile p.yaml # plus your values
|
|
124
|
+
spectro preset show be_halpha_ew # variables and steps
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Validation is what the CI of a recipe collection runs on every contribution.
|
|
128
|
+
It reports, all at once: a name that is not snake_case, a missing or malformed
|
|
129
|
+
version, a missing description, an unknown `kind` or `status`, a campaign
|
|
130
|
+
recipe without references, a `requires` range the kernel does not satisfy,
|
|
131
|
+
an unknown algorithm, an unknown parameter name, a required parameter that is
|
|
132
|
+
neither set nor bound to a variable, an undeclared `${token}`, an unused
|
|
133
|
+
variable, and a `depends_on` that matches no step.
|
|
134
|
+
|
|
135
|
+
## Provenance
|
|
136
|
+
|
|
137
|
+
When a recipe runs, every brick records itself in the context history as
|
|
138
|
+
before, and the run closes with one more record:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
algorithm pipeline:be_halpha_ew
|
|
142
|
+
version 1.0.0
|
|
143
|
+
params {variables: {...}, n_steps: 4, kernel_version: 0.7.0, source: package:spectro-kernel-recipes}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
It is written by `Pipeline.execute` for every named pipeline built from a
|
|
147
|
+
file or a config, and carried into every export that serialises the history.
|
|
148
|
+
Ad-hoc pipelines assembled in Python without a name leave the history exactly
|
|
149
|
+
as their steps wrote it.
|
|
150
|
+
|
|
151
|
+
## Discovery
|
|
152
|
+
|
|
153
|
+
`spectro presets` lists every recipe the kernel can see, in this search order:
|
|
154
|
+
|
|
155
|
+
1. the recipes bundled with the kernel;
|
|
156
|
+
2. the directories listed in the `SPECTRO_PRESET_PATH` environment variable
|
|
157
|
+
(`:`-separated on macOS and Linux);
|
|
158
|
+
3. installed packages that register an entry point in the
|
|
159
|
+
`spectro_kernel.presets` group (see [Share a recipe](share.md)).
|
|
160
|
+
|
|
161
|
+
A bundled name always wins over an external one with the same name. A recipe
|
|
162
|
+
can also be run from a path (`spectro pipeline ./my_recipe.yaml`). Nothing is
|
|
163
|
+
ever fetched from the network.
|