spectro-kernel 0.6.1__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.1 → spectro_kernel-0.7.0}/.gitignore +6 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/CHANGELOG.md +283 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/PKG-INFO +18 -4
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/README.md +12 -1
- spectro_kernel-0.7.0/docs/.drafts/README.md +7 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/concepts/algorithms.md +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/concepts/pipelines.md +6 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/contributing.md +3 -3
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/getting-started.md +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/index.md +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/be-star-variability.md +2 -2
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/claude-mcp-end-to-end.md +1 -1
- {spectro_kernel-0.6.1 → 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.6.1 → spectro_kernel-0.7.0}/docs/reference.md +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/tutorials/discover-the-catalogue.md +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/tutorials/first-spectrum.md +1 -1
- spectro_kernel-0.7.0/docs/tutorials/long-slit-reduction.md +299 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/usage/cli.md +20 -5
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/usage/mcp.md +3 -2
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/why.md +2 -2
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/pyproject.toml +7 -4
- 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.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_edges.py +7 -2
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_max.py +10 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_percentile.py +11 -4
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/normalize_polynomial.py +11 -12
- {spectro_kernel-0.6.1 → 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.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/smooth_gaussian.py +28 -5
- {spectro_kernel-0.6.1 → 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.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/combine_arithmetic.py +79 -9
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/resample.py +23 -3
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/cli.py +122 -5
- {spectro_kernel-0.6.1 → 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.1 → 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.1 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/balmer_quick.yaml +2 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/embed_quick.yaml +2 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/quality_report.yaml +2 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/rv_quick.yaml +2 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/presets/catalog/analysis/snr_check.yaml +2 -0
- {spectro_kernel-0.6.1 → 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.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/enums.py +2 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/version.py +1 -1
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/__main__.py +43 -2
- {spectro_kernel-0.6.1 → 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.1 → 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.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp_http_entry.py +67 -2
- 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.7.0/tools/docs/__init__.py +6 -0
- spectro_kernel-0.7.0/tools/docs/build.py +94 -0
- spectro_kernel-0.7.0/tools/docs/generate.py +27 -0
- spectro_kernel-0.7.0/tools/docs/generate_catalogue.py +485 -0
- spectro_kernel-0.7.0/tools/docs/generate_llms.py +134 -0
- spectro_kernel-0.7.0/tools/docs/generate_recipes.py +300 -0
- spectro_kernel-0.7.0/tools/docs/netlify.toml +20 -0
- spectro_kernel-0.6.1/docs/cookbook/bess-dashboard.md +0 -118
- spectro_kernel-0.6.1/docs/gen_catalogue.py +0 -124
- spectro_kernel-0.6.1/docs/tutorials/long-slit-reduction.md +0 -171
- spectro_kernel-0.6.1/src/spectro_kernel/algorithms/io/read_fits.py +0 -53
- spectro_kernel-0.6.1/src/spectro_kernel/algorithms/stacking/stack.py +0 -110
- spectro_kernel-0.6.1/src/spectro_kernel/io/fits.py +0 -345
- spectro_kernel-0.6.1/src/spectro_kernel/presets/__init__.py +0 -7
- spectro_kernel-0.6.1/src/spectro_kernel/presets/catalog/reduction/full_reduction_easyspec.yaml +0 -68
- spectro_kernel-0.6.1/src/spectro_kernel/presets/loader.py +0 -83
- spectro_kernel-0.6.1/tests/unit/test_combine.py +0 -118
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/LICENSE +0 -0
- {spectro_kernel-0.6.1/docs → spectro_kernel-0.7.0/docs/.drafts}/notebooks/aurora-line-monitor.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/concepts/architecture.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/concepts/data-types.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/cookbook/multi-star-viewer.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/cookbook/web-playground.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_ew_timeseries.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_halpha_phase_stack.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_halpha_timeseries.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_overlay.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pc1_vs_phase.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pca_2d.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_pca_3d.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_periodogram.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_phase_folded.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_rv_timeseries.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_similarity.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_cyg_similarity_date.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_halpha_phase_stack.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pc1_vs_phase.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pca_2d.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_pca_3d.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_periodogram.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_phase_folded.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_rv_timeseries.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_similarity_date.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/images/notebooks/alpha_dra_similarity_phase.png +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/alpha-cyg-time-series.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/alpha-dra-binary-period.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/exoplanet-transit-rv.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/native-vs-easyspec-showdown.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/notebooks/your-first-sb2.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/tutorials/add-an-algorithm.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/tutorials/analyse-a-spectrum.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/docs/usage/library.md +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/adapters/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/adapters/easyspec.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/_common.py +0 -0
- {spectro_kernel-0.6.1/src/spectro_kernel/algorithms/classification → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/activity}/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/aperture_photometry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/disentangle_sb2.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/advanced/doppler_tomogram.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/gaia.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/simbad.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/catalogs/vizier.py +0 -0
- {spectro_kernel-0.6.1/src/spectro_kernel/algorithms/embedding → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/classification}/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/classification/classify_template_chi2.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/classification/pickles_atlas.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/compare_normalisations.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/continuum/subtract_continuum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/air_vacuum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/barycentric.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/doppler_shift.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/extinction_correct_easyspec.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/fit_telluric_scaling.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/flux_calibrate_easyspec.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/remove_telluric.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/response_from_standard.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/corrections/synth_telluric.py +0 -0
- {spectro_kernel-0.6.1/src/spectro_kernel/algorithms/kinematics → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/embedding}/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_band_power.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_continuum_subtracted.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_lick_indices.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_log_lambda.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_pretrained.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_remote.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_spectrum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/embedding/embed_wavelets.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/_bess_contract.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_csv.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_fits.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_fits_bess.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_hdf5.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/exports/export_votable.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/boxcar.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/detect_trace.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/easyspec_extract.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/optimal.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/extraction/sky_lateral_bands.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_ascii.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_echelle.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_sdss.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/io/read_votable.py +0 -0
- {spectro_kernel-0.6.1/src/spectro_kernel/algorithms/nebular → spectro_kernel-0.7.0/src/spectro_kernel/algorithms/kinematics}/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/kinematics/rotation_curve.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/_line_flux.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/_profiles.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/catalogs.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/compare_line_fits.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/detect.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/equivalent_width.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_gaussian.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_lorentzian.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/fit_voigt.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/lines/vr_ratio.py +0 -0
- /spectro_kernel-0.6.1/src/spectro_kernel/py.typed → /spectro_kernel-0.7.0/src/spectro_kernel/algorithms/nebular/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/bpt_line_ratios.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/oiii_electron_temperature.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/nebular/sii_electron_density.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/compare_snr_methods.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_der.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_edge.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/snr_linear_fit.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/quality/validate_bess_header.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/_easyspec_apply.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/_easyspec_helpers.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/bias_combine.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/clip_cosmic_rays.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/dark_combine.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/dark_subtract.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/denoise_2d.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_bias.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_cosmic_ray.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_dark.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_flat.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_flat_normalize.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_subtract_bias.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/easyspec_subtract_dark.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/extract_spectrum_sum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/flat_combine.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/flat_normalize.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/geometry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/subtract_sky_2d.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/reduction/wavelength_calibrate.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/cross_correlate.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/fit_keplerian_orbit.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/measure.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/precision_bouchy.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/rv/redshift_lines.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/_nan_bridge.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/smoothing/compare_smoothings.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/stacking/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/stacking/merge_echelle_orders.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/lomb_scargle.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/timeseries/phase_fold.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/clip_sigma.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/extract_region.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/mask_range.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/transforms/resample_flux_conserving.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_3d_surface.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_animation.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_dynamic_spectrum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/viz/plot_plotly.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/arc_geometry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/easyspec_wavelength.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/in_situ.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/lamp_atlas.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/match_lamp.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/reidentify.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/algorithms/wavelength_calibration/solar.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/base.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/embeddings.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/io/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/io/ascii.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/io/votable.py +0 -0
- {spectro_kernel-0.6.1/src/spectro_mcp → spectro_kernel-0.7.0/src/spectro_kernel}/py.typed +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/registry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/catalog.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/context.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/history.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/image.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/line.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/spectrum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/types/timeseries.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_kernel/url_safety.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/__init__.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/auth.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/observability.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/server.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/session.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/src/spectro_mcp/url_safety.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/conftest.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/reference/conftest.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/reference/test_known_answers.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/reference/test_sun.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/reference/test_vega.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_aperture_photometry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_barycentric_bjd.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_base.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_catalog_queries_mocked.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_classify_template_chi2.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_cli.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_combine_arithmetic.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_continuum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_corrections.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_cross_correlate_extension.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_dark_flat_combine.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_denoise_2d.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_detect_lines_blind.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_detect_trace.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_disentangle_sb2.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_doppler_tomogram.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_apply_staging.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_sessions.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_easyspec_wrappers.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_embedding.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_embedding_pretrained.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_embedding_remote_lick.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_embedding_tier1.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_export_fits_bess.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_export_hdf5.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_extract_boxcar.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_extract_optimal.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_extract_spectrum_sum.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_flux_calibrate_easyspec.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_geometry_corrections.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_lamp_atlas_match.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_line_profiles.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_lines.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp_param_guard.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp_production.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp_security.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_mcp_tools_extra.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_measure_arc_geometry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_misc_algorithms.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_nebular_diagnostics.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_no_circular_imports.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_normalize_to_region.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_output_produces_contract.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_pipeline.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_quality.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_read_sdss.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_redshift_lines.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_registry.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_reidentify.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_resample_flux_conserving.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_response_from_standard.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_rotation_curve.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_rv_precision_bouchy.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_sky_lateral_bands.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_smoothing.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_timeseries.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_transforms.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_types.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_url_safety_kernel.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_validate_bess_header.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_viz.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_vr_ratio.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_wavelength_calibration_in_situ.py +0 -0
- {spectro_kernel-0.6.1 → spectro_kernel-0.7.0}/tests/unit/test_wavelength_calibration_solar.py +0 -0
|
@@ -6,6 +6,289 @@ 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
|
+
|
|
249
|
+
## [0.6.2] — 2026-09-19
|
|
250
|
+
|
|
251
|
+
A documentation and web release : the docs move to a generated,
|
|
252
|
+
agent-readable site at https://docs.spectrokernel.io/, the landing page is
|
|
253
|
+
rebuilt around the open MCP server, and the server gains CORS so the web
|
|
254
|
+
playground can use it. No algorithm changes.
|
|
255
|
+
|
|
256
|
+
### MCP server
|
|
257
|
+
|
|
258
|
+
- CORS for browser clients in HTTP mode : `SPECTRO_MCP_CORS_ORIGINS`
|
|
259
|
+
(default : the spectrokernel.io sites ; `*` or `none`), with the
|
|
260
|
+
`Mcp-Session-Id` header exposed, so the web playground on the landing
|
|
261
|
+
page can talk to the public server. Pre-flights are answered before the
|
|
262
|
+
API-key check.
|
|
263
|
+
|
|
264
|
+
### Documentation — new build pipeline and hosting (no package change)
|
|
265
|
+
|
|
266
|
+
- The site is now built with **Zensical** (the Material for MkDocs team's
|
|
267
|
+
successor engine, reading the unchanged `mkdocs.yml`) and published at
|
|
268
|
+
**https://docs.spectrokernel.io/** by Netlify, which builds it from the
|
|
269
|
+
repository (base directory `tools/docs`, see `tools/docs/netlify.toml`) ;
|
|
270
|
+
pull requests get a deploy preview and GitHub Actions keeps a strict build
|
|
271
|
+
check. `mkdocs build` keeps working as a fallback.
|
|
272
|
+
- The algorithm catalogue is generated *before* the build by
|
|
273
|
+
`tools/docs/generate_catalogue.py` (Zensical runs no MkDocs plugin such as
|
|
274
|
+
`gen-files`) : one page per algorithm under `/algorithms/<category>/<name>/`
|
|
275
|
+
(summary, backend, version, context reads/writes, parameter table, Python /
|
|
276
|
+
CLI / MCP call examples, references, related algorithms), a category index,
|
|
277
|
+
and a navigation tree consumed by `literate-nav`.
|
|
278
|
+
- Machine-readable layer for agents and tooling : `/ai/algorithms.json`
|
|
279
|
+
(validated at build time against `/ai/schemas/algorithms.schema.json`,
|
|
280
|
+
schema version 1, stamped with the package version), a curated `/llms.txt`
|
|
281
|
+
derived from the navigation, and the Markdown source of every page served
|
|
282
|
+
next to its HTML (`<page>/index.md`). Netlify headers set the content types
|
|
283
|
+
and CORS on `/ai/*`.
|
|
284
|
+
- `tools/docs/build.py` reproduces the CI build locally (generators + strict
|
|
285
|
+
build + post-processing) ; `tools/docs/generate.py && zensical serve` for
|
|
286
|
+
live preview. Generated files (`docs/algorithms/`, `docs/ai/`,
|
|
287
|
+
`docs/llms.txt`) are git-ignored. `.readthedocs.yaml` and
|
|
288
|
+
`docs/gen_catalogue.py` are removed ; the `docs` extra now installs
|
|
289
|
+
`zensical`, `mkdocstrings[python]`, `mkdocs-material`,
|
|
290
|
+
`mkdocs-literate-nav`, `jsonschema`.
|
|
291
|
+
|
|
9
292
|
## [0.6.1] — 2026-09-19
|
|
10
293
|
|
|
11
294
|
A correctness and hardening release driven by a full audit of the
|
|
@@ -1,9 +1,9 @@
|
|
|
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
|
-
Project-URL: Documentation, https://
|
|
6
|
+
Project-URL: Documentation, https://docs.spectrokernel.io/
|
|
7
7
|
Project-URL: Source, https://github.com/matthieulel/spectro-kernel
|
|
8
8
|
Project-URL: Issues, https://github.com/matthieulel/spectro-kernel/issues
|
|
9
9
|
Project-URL: Changelog, https://github.com/matthieulel/spectro-kernel/blob/main/CHANGELOG.md
|
|
@@ -54,9 +54,12 @@ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
|
54
54
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
55
55
|
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
56
56
|
Provides-Extra: docs
|
|
57
|
-
Requires-Dist:
|
|
57
|
+
Requires-Dist: jsonschema>=4.0; extra == 'docs'
|
|
58
|
+
Requires-Dist: mkdocs-literate-nav>=0.6; extra == 'docs'
|
|
58
59
|
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
59
60
|
Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
|
|
61
|
+
Requires-Dist: pyyaml>=6.0; extra == 'docs'
|
|
62
|
+
Requires-Dist: zensical>=0.0.62; extra == 'docs'
|
|
60
63
|
Provides-Extra: embedding-ml
|
|
61
64
|
Requires-Dist: torch>=2.2; extra == 'embedding-ml'
|
|
62
65
|
Provides-Extra: embedding-remote
|
|
@@ -197,6 +200,7 @@ by environment variable (none of these affect stdio mode) :
|
|
|
197
200
|
| `SPECTRO_MCP_ALLOW_KEY_IN_URL` | unset | `1` also accepts the key as `?api_key=…` in the URL (for claude.ai / Claude Desktop connectors, which cannot set headers); the parameter is scrubbed before access logging. `Authorization: Bearer <key>` is always accepted. |
|
|
198
201
|
| `SPECTRO_MCP_RATE_PER_MINUTE` | `0` (off) | Sliding-window request limit per API key (per client IP when auth is off). |
|
|
199
202
|
| `SPECTRO_MCP_TRUSTED_PROXY` | unset | `1` behind a load balancer: trust `X-Forwarded-For` for the client IP. |
|
|
203
|
+
| `SPECTRO_MCP_CORS_ORIGINS` | spectrokernel.io sites | Comma-separated browser origins allowed to call the server (`*` for any, `none` to disable). The `Mcp-Session-Id` header is exposed to browsers. |
|
|
200
204
|
| `SPECTRO_MCP_MAX_SESSIONS` | `200` | Cap on live in-memory sessions; the least recently used one is evicted. |
|
|
201
205
|
| `SPECTRO_MCP_MAX_PIXELS` | `32000000` | Refuse downloaded FITS files with more data elements than this (256 MB as float64); `0` disables. |
|
|
202
206
|
| `SPECTRO_MCP_DOWNLOAD_BUDGET_S` | `120` | Wall-clock budget for one URL download (on top of the 256 MiB cap). |
|
|
@@ -206,6 +210,16 @@ by environment variable (none of these affect stdio mode) :
|
|
|
206
210
|
| `SPECTRO_MCP_S3_BUCKET`, `SPECTRO_MCP_S3_ENDPOINT`, … | unset | Presigned-URL uploads (`request_upload_url`). |
|
|
207
211
|
| `SENTRY_DSN` | unset | Error reporting. |
|
|
208
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
|
+
|
|
209
223
|
## Architecture
|
|
210
224
|
|
|
211
225
|
```
|
|
@@ -234,7 +248,7 @@ from the registry. Build it locally with:
|
|
|
234
248
|
|
|
235
249
|
```bash
|
|
236
250
|
uv pip install -e ".[docs,all]"
|
|
237
|
-
|
|
251
|
+
python tools/docs/generate.py && zensical serve # live preview at http://127.0.0.1:8000
|
|
238
252
|
```
|
|
239
253
|
|
|
240
254
|
Every algorithm declares its **provenance** — a `backend` (the library it leans on) and
|
|
@@ -111,6 +111,7 @@ by environment variable (none of these affect stdio mode) :
|
|
|
111
111
|
| `SPECTRO_MCP_ALLOW_KEY_IN_URL` | unset | `1` also accepts the key as `?api_key=…` in the URL (for claude.ai / Claude Desktop connectors, which cannot set headers); the parameter is scrubbed before access logging. `Authorization: Bearer <key>` is always accepted. |
|
|
112
112
|
| `SPECTRO_MCP_RATE_PER_MINUTE` | `0` (off) | Sliding-window request limit per API key (per client IP when auth is off). |
|
|
113
113
|
| `SPECTRO_MCP_TRUSTED_PROXY` | unset | `1` behind a load balancer: trust `X-Forwarded-For` for the client IP. |
|
|
114
|
+
| `SPECTRO_MCP_CORS_ORIGINS` | spectrokernel.io sites | Comma-separated browser origins allowed to call the server (`*` for any, `none` to disable). The `Mcp-Session-Id` header is exposed to browsers. |
|
|
114
115
|
| `SPECTRO_MCP_MAX_SESSIONS` | `200` | Cap on live in-memory sessions; the least recently used one is evicted. |
|
|
115
116
|
| `SPECTRO_MCP_MAX_PIXELS` | `32000000` | Refuse downloaded FITS files with more data elements than this (256 MB as float64); `0` disables. |
|
|
116
117
|
| `SPECTRO_MCP_DOWNLOAD_BUDGET_S` | `120` | Wall-clock budget for one URL download (on top of the 256 MiB cap). |
|
|
@@ -120,6 +121,16 @@ by environment variable (none of these affect stdio mode) :
|
|
|
120
121
|
| `SPECTRO_MCP_S3_BUCKET`, `SPECTRO_MCP_S3_ENDPOINT`, … | unset | Presigned-URL uploads (`request_upload_url`). |
|
|
121
122
|
| `SENTRY_DSN` | unset | Error reporting. |
|
|
122
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
|
+
|
|
123
134
|
## Architecture
|
|
124
135
|
|
|
125
136
|
```
|
|
@@ -148,7 +159,7 @@ from the registry. Build it locally with:
|
|
|
148
159
|
|
|
149
160
|
```bash
|
|
150
161
|
uv pip install -e ".[docs,all]"
|
|
151
|
-
|
|
162
|
+
python tools/docs/generate.py && zensical serve # live preview at http://127.0.0.1:8000
|
|
152
163
|
```
|
|
153
164
|
|
|
154
165
|
Every algorithm declares its **provenance** — a `backend` (the library it leans on) and
|
|
@@ -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.
|
|
@@ -103,7 +103,7 @@ principle](../why.md#the-principle-we-do-not-reinvent). Every algorithm declares
|
|
|
103
103
|
- its **`references`** - the literature for the method, or the wrapped library.
|
|
104
104
|
|
|
105
105
|
Both are visible in `spectro describe <name>`, in the
|
|
106
|
-
[catalogue](../
|
|
106
|
+
[catalogue](../algorithms/index.md), and in every MCP tool description. Nothing is a black box:
|
|
107
107
|
you can always see what an algorithm stands on and where the method comes from.
|
|
108
108
|
|
|
109
109
|
## Naming conventions
|
|
@@ -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
|
|
|
@@ -57,10 +57,10 @@ CI runs the same checks on every pull request; keep `main` green.
|
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
59
|
uv pip install -e ".[docs,all]"
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
python tools/docs/generate.py && zensical serve # live preview at http://127.0.0.1:8000
|
|
61
|
+
python tools/docs/build.py # what CI runs: generators + strict build into site/
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
The [algorithm catalogue](
|
|
64
|
+
The [algorithm catalogue](algorithms/index.md) page is *generated* from the registry at build
|
|
65
65
|
time - you never edit it by hand. Add a docstring and metadata to your algorithm and the
|
|
66
66
|
catalogue page documents it automatically.
|
|
@@ -114,4 +114,4 @@ The agent now sees every algorithm as a tool. See [As an MCP server](usage/mcp.m
|
|
|
114
114
|
catalogue](tutorials/discover-the-catalogue.md).
|
|
115
115
|
- Understand the moving parts → [Concepts: architecture](concepts/architecture.md).
|
|
116
116
|
- A guided, end-to-end analysis → [Tutorial: analyse a spectrum](tutorials/analyse-a-spectrum.md).
|
|
117
|
-
- Browse everything available → [Algorithm catalogue](
|
|
117
|
+
- Browse everything available → [Algorithm catalogue](algorithms/index.md).
|
|
@@ -49,7 +49,7 @@ through MCP, you can do from a terminal, and vice-versa.
|
|
|
49
49
|
your first analysis in five minutes.
|
|
50
50
|
- :material-sitemap: **[Concepts](concepts/architecture.md)** - the architecture,
|
|
51
51
|
the data types, the registry, the pipelines.
|
|
52
|
-
- :material-book-open-variant: **[Algorithm catalogue](
|
|
52
|
+
- :material-book-open-variant: **[Algorithm catalogue](algorithms/index.md)** - every
|
|
53
53
|
algorithm, auto-generated from the code.
|
|
54
54
|
- :material-school: **[Tutorials](tutorials/first-spectrum.md)** - from *"I captured a
|
|
55
55
|
spectrum of a star, now what?"* all the way to writing your own algorithm.
|
|
@@ -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
|