diskmelts 2.2.0__tar.gz → 2.2.2__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.
- diskmelts-2.2.2/MANIFEST.in +2 -0
- {diskmelts-2.2.0/src/diskmelts.egg-info → diskmelts-2.2.2}/PKG-INFO +89 -34
- {diskmelts-2.2.0 → diskmelts-2.2.2}/README.md +86 -31
- {diskmelts-2.2.0 → diskmelts-2.2.2}/pyproject.toml +5 -3
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/__init__.py +4 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/_core.py +24 -7
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/fitting.py +188 -120
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/C2H2_model_bank.json +26 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/net_C2H2_w11p5to17.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/net_C2H2_w6to9.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/C4H2_single_v2/net_C4H2_forward.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma0/C6H6_single_v2/net_C6H6_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/CH3_single_v2/net_CH3_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/CH4_single_v2/net_CH4_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/CO2_single_v2/net_CO2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w19to25_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/HC3N_single_v2/net_HC3N_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/HCN_single_v2/net_HCN_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma0/OH_single_v2/net_OH_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w11p5to17.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w6to9.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/C4H2_single_v2/net_C4H2_forward.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/C6H6_single_v2/net_C6H6_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/CH3_single_v2/net_CH3_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/CH4_single_v2/net_CH4_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/CO2_single_v2/net_CO2_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w19to25_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/HC3N_single_v2/net_HC3N_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/HCN_single_v2/net_HCN_forward.pt +0 -0
- diskmelts-2.2.2/src/diskmelts/models/Trained_model/sigma2/OH_single_v2/net_OH_forward.pt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/plotting.py +1 -1
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/trainmodel.py +146 -17
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/v2_fitting.py +152 -24
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/v2_grid_fitting.py +117 -56
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/validation.py +22 -6
- {diskmelts-2.2.0 → diskmelts-2.2.2/src/diskmelts.egg-info}/PKG-INFO +89 -34
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts.egg-info/SOURCES.txt +6 -16
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts.egg-info/requires.txt +2 -2
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C2H2_single_v2/net_C2H2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/C4H2_single_v2/net_C4H2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/CH3_single_v2/net_CH3_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/CH4_single_v2/net_CH4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/CO2_single_v2/net_CO2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/HC3N_single_v2/net_HC3N_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma0/HCN_single_v2/net_HCN_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w11p5to17.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w6to9.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/CH3_single_v2/net_CH3_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/CH4_single_v2/net_CH4_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/CO2_single_v2/net_CO2_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/HCN_single_v2/net_HCN_forward.pt +0 -0
- diskmelts-2.2.0/src/diskmelts/models/Trained_model/sigma2/OH_single_v2/net_OH_forward.pt +0 -0
- diskmelts-2.2.0/tests/test_consub_package.py +0 -99
- diskmelts-2.2.0/tests/test_detection.py +0 -133
- diskmelts-2.2.0/tests/test_dev_v2_fitting_distance.py +0 -41
- diskmelts-2.2.0/tests/test_dev_v2_fitting_grids.py +0 -176
- diskmelts-2.2.0/tests/test_dev_v2_read_plot.py +0 -95
- diskmelts-2.2.0/tests/test_imports.py +0 -61
- diskmelts-2.2.0/tests/test_io.py +0 -80
- diskmelts-2.2.0/tests/test_mlp.py +0 -43
- diskmelts-2.2.0/tests/test_model_bank.py +0 -230
- diskmelts-2.2.0/tests/test_shared_area_fitting.py +0 -190
- diskmelts-2.2.0/tests/test_smoke.py +0 -48
- diskmelts-2.2.0/tests/test_v2_package_assets.py +0 -129
- diskmelts-2.2.0/tests/test_water_training.py +0 -126
- diskmelts-2.2.0/tests/test_workflows.py +0 -263
- {diskmelts-2.2.0 → diskmelts-2.2.2}/LICENSE +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/setup.cfg +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/__init__.py +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/_api.py +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/cont_ranges.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/cont_ranges_PPan.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/carbon_extended.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/carbon_extended.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/carbon_rich.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/carbon_rich.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/ttauri.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/ttauri.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/water.csv +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/consub/regions/water.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma0/H2O_wavelength_bank_v2_fixed/H2O_model_bank.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/C2H2_model_bank.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/H2O_model_bank.json +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/v2_paper_comparison.py +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts/v2_read_plot.py +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts.egg-info/dependency_links.txt +0 -0
- {diskmelts-2.2.0 → diskmelts-2.2.2}/src/diskmelts.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diskmelts
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Machine-learning Enabled Line fitting Tool for Spectra of protoplanetary disks
|
|
5
5
|
Author: Chengyan Xie, Dingshan Deng
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,12 +15,12 @@ Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
|
15
15
|
Requires-Python: >=3.9
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: torch
|
|
18
|
+
Requires-Dist: torch>=1.13
|
|
19
19
|
Requires-Dist: numpy<2,>=1.26; sys_platform == "darwin" and platform_machine == "x86_64"
|
|
20
20
|
Requires-Dist: numpy; sys_platform != "darwin" or platform_machine != "x86_64"
|
|
21
21
|
Requires-Dist: pandas
|
|
22
22
|
Requires-Dist: scipy
|
|
23
|
-
Requires-Dist: scikit-learn
|
|
23
|
+
Requires-Dist: scikit-learn>=1.0
|
|
24
24
|
Requires-Dist: matplotlib
|
|
25
25
|
Provides-Extra: io
|
|
26
26
|
Requires-Dist: astropy; extra == "io"
|
|
@@ -49,10 +49,11 @@ density (`logN`), and emitting area scaling (`A`) from observed spectra.
|
|
|
49
49
|
|
|
50
50
|
## Installation
|
|
51
51
|
|
|
52
|
-
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/) and
|
|
53
|
+
requires Python 3.9 or newer. It bundles 46 production checkpoints, 23 each
|
|
54
|
+
for the sigma=0 and sigma=2 grids, covering the same 18 species (see
|
|
55
|
+
[Available molecules](#available-molecules)).
|
|
56
|
+
Install it from any directory. These commands use
|
|
56
57
|
`python` in an activated environment; the
|
|
57
58
|
[installation guide](https://diskmelts.readthedocs.io/en/latest/installation.html)
|
|
58
59
|
shows how to create one on macOS, Linux, Windows, or Conda:
|
|
@@ -87,6 +88,36 @@ conda activate diskmelts
|
|
|
87
88
|
Use `environment-notebooks.yaml` or `environment-dev.yaml` for the corresponding
|
|
88
89
|
notebook or contributor dependencies.
|
|
89
90
|
|
|
91
|
+
## Minimal workflow
|
|
92
|
+
|
|
93
|
+
Subtract the continuum, fit one molecule, and print the result:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from diskmelts import consub, fit_stage, load_fitting_models
|
|
97
|
+
|
|
98
|
+
# 1. Raw spectrum: CSV with wave (µm), flux (Jy), and optional err columns.
|
|
99
|
+
raw_wave, raw_flux, raw_err = consub.read_spectrum("my_raw_spectrum.csv")
|
|
100
|
+
wave, flux, err, cont, cont_unshifted = consub.calculate(
|
|
101
|
+
raw_wave, raw_flux, raw_err, preset="ttauri",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# 2. Fit C2H2 near 13.7 µm with the bundled surrogate model.
|
|
105
|
+
models = load_fitting_models("C2H2")
|
|
106
|
+
fit = fit_stage(
|
|
107
|
+
wave, flux, molecule="C2H2", pretrained=models,
|
|
108
|
+
wavelength_range=(13.0, 15.0), fit_ranges=(13.5, 14.1),
|
|
109
|
+
distance_pc=140.0, n_samples=1024, n_refine=4, n_top=4,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# 3. Best-fit T (K), logN (cm^-2), A (au^2), and the spread of top solutions.
|
|
113
|
+
print(fit["params"]["C2H2"])
|
|
114
|
+
print(fit["uncertainty"]["C2H2"])
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The sections below explain each step, and the
|
|
118
|
+
[first-spectrum guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html)
|
|
119
|
+
covers multi-stage fits, saved outputs, and plots.
|
|
120
|
+
|
|
90
121
|
## Runtime dependencies
|
|
91
122
|
|
|
92
123
|
| Package | Purpose |
|
|
@@ -95,7 +126,7 @@ notebook or contributor dependencies.
|
|
|
95
126
|
| `numpy` | Array operations |
|
|
96
127
|
| `pandas` | CSV I/O |
|
|
97
128
|
| `scipy` | L-BFGS-B optimizer, NNLS, Sobol sampling |
|
|
98
|
-
| `scikit-learn` |
|
|
129
|
+
| `scikit-learn` | PCA and scaling when training new models |
|
|
99
130
|
| `matplotlib` | Plotting |
|
|
100
131
|
|
|
101
132
|
## Continuum subtraction
|
|
@@ -130,12 +161,6 @@ With `preset=None, linefreefile=None` (or `""`), fitting uses all nonexcluded
|
|
|
130
161
|
pixels and skips the line-free correction, so `cont` equals `contOrig`.
|
|
131
162
|
Reference tables are bundled; normal continuum subtraction needs no model grids.
|
|
132
163
|
|
|
133
|
-
The private `0-Consub/` experiment directory is excluded from Git and is not
|
|
134
|
-
required by the installed package. Its runtime code and reference tables are
|
|
135
|
-
maintained under `src/diskmelts/consub/`.
|
|
136
|
-
The distributed tests in `tests/` exercise the installed continuum API and
|
|
137
|
-
bundled references without that private directory.
|
|
138
|
-
|
|
139
164
|
Returned `err` represents measurement/noise error, not correlated continuum
|
|
140
165
|
uncertainty. Broad excluded intervals require inspection. See the
|
|
141
166
|
[continuum guide](https://diskmelts.readthedocs.io/en/latest/continuum.html) for presets, regional box sizes,
|
|
@@ -182,31 +207,35 @@ You can also read spectra with your own code. DiskMELTS only requires
|
|
|
182
207
|
one-dimensional `obs_wav` and `obs_flux` arrays. Replace the sample CSV with
|
|
183
208
|
your own file to fit your source; update `distance_pc` and fit intervals.
|
|
184
209
|
|
|
185
|
-
For a complete staged fit-and-subtract workflow from a
|
|
210
|
+
For a complete staged fit-and-subtract workflow from a clone of the
|
|
211
|
+
repository, run:
|
|
186
212
|
|
|
187
213
|
```bash
|
|
188
214
|
python examples/dev_v2_realobs.py
|
|
215
|
+
python examples/dev_v2_realobs.py --input /path/to/my_spectrum.csv --name my_source --distance-pc 140 --sigma 2
|
|
189
216
|
```
|
|
190
217
|
|
|
218
|
+
Adjust that script's stage windows for your spectrum.
|
|
219
|
+
`python examples/synthetic_array_fit.py` generates an HCN spectrum and fits it
|
|
220
|
+
from in-memory arrays, without an observation file.
|
|
221
|
+
|
|
191
222
|
The v2 fitting API is `load_fitting_models`, `fit_stage`, `fit_observation`, and
|
|
192
|
-
`plot_saved_observation`. The production checkpoints are
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
`
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
The
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
be no hotter than C2H2 and gives them the same emitting area. It ties 13CO2
|
|
209
|
-
to CO2 in both temperature and area. Set
|
|
223
|
+
`plot_saved_observation`. The production checkpoints are included in the
|
|
224
|
+
wheel, so model fitting needs no local model grids. The checkpoint flux
|
|
225
|
+
convention is 1 au² at 140 pc; `distance_pc` sets the source distance and
|
|
226
|
+
makes the returned emitting area physical. `fit_observation` accepts either a
|
|
227
|
+
CSV path or in-memory `obs_wav`, `obs_flux`, and optional `obs_err` arrays
|
|
228
|
+
(new in 2.2.1).
|
|
229
|
+
|
|
230
|
+
For a synthetic spectrum, `wave, flux = diskmelts.synthesize_spectrum('HCN',
|
|
231
|
+
T=300, logN=18, A=1)` returns the native wavelength axis and model flux (new
|
|
232
|
+
in 2.2.1). See the
|
|
233
|
+
[generation guide](https://diskmelts.readthedocs.io/en/latest/generate_spectra.html).
|
|
234
|
+
|
|
235
|
+
The [fitting notebook](https://github.com/wddlx/DiskMELTS/blob/main/notebooks/Example_Fitting.ipynb)
|
|
236
|
+
requires 13C12CH2 to be no hotter than C2H2 and gives them the same emitting
|
|
237
|
+
area; it ties 13CO2 to CO2 in both temperature and area. Point its input at
|
|
238
|
+
your own continuum-subtracted CSV, or pass arrays. Set
|
|
210
239
|
`isotopologue_groups`, `Tshare` (`free`, `equal`, or `less`), and `Ashare` in a
|
|
211
240
|
joint stage to choose those constraints. See the
|
|
212
241
|
[fitting guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for examples.
|
|
@@ -218,6 +247,32 @@ separate method does require the full local grids. See the
|
|
|
218
247
|
plotting.
|
|
219
248
|
For complete sigma=2 grids, pass `grid_root='Model_grids/sigma2'`.
|
|
220
249
|
|
|
250
|
+
## Available molecules
|
|
251
|
+
|
|
252
|
+
Each molecule is available for two slab-model grids: sigma=0 (default) assumes
|
|
253
|
+
no turbulent broadening, so lines are only thermally broadened, and sigma=2
|
|
254
|
+
assumes 2 km/s turbulent broadening. Select sigma=2 with `load_fitting_models(..., sigma=2)` or
|
|
255
|
+
`fit_observation(..., sigma=2)`. Fit windows must lie inside a model's band.
|
|
256
|
+
|
|
257
|
+
| Molecule | Band (µm) | T (K) | logN (cm⁻²) |
|
|
258
|
+
|---|---|---|---|
|
|
259
|
+
| H2O | 4.9–25.0 (five overlapping tiles) | 100–1400 | 13–19 |
|
|
260
|
+
| C2H2 | 6–9 and 11.5–17 | 100–1400 | 13–19.5 |
|
|
261
|
+
| HCN, CO2, 13C12CH2, 13CO2 | 11.5–17 | 100–1400 | 13–19.5 |
|
|
262
|
+
| HC3N, CO17O, CO18O | 13–18 | 100–1400 | 13–19.5 |
|
|
263
|
+
| C4H2 | 14–18 | 100–1400 | 13–19.5 |
|
|
264
|
+
| C3H4, CH3 | 15–18 | 100–1400 | 13–19.5 |
|
|
265
|
+
| C6H6 | 13–17 | 100–675 | 13–19.5 |
|
|
266
|
+
| C2H6 | 9–15 | 100–1400 | 13–19.5 |
|
|
267
|
+
| C2H4 | 8–14 | 100–1400 | 13–19.5 |
|
|
268
|
+
| CH4 | 5–9 | 100–1400 | 13–19.5 |
|
|
269
|
+
| C2HD | 11.5–20.5 | 100–1400 | 13–19.5 |
|
|
270
|
+
| OH | 15–26 | 100–1400 | 13–19.5 |
|
|
271
|
+
|
|
272
|
+
`diskmelts.MODEL_SPECS` records the exact domains, PCA sizes, and network
|
|
273
|
+
layers. Version 2.2.0 lacks the sigma=0 OH and 6–9 µm C2H2 checkpoints;
|
|
274
|
+
upgrade with `python -m pip install -U diskmelts`.
|
|
275
|
+
|
|
221
276
|
## Training and validation data
|
|
222
277
|
|
|
223
278
|
Generated data under `Model_grids/` and `Pretrain_grid/` are intentionally
|
|
@@ -250,7 +305,7 @@ uses the same names with local `Model_grids/sigma0/C6H6/` and `Model_grids/sigma
|
|
|
250
305
|
files. See the [training guide](https://diskmelts.readthedocs.io/en/latest/training.html)
|
|
251
306
|
for peak audits and retraining commands.
|
|
252
307
|
|
|
253
|
-
|
|
308
|
+
The package also includes a CH3 checkpoint for 15–18 µm,
|
|
254
309
|
`T=100–1400 K`, and `logN=13–19.5`. Its strongest grid feature in this window
|
|
255
310
|
is near 16.4–16.6 µm. Use `load_fitting_models('CH3')` after installing this
|
|
256
311
|
package; direct-grid fitting uses local `Model_grids/sigma0/CH3/` files.
|
|
@@ -10,10 +10,11 @@ density (`logN`), and emitting area scaling (`A`) from observed spectra.
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
-
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/) and
|
|
14
|
+
requires Python 3.9 or newer. It bundles 46 production checkpoints, 23 each
|
|
15
|
+
for the sigma=0 and sigma=2 grids, covering the same 18 species (see
|
|
16
|
+
[Available molecules](#available-molecules)).
|
|
17
|
+
Install it from any directory. These commands use
|
|
17
18
|
`python` in an activated environment; the
|
|
18
19
|
[installation guide](https://diskmelts.readthedocs.io/en/latest/installation.html)
|
|
19
20
|
shows how to create one on macOS, Linux, Windows, or Conda:
|
|
@@ -48,6 +49,36 @@ conda activate diskmelts
|
|
|
48
49
|
Use `environment-notebooks.yaml` or `environment-dev.yaml` for the corresponding
|
|
49
50
|
notebook or contributor dependencies.
|
|
50
51
|
|
|
52
|
+
## Minimal workflow
|
|
53
|
+
|
|
54
|
+
Subtract the continuum, fit one molecule, and print the result:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from diskmelts import consub, fit_stage, load_fitting_models
|
|
58
|
+
|
|
59
|
+
# 1. Raw spectrum: CSV with wave (µm), flux (Jy), and optional err columns.
|
|
60
|
+
raw_wave, raw_flux, raw_err = consub.read_spectrum("my_raw_spectrum.csv")
|
|
61
|
+
wave, flux, err, cont, cont_unshifted = consub.calculate(
|
|
62
|
+
raw_wave, raw_flux, raw_err, preset="ttauri",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 2. Fit C2H2 near 13.7 µm with the bundled surrogate model.
|
|
66
|
+
models = load_fitting_models("C2H2")
|
|
67
|
+
fit = fit_stage(
|
|
68
|
+
wave, flux, molecule="C2H2", pretrained=models,
|
|
69
|
+
wavelength_range=(13.0, 15.0), fit_ranges=(13.5, 14.1),
|
|
70
|
+
distance_pc=140.0, n_samples=1024, n_refine=4, n_top=4,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# 3. Best-fit T (K), logN (cm^-2), A (au^2), and the spread of top solutions.
|
|
74
|
+
print(fit["params"]["C2H2"])
|
|
75
|
+
print(fit["uncertainty"]["C2H2"])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The sections below explain each step, and the
|
|
79
|
+
[first-spectrum guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html)
|
|
80
|
+
covers multi-stage fits, saved outputs, and plots.
|
|
81
|
+
|
|
51
82
|
## Runtime dependencies
|
|
52
83
|
|
|
53
84
|
| Package | Purpose |
|
|
@@ -56,7 +87,7 @@ notebook or contributor dependencies.
|
|
|
56
87
|
| `numpy` | Array operations |
|
|
57
88
|
| `pandas` | CSV I/O |
|
|
58
89
|
| `scipy` | L-BFGS-B optimizer, NNLS, Sobol sampling |
|
|
59
|
-
| `scikit-learn` |
|
|
90
|
+
| `scikit-learn` | PCA and scaling when training new models |
|
|
60
91
|
| `matplotlib` | Plotting |
|
|
61
92
|
|
|
62
93
|
## Continuum subtraction
|
|
@@ -91,12 +122,6 @@ With `preset=None, linefreefile=None` (or `""`), fitting uses all nonexcluded
|
|
|
91
122
|
pixels and skips the line-free correction, so `cont` equals `contOrig`.
|
|
92
123
|
Reference tables are bundled; normal continuum subtraction needs no model grids.
|
|
93
124
|
|
|
94
|
-
The private `0-Consub/` experiment directory is excluded from Git and is not
|
|
95
|
-
required by the installed package. Its runtime code and reference tables are
|
|
96
|
-
maintained under `src/diskmelts/consub/`.
|
|
97
|
-
The distributed tests in `tests/` exercise the installed continuum API and
|
|
98
|
-
bundled references without that private directory.
|
|
99
|
-
|
|
100
125
|
Returned `err` represents measurement/noise error, not correlated continuum
|
|
101
126
|
uncertainty. Broad excluded intervals require inspection. See the
|
|
102
127
|
[continuum guide](https://diskmelts.readthedocs.io/en/latest/continuum.html) for presets, regional box sizes,
|
|
@@ -143,31 +168,35 @@ You can also read spectra with your own code. DiskMELTS only requires
|
|
|
143
168
|
one-dimensional `obs_wav` and `obs_flux` arrays. Replace the sample CSV with
|
|
144
169
|
your own file to fit your source; update `distance_pc` and fit intervals.
|
|
145
170
|
|
|
146
|
-
For a complete staged fit-and-subtract workflow from a
|
|
171
|
+
For a complete staged fit-and-subtract workflow from a clone of the
|
|
172
|
+
repository, run:
|
|
147
173
|
|
|
148
174
|
```bash
|
|
149
175
|
python examples/dev_v2_realobs.py
|
|
176
|
+
python examples/dev_v2_realobs.py --input /path/to/my_spectrum.csv --name my_source --distance-pc 140 --sigma 2
|
|
150
177
|
```
|
|
151
178
|
|
|
179
|
+
Adjust that script's stage windows for your spectrum.
|
|
180
|
+
`python examples/synthetic_array_fit.py` generates an HCN spectrum and fits it
|
|
181
|
+
from in-memory arrays, without an observation file.
|
|
182
|
+
|
|
152
183
|
The v2 fitting API is `load_fitting_models`, `fit_stage`, `fit_observation`, and
|
|
153
|
-
`plot_saved_observation`. The production checkpoints are
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
`
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
The
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
be no hotter than C2H2 and gives them the same emitting area. It ties 13CO2
|
|
170
|
-
to CO2 in both temperature and area. Set
|
|
184
|
+
`plot_saved_observation`. The production checkpoints are included in the
|
|
185
|
+
wheel, so model fitting needs no local model grids. The checkpoint flux
|
|
186
|
+
convention is 1 au² at 140 pc; `distance_pc` sets the source distance and
|
|
187
|
+
makes the returned emitting area physical. `fit_observation` accepts either a
|
|
188
|
+
CSV path or in-memory `obs_wav`, `obs_flux`, and optional `obs_err` arrays
|
|
189
|
+
(new in 2.2.1).
|
|
190
|
+
|
|
191
|
+
For a synthetic spectrum, `wave, flux = diskmelts.synthesize_spectrum('HCN',
|
|
192
|
+
T=300, logN=18, A=1)` returns the native wavelength axis and model flux (new
|
|
193
|
+
in 2.2.1). See the
|
|
194
|
+
[generation guide](https://diskmelts.readthedocs.io/en/latest/generate_spectra.html).
|
|
195
|
+
|
|
196
|
+
The [fitting notebook](https://github.com/wddlx/DiskMELTS/blob/main/notebooks/Example_Fitting.ipynb)
|
|
197
|
+
requires 13C12CH2 to be no hotter than C2H2 and gives them the same emitting
|
|
198
|
+
area; it ties 13CO2 to CO2 in both temperature and area. Point its input at
|
|
199
|
+
your own continuum-subtracted CSV, or pass arrays. Set
|
|
171
200
|
`isotopologue_groups`, `Tshare` (`free`, `equal`, or `less`), and `Ashare` in a
|
|
172
201
|
joint stage to choose those constraints. See the
|
|
173
202
|
[fitting guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for examples.
|
|
@@ -179,6 +208,32 @@ separate method does require the full local grids. See the
|
|
|
179
208
|
plotting.
|
|
180
209
|
For complete sigma=2 grids, pass `grid_root='Model_grids/sigma2'`.
|
|
181
210
|
|
|
211
|
+
## Available molecules
|
|
212
|
+
|
|
213
|
+
Each molecule is available for two slab-model grids: sigma=0 (default) assumes
|
|
214
|
+
no turbulent broadening, so lines are only thermally broadened, and sigma=2
|
|
215
|
+
assumes 2 km/s turbulent broadening. Select sigma=2 with `load_fitting_models(..., sigma=2)` or
|
|
216
|
+
`fit_observation(..., sigma=2)`. Fit windows must lie inside a model's band.
|
|
217
|
+
|
|
218
|
+
| Molecule | Band (µm) | T (K) | logN (cm⁻²) |
|
|
219
|
+
|---|---|---|---|
|
|
220
|
+
| H2O | 4.9–25.0 (five overlapping tiles) | 100–1400 | 13–19 |
|
|
221
|
+
| C2H2 | 6–9 and 11.5–17 | 100–1400 | 13–19.5 |
|
|
222
|
+
| HCN, CO2, 13C12CH2, 13CO2 | 11.5–17 | 100–1400 | 13–19.5 |
|
|
223
|
+
| HC3N, CO17O, CO18O | 13–18 | 100–1400 | 13–19.5 |
|
|
224
|
+
| C4H2 | 14–18 | 100–1400 | 13–19.5 |
|
|
225
|
+
| C3H4, CH3 | 15–18 | 100–1400 | 13–19.5 |
|
|
226
|
+
| C6H6 | 13–17 | 100–675 | 13–19.5 |
|
|
227
|
+
| C2H6 | 9–15 | 100–1400 | 13–19.5 |
|
|
228
|
+
| C2H4 | 8–14 | 100–1400 | 13–19.5 |
|
|
229
|
+
| CH4 | 5–9 | 100–1400 | 13–19.5 |
|
|
230
|
+
| C2HD | 11.5–20.5 | 100–1400 | 13–19.5 |
|
|
231
|
+
| OH | 15–26 | 100–1400 | 13–19.5 |
|
|
232
|
+
|
|
233
|
+
`diskmelts.MODEL_SPECS` records the exact domains, PCA sizes, and network
|
|
234
|
+
layers. Version 2.2.0 lacks the sigma=0 OH and 6–9 µm C2H2 checkpoints;
|
|
235
|
+
upgrade with `python -m pip install -U diskmelts`.
|
|
236
|
+
|
|
182
237
|
## Training and validation data
|
|
183
238
|
|
|
184
239
|
Generated data under `Model_grids/` and `Pretrain_grid/` are intentionally
|
|
@@ -211,7 +266,7 @@ uses the same names with local `Model_grids/sigma0/C6H6/` and `Model_grids/sigma
|
|
|
211
266
|
files. See the [training guide](https://diskmelts.readthedocs.io/en/latest/training.html)
|
|
212
267
|
for peak audits and retraining commands.
|
|
213
268
|
|
|
214
|
-
|
|
269
|
+
The package also includes a CH3 checkpoint for 15–18 µm,
|
|
215
270
|
`T=100–1400 K`, and `logN=13–19.5`. Its strongest grid feature in this window
|
|
216
271
|
is near 16.4–16.6 µm. Use `load_fitting_models('CH3')` after installing this
|
|
217
272
|
package; direct-grid fitting uses local `Model_grids/sigma0/CH3/` files.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "diskmelts"
|
|
7
|
-
version = "2.2.
|
|
7
|
+
version = "2.2.2"
|
|
8
8
|
description = "Machine-learning Enabled Line fitting Tool for Spectra of protoplanetary disks"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -21,13 +21,15 @@ classifiers = [
|
|
|
21
21
|
"Topic :: Scientific/Engineering :: Astronomy",
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
|
-
|
|
24
|
+
# Checkpoints load with torch.load(weights_only=True), added in 1.13.
|
|
25
|
+
"torch>=1.13",
|
|
25
26
|
# Intel macOS wheels stop at PyTorch 2.2, whose NumPy bridge needs NumPy 1.x.
|
|
26
27
|
"numpy>=1.26,<2; sys_platform == 'darwin' and platform_machine == 'x86_64'",
|
|
27
28
|
"numpy; sys_platform != 'darwin' or platform_machine != 'x86_64'",
|
|
28
29
|
"pandas",
|
|
29
30
|
"scipy",
|
|
30
|
-
|
|
31
|
+
# Used only to fit PCA/scalers when training; checkpoints store plain arrays.
|
|
32
|
+
"scikit-learn>=1.0",
|
|
31
33
|
"matplotlib",
|
|
32
34
|
]
|
|
33
35
|
|
|
@@ -12,6 +12,7 @@ from diskmelts.trainmodel import (
|
|
|
12
12
|
train_model_bank,
|
|
13
13
|
select_grid_holdout,
|
|
14
14
|
tune_pca_components,
|
|
15
|
+
convert_legacy_checkpoint,
|
|
15
16
|
)
|
|
16
17
|
from diskmelts.fitting import (
|
|
17
18
|
load_models,
|
|
@@ -41,6 +42,7 @@ from diskmelts.v2_fitting import (
|
|
|
41
42
|
MODEL_SPECS,
|
|
42
43
|
SIGMA2_MODEL_SPECS,
|
|
43
44
|
load_fitting_models,
|
|
45
|
+
synthesize_spectrum,
|
|
44
46
|
fit_stage,
|
|
45
47
|
fit_observation,
|
|
46
48
|
)
|
|
@@ -61,6 +63,7 @@ __all__ = [
|
|
|
61
63
|
"MODEL_SPECS",
|
|
62
64
|
"SIGMA2_MODEL_SPECS",
|
|
63
65
|
"load_fitting_models",
|
|
66
|
+
"synthesize_spectrum",
|
|
64
67
|
"fit_stage",
|
|
65
68
|
"fit_observation",
|
|
66
69
|
"fit_grid_stage",
|
|
@@ -76,6 +79,7 @@ __all__ = [
|
|
|
76
79
|
"train_model_bank",
|
|
77
80
|
"select_grid_holdout",
|
|
78
81
|
"tune_pca_components",
|
|
82
|
+
"convert_legacy_checkpoint",
|
|
79
83
|
# fitting
|
|
80
84
|
"load_models",
|
|
81
85
|
"load_model_bank",
|
|
@@ -41,6 +41,8 @@ def _regions(regions):
|
|
|
41
41
|
a = np.asarray(regions, dtype=float)
|
|
42
42
|
if a.size == 0:
|
|
43
43
|
return np.empty((0, 2))
|
|
44
|
+
if a.shape == (2,):
|
|
45
|
+
a = a[np.newaxis]
|
|
44
46
|
if a.ndim != 2 or a.shape[1] != 2 or not np.all(np.isfinite(a)) or np.any(a[:, 1] <= a[:, 0]):
|
|
45
47
|
raise ValueError("Regions must be finite (xmin, xmax) pairs with xmin < xmax")
|
|
46
48
|
return a
|
|
@@ -128,11 +130,21 @@ def _mad(a):
|
|
|
128
130
|
return 1.4826 * np.median(np.abs(a - np.median(a)))
|
|
129
131
|
|
|
130
132
|
|
|
131
|
-
def _interp(x, xp, yp):
|
|
133
|
+
def _interp(x, xp, yp, linear_ends=False):
|
|
132
134
|
if len(xp) == 1:
|
|
133
135
|
return np.full(len(x), yp[0])
|
|
134
136
|
# Constant end corrections avoid unstable polynomial extrapolation.
|
|
135
|
-
|
|
137
|
+
out = PchipInterpolator(xp, yp)(np.clip(x, xp[0], xp[-1]))
|
|
138
|
+
if linear_ends:
|
|
139
|
+
# A sloped continuum beyond the last knot needs a slope, not a constant;
|
|
140
|
+
# fit it over about 1 um of knots so one noisy knot cannot set it.
|
|
141
|
+
xp, yp = np.asarray(xp), np.asarray(yp)
|
|
142
|
+
for outside, end, near in ((x < xp[0], 0, xp <= xp[0] + 1.0),
|
|
143
|
+
(x > xp[-1], -1, xp >= xp[-1] - 1.0)):
|
|
144
|
+
if outside.any() and near.sum() >= 2:
|
|
145
|
+
slope = np.polyfit(xp[near], yp[near], 1)[0]
|
|
146
|
+
out[outside] = yp[end] + slope * (x[outside] - xp[end])
|
|
147
|
+
return out
|
|
136
148
|
|
|
137
149
|
|
|
138
150
|
def _widths(x, good, boxsizes):
|
|
@@ -143,7 +155,7 @@ def _widths(x, good, boxsizes):
|
|
|
143
155
|
n = np.convolve(good.astype(float), np.ones(min(101, len(x))), "same")
|
|
144
156
|
fraction = np.maximum(n / min(101, len(x)), 0.05)
|
|
145
157
|
return np.clip(31 * dx / fraction, 0.25, 1.0)
|
|
146
|
-
if np.
|
|
158
|
+
if np.ndim(boxsizes) == 0:
|
|
147
159
|
if not np.isfinite(boxsizes) or boxsizes < 5:
|
|
148
160
|
raise ValueError("boxsizes must be at least 5 pixels")
|
|
149
161
|
return dx * float(boxsizes)
|
|
@@ -188,7 +200,7 @@ def _local_baseline(x, y, noise, good, widths):
|
|
|
188
200
|
if len(positions) < 3:
|
|
189
201
|
raise ValueError("Too few continuum windows; widen boxsizes or revise masks")
|
|
190
202
|
knots = pd.DataFrame({"x": positions, "y": values}).groupby("x", sort=True).median()
|
|
191
|
-
return _interp(x, knots.index.to_numpy(), knots.y.to_numpy())
|
|
203
|
+
return _interp(x, knots.index.to_numpy(), knots.y.to_numpy(), linear_ends=True)
|
|
192
204
|
|
|
193
205
|
|
|
194
206
|
def _arpls(x, y, noise, good, widths):
|
|
@@ -203,10 +215,12 @@ def _arpls(x, y, noise, good, widths):
|
|
|
203
215
|
weights = base.copy()
|
|
204
216
|
converged = False
|
|
205
217
|
for _ in range(40):
|
|
206
|
-
z = spsolve(diags(weights) + penalty, weights*y)
|
|
218
|
+
z = spsolve((diags(weights) + penalty).tocsc(), weights*y)
|
|
207
219
|
residual = y-z
|
|
208
220
|
negative = residual[good & (residual < 0)]
|
|
209
221
|
if len(negative) < 3:
|
|
222
|
+
# Nothing left below the baseline to down-weight: a fixed point.
|
|
223
|
+
converged = True
|
|
210
224
|
break
|
|
211
225
|
scale = max(np.std(negative), np.median(noise[good])*0.1)
|
|
212
226
|
new = base * expit(-2*(residual - (2*scale-np.mean(negative)))/scale)
|
|
@@ -354,8 +368,11 @@ def subtract_continuum(wav, flux, *, error=None, exclude=None, boxsizes=None,
|
|
|
354
368
|
unsupported |= (x < x[reference][0]) | (x > x[reference][-1])
|
|
355
369
|
cont_error[unsupported] = np.nan
|
|
356
370
|
if unsupported.any():
|
|
357
|
-
|
|
358
|
-
|
|
371
|
+
edges = np.flatnonzero(np.diff(np.r_[0, unsupported.astype(int), 0]))
|
|
372
|
+
spans = ", ".join(f"{x[a]:.2f}-{x[b-1]:.2f}" for a, b in zip(edges[::2], edges[1::2]))
|
|
373
|
+
warnings.warn(f"Continuum is interpolated or extrapolated without nearby reference "
|
|
374
|
+
f"pixels at {spans} um (weak_support column); inspect the plot before "
|
|
375
|
+
"using those regions", stacklevel=2)
|
|
359
376
|
result = pd.DataFrame({"wave": x, "flux": original-continuum,
|
|
360
377
|
"err": measurement, "cont": continuum,
|
|
361
378
|
"cont_unshifted": baseline, "raw_flux": original,
|