diskmelts 2.1.2__tar.gz → 2.2.1__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.1/MANIFEST.in +2 -0
- {diskmelts-2.1.2/src/diskmelts.egg-info → diskmelts-2.2.1}/PKG-INFO +109 -26
- {diskmelts-2.1.2 → diskmelts-2.2.1}/README.md +105 -22
- {diskmelts-2.1.2 → diskmelts-2.2.1}/pyproject.toml +8 -5
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/__init__.py +4 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/_core.py +24 -7
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/fitting.py +189 -120
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/C2H2_model_bank.json +26 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/net_C2H2_w6to9.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0/CH3_single_v2/net_CH3_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/H2O_model_bank.json +1 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0/OH_single_v2/net_OH_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/C2H2_model_bank.json +26 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w11p5to17.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2H2_wavelength_bank_v2/net_C2H2_w6to9.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C4H2_single_v2/net_C4H2_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/C6H6_single_v2/net_C6H6_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/CH3_single_v2/net_CH3_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/CH4_single_v2/net_CH4_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/CO2_single_v2/net_CO2_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/H2O_model_bank.json +132 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w19to25_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/HC3N_single_v2/net_HC3N_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/HCN_single_v2/net_HCN_forward.pt +0 -0
- diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma2/OH_single_v2/net_OH_forward.pt +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/plotting.py +3 -1
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/trainmodel.py +27 -10
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/v2_fitting.py +233 -35
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/v2_grid_fitting.py +119 -57
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/validation.py +23 -7
- {diskmelts-2.1.2 → diskmelts-2.2.1/src/diskmelts.egg-info}/PKG-INFO +109 -26
- diskmelts-2.2.1/src/diskmelts.egg-info/SOURCES.txt +81 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts.egg-info/requires.txt +2 -2
- diskmelts-2.1.2/src/diskmelts.egg-info/SOURCES.txt +0 -65
- diskmelts-2.1.2/tests/test_consub_package.py +0 -99
- diskmelts-2.1.2/tests/test_detection.py +0 -133
- diskmelts-2.1.2/tests/test_dev_v2_fitting_distance.py +0 -41
- diskmelts-2.1.2/tests/test_dev_v2_fitting_grids.py +0 -175
- diskmelts-2.1.2/tests/test_dev_v2_read_plot.py +0 -95
- diskmelts-2.1.2/tests/test_imports.py +0 -60
- diskmelts-2.1.2/tests/test_io.py +0 -80
- diskmelts-2.1.2/tests/test_mlp.py +0 -43
- diskmelts-2.1.2/tests/test_model_bank.py +0 -228
- diskmelts-2.1.2/tests/test_shared_area_fitting.py +0 -190
- diskmelts-2.1.2/tests/test_smoke.py +0 -48
- diskmelts-2.1.2/tests/test_v2_package_assets.py +0 -44
- diskmelts-2.1.2/tests/test_water_training.py +0 -126
- diskmelts-2.1.2/tests/test_workflows.py +0 -240
- {diskmelts-2.1.2 → diskmelts-2.2.1}/LICENSE +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/setup.cfg +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/__init__.py +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/_api.py +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/cont_ranges.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/cont_ranges_PPan.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/carbon_extended.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/carbon_extended.json +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/carbon_rich.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/carbon_rich.json +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/ttauri.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/ttauri.json +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/water.csv +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/consub/regions/water.json +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/13C12CH2_single_v2/net_13C12CH2_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/13CO2_single_v2/net_13CO2_forward.pt +0 -0
- /diskmelts-2.1.2/src/diskmelts/models/Trained_model/C2H2_single_v2/net_C2H2_forward.pt → /diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0/C2H2_wavelength_bank_v2/net_C2H2_w11p5to17.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C2H4_single_v2/net_C2H4_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C2H6_single_v2/net_C2H6_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C2HD_single_v2/net_C2HD_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C3H4_single_v2/net_C3H4_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C4H2_single_v2/net_C4H2_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/C6H6_single_v2/net_C6H6_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/CH4_single_v2/net_CH4_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/CO17O_single_v2/net_CO17O_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/CO18O_single_v2/net_CO18O_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/CO2_single_v2/net_CO2_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/net_H2O_w13p5to19p2_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/net_H2O_w19to25_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/net_H2O_w4p9to7p4_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/net_H2O_w7p2to11p2_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/H2O_wavelength_bank_v2_fixed/net_H2O_w9p9to15p1_n13to19_t100to1400.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/HC3N_single_v2/net_HC3N_forward.pt +0 -0
- {diskmelts-2.1.2/src/diskmelts/models/Trained_model → diskmelts-2.2.1/src/diskmelts/models/Trained_model/sigma0}/HCN_single_v2/net_HCN_forward.pt +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/v2_paper_comparison.py +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts/v2_read_plot.py +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/src/diskmelts.egg-info/dependency_links.txt +0 -0
- {diskmelts-2.1.2 → diskmelts-2.2.1}/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.1
|
|
3
|
+
Version: 2.2.1
|
|
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
|
|
@@ -12,15 +12,15 @@ Keywords: astronomy,protoplanetary disks,JWST,spectral fitting,machine learning
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.11
|
|
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.9,>=1.8
|
|
24
24
|
Requires-Dist: matplotlib
|
|
25
25
|
Provides-Extra: io
|
|
26
26
|
Requires-Dist: astropy; extra == "io"
|
|
@@ -49,9 +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
|
-
|
|
52
|
+
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/) and
|
|
53
|
+
requires Python 3.11 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
|
|
55
57
|
`python` in an activated environment; the
|
|
56
58
|
[installation guide](https://diskmelts.readthedocs.io/en/latest/installation.html)
|
|
57
59
|
shows how to create one on macOS, Linux, Windows, or Conda:
|
|
@@ -74,6 +76,48 @@ downloads; pass their local path as `grid_root`.
|
|
|
74
76
|
Example notebooks and spectra can be downloaded from the repository when
|
|
75
77
|
needed; they are not installed by pip.
|
|
76
78
|
|
|
79
|
+
To install from a checkout with Conda or Mamba, run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
git clone https://github.com/wddlx/DiskMELTS.git
|
|
83
|
+
cd DiskMELTS
|
|
84
|
+
conda env create -f environment.yaml
|
|
85
|
+
conda activate diskmelts
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `environment-notebooks.yaml` or `environment-dev.yaml` for the corresponding
|
|
89
|
+
notebook or contributor dependencies.
|
|
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
|
+
|
|
77
121
|
## Runtime dependencies
|
|
78
122
|
|
|
79
123
|
| Package | Purpose |
|
|
@@ -117,12 +161,6 @@ With `preset=None, linefreefile=None` (or `""`), fitting uses all nonexcluded
|
|
|
117
161
|
pixels and skips the line-free correction, so `cont` equals `contOrig`.
|
|
118
162
|
Reference tables are bundled; normal continuum subtraction needs no model grids.
|
|
119
163
|
|
|
120
|
-
The private `0-Consub/` experiment directory is excluded from Git and is not
|
|
121
|
-
required by the installed package. Its runtime code and reference tables are
|
|
122
|
-
maintained under `src/diskmelts/consub/`.
|
|
123
|
-
The distributed tests in `tests/` exercise the installed continuum API and
|
|
124
|
-
bundled references without that private directory.
|
|
125
|
-
|
|
126
164
|
Returned `err` represents measurement/noise error, not correlated continuum
|
|
127
165
|
uncertainty. Broad excluded intervals require inspection. See the
|
|
128
166
|
[continuum guide](https://diskmelts.readthedocs.io/en/latest/continuum.html) for presets, regional box sizes,
|
|
@@ -169,31 +207,71 @@ You can also read spectra with your own code. DiskMELTS only requires
|
|
|
169
207
|
one-dimensional `obs_wav` and `obs_flux` arrays. Replace the sample CSV with
|
|
170
208
|
your own file to fit your source; update `distance_pc` and fit intervals.
|
|
171
209
|
|
|
172
|
-
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:
|
|
173
212
|
|
|
174
213
|
```bash
|
|
175
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
|
|
176
216
|
```
|
|
177
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
|
+
|
|
178
222
|
The v2 fitting API is `load_fitting_models`, `fit_stage`, `fit_observation`, and
|
|
179
|
-
`plot_saved_observation`. The production checkpoints are
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
188
239
|
`isotopologue_groups`, `Tshare` (`free`, `equal`, or `less`), and `Ashare` in a
|
|
189
240
|
joint stage to choose those constraints. See the
|
|
190
241
|
[fitting guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for examples.
|
|
191
242
|
|
|
192
243
|
For an optional fit directly from slab grids, use `fit_grid_stage` or
|
|
193
|
-
`fit_observation_grids` and supply `grid_root='Model_grids'` explicitly. This
|
|
244
|
+
`fit_observation_grids` and supply `grid_root='Model_grids/sigma0'` explicitly. This
|
|
194
245
|
separate method does require the full local grids. See the
|
|
195
246
|
[quick start](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for both workflows and saved-result
|
|
196
247
|
plotting.
|
|
248
|
+
For complete sigma=2 grids, pass `grid_root='Model_grids/sigma2'`.
|
|
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`.
|
|
197
275
|
|
|
198
276
|
## Training and validation data
|
|
199
277
|
|
|
@@ -203,7 +281,7 @@ checkpoint directories under the top-level `Trained_model/` are also optional; t
|
|
|
203
281
|
only the production checkpoints needed for v2 fitting. To run
|
|
204
282
|
`examples/dev_v2_pt_validation.py` or
|
|
205
283
|
`notebooks/Example_Training_Validation.ipynb`, place the complete model grids
|
|
206
|
-
under `Model_grids/<molecule>/`. The workflows create or reuse the corresponding
|
|
284
|
+
under `Model_grids/sigma0/<molecule>/`. The workflows create or reuse the corresponding
|
|
207
285
|
pretraining CSV under `Pretrain_grid/`.
|
|
208
286
|
|
|
209
287
|
The maintained v2 workflow uses a hybrid design after restricting the expanded
|
|
@@ -223,10 +301,15 @@ DISKMELTS_MOLECULES=13C12CH2,C2HD,CO17O,CO18O python examples/dev_v2_pt_validati
|
|
|
223
301
|
C6H6 and C3H4 also have bundled fitting checkpoints. The C6H6 checkpoint
|
|
224
302
|
covers 13–17 µm and 100–675 K; C3H4 covers 15–18 µm and 100–1400 K. Load
|
|
225
303
|
either by name with `load_fitting_models`. Direct grid fitting
|
|
226
|
-
uses the same names with local `Model_grids/C6H6/` and `Model_grids/C3H4/`
|
|
304
|
+
uses the same names with local `Model_grids/sigma0/C6H6/` and `Model_grids/sigma0/C3H4/`
|
|
227
305
|
files. See the [training guide](https://diskmelts.readthedocs.io/en/latest/training.html)
|
|
228
306
|
for peak audits and retraining commands.
|
|
229
307
|
|
|
308
|
+
The package also includes a CH3 checkpoint for 15–18 µm,
|
|
309
|
+
`T=100–1400 K`, and `logN=13–19.5`. Its strongest grid feature in this window
|
|
310
|
+
is near 16.4–16.6 µm. Use `load_fitting_models('CH3')` after installing this
|
|
311
|
+
package; direct-grid fitting uses local `Model_grids/sigma0/CH3/` files.
|
|
312
|
+
|
|
230
313
|
Five to ten percent of complete `(T, logN)` grid spectra are excluded before
|
|
231
314
|
PCA or neural-network training. They are used to select the PCA dimension and
|
|
232
315
|
to validate spectral reconstruction and full parameter fitting. The
|
|
@@ -10,9 +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
|
-
|
|
13
|
+
DiskMELTS is available on [PyPI](https://pypi.org/project/diskmelts/) and
|
|
14
|
+
requires Python 3.11 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
|
|
16
18
|
`python` in an activated environment; the
|
|
17
19
|
[installation guide](https://diskmelts.readthedocs.io/en/latest/installation.html)
|
|
18
20
|
shows how to create one on macOS, Linux, Windows, or Conda:
|
|
@@ -35,6 +37,48 @@ downloads; pass their local path as `grid_root`.
|
|
|
35
37
|
Example notebooks and spectra can be downloaded from the repository when
|
|
36
38
|
needed; they are not installed by pip.
|
|
37
39
|
|
|
40
|
+
To install from a checkout with Conda or Mamba, run:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/wddlx/DiskMELTS.git
|
|
44
|
+
cd DiskMELTS
|
|
45
|
+
conda env create -f environment.yaml
|
|
46
|
+
conda activate diskmelts
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Use `environment-notebooks.yaml` or `environment-dev.yaml` for the corresponding
|
|
50
|
+
notebook or contributor dependencies.
|
|
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
|
+
|
|
38
82
|
## Runtime dependencies
|
|
39
83
|
|
|
40
84
|
| Package | Purpose |
|
|
@@ -78,12 +122,6 @@ With `preset=None, linefreefile=None` (or `""`), fitting uses all nonexcluded
|
|
|
78
122
|
pixels and skips the line-free correction, so `cont` equals `contOrig`.
|
|
79
123
|
Reference tables are bundled; normal continuum subtraction needs no model grids.
|
|
80
124
|
|
|
81
|
-
The private `0-Consub/` experiment directory is excluded from Git and is not
|
|
82
|
-
required by the installed package. Its runtime code and reference tables are
|
|
83
|
-
maintained under `src/diskmelts/consub/`.
|
|
84
|
-
The distributed tests in `tests/` exercise the installed continuum API and
|
|
85
|
-
bundled references without that private directory.
|
|
86
|
-
|
|
87
125
|
Returned `err` represents measurement/noise error, not correlated continuum
|
|
88
126
|
uncertainty. Broad excluded intervals require inspection. See the
|
|
89
127
|
[continuum guide](https://diskmelts.readthedocs.io/en/latest/continuum.html) for presets, regional box sizes,
|
|
@@ -130,31 +168,71 @@ You can also read spectra with your own code. DiskMELTS only requires
|
|
|
130
168
|
one-dimensional `obs_wav` and `obs_flux` arrays. Replace the sample CSV with
|
|
131
169
|
your own file to fit your source; update `distance_pc` and fit intervals.
|
|
132
170
|
|
|
133
|
-
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:
|
|
134
173
|
|
|
135
174
|
```bash
|
|
136
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
|
|
137
177
|
```
|
|
138
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
|
+
|
|
139
183
|
The v2 fitting API is `load_fitting_models`, `fit_stage`, `fit_observation`, and
|
|
140
|
-
`plot_saved_observation`. The production checkpoints are
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
|
149
200
|
`isotopologue_groups`, `Tshare` (`free`, `equal`, or `less`), and `Ashare` in a
|
|
150
201
|
joint stage to choose those constraints. See the
|
|
151
202
|
[fitting guide](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for examples.
|
|
152
203
|
|
|
153
204
|
For an optional fit directly from slab grids, use `fit_grid_stage` or
|
|
154
|
-
`fit_observation_grids` and supply `grid_root='Model_grids'` explicitly. This
|
|
205
|
+
`fit_observation_grids` and supply `grid_root='Model_grids/sigma0'` explicitly. This
|
|
155
206
|
separate method does require the full local grids. See the
|
|
156
207
|
[quick start](https://diskmelts.readthedocs.io/en/latest/quickstart.html) for both workflows and saved-result
|
|
157
208
|
plotting.
|
|
209
|
+
For complete sigma=2 grids, pass `grid_root='Model_grids/sigma2'`.
|
|
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`.
|
|
158
236
|
|
|
159
237
|
## Training and validation data
|
|
160
238
|
|
|
@@ -164,7 +242,7 @@ checkpoint directories under the top-level `Trained_model/` are also optional; t
|
|
|
164
242
|
only the production checkpoints needed for v2 fitting. To run
|
|
165
243
|
`examples/dev_v2_pt_validation.py` or
|
|
166
244
|
`notebooks/Example_Training_Validation.ipynb`, place the complete model grids
|
|
167
|
-
under `Model_grids/<molecule>/`. The workflows create or reuse the corresponding
|
|
245
|
+
under `Model_grids/sigma0/<molecule>/`. The workflows create or reuse the corresponding
|
|
168
246
|
pretraining CSV under `Pretrain_grid/`.
|
|
169
247
|
|
|
170
248
|
The maintained v2 workflow uses a hybrid design after restricting the expanded
|
|
@@ -184,10 +262,15 @@ DISKMELTS_MOLECULES=13C12CH2,C2HD,CO17O,CO18O python examples/dev_v2_pt_validati
|
|
|
184
262
|
C6H6 and C3H4 also have bundled fitting checkpoints. The C6H6 checkpoint
|
|
185
263
|
covers 13–17 µm and 100–675 K; C3H4 covers 15–18 µm and 100–1400 K. Load
|
|
186
264
|
either by name with `load_fitting_models`. Direct grid fitting
|
|
187
|
-
uses the same names with local `Model_grids/C6H6/` and `Model_grids/C3H4/`
|
|
265
|
+
uses the same names with local `Model_grids/sigma0/C6H6/` and `Model_grids/sigma0/C3H4/`
|
|
188
266
|
files. See the [training guide](https://diskmelts.readthedocs.io/en/latest/training.html)
|
|
189
267
|
for peak audits and retraining commands.
|
|
190
268
|
|
|
269
|
+
The package also includes a CH3 checkpoint for 15–18 µm,
|
|
270
|
+
`T=100–1400 K`, and `logN=13–19.5`. Its strongest grid feature in this window
|
|
271
|
+
is near 16.4–16.6 µm. Use `load_fitting_models('CH3')` after installing this
|
|
272
|
+
package; direct-grid fitting uses local `Model_grids/sigma0/CH3/` files.
|
|
273
|
+
|
|
191
274
|
Five to ten percent of complete `(T, logN)` grid spectra are excluded before
|
|
192
275
|
PCA or neural-network training. They are used to select the PCA dimension and
|
|
193
276
|
to validate spectral reconstruction and full parameter fitting. The
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "diskmelts"
|
|
7
|
-
version = "2.1
|
|
7
|
+
version = "2.2.1"
|
|
8
8
|
description = "Machine-learning Enabled Line fitting Tool for Spectra of protoplanetary disks"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [
|
|
@@ -21,13 +21,16 @@ classifiers = [
|
|
|
21
21
|
"Topic :: Scientific/Engineering :: Astronomy",
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
|
-
|
|
24
|
+
# Checkpoints load with torch.load(weights_only=False), 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
|
+
# Bundled checkpoints pickle scikit-learn 1.8 PCA/scaler objects; keep the
|
|
32
|
+
# same minor version so they unpickle without a cross-version warning.
|
|
33
|
+
"scikit-learn>=1.8,<1.9",
|
|
31
34
|
"matplotlib",
|
|
32
35
|
]
|
|
33
36
|
|
|
@@ -47,7 +50,7 @@ notebooks = ["jupyterlab", "ipykernel"]
|
|
|
47
50
|
where = ["src"]
|
|
48
51
|
|
|
49
52
|
[tool.setuptools.package-data]
|
|
50
|
-
diskmelts = ["models/Trained_model
|
|
53
|
+
diskmelts = ["models/Trained_model/sigma*/*/*.pt", "models/Trained_model/sigma*/*/*.json",
|
|
51
54
|
"consub/*.csv", "consub/regions/*.csv", "consub/regions/*.json"]
|
|
52
55
|
|
|
53
56
|
[tool.pytest.ini_options]
|
|
@@ -39,7 +39,9 @@ from diskmelts.plotting import (
|
|
|
39
39
|
)
|
|
40
40
|
from diskmelts.v2_fitting import (
|
|
41
41
|
MODEL_SPECS,
|
|
42
|
+
SIGMA2_MODEL_SPECS,
|
|
42
43
|
load_fitting_models,
|
|
44
|
+
synthesize_spectrum,
|
|
43
45
|
fit_stage,
|
|
44
46
|
fit_observation,
|
|
45
47
|
)
|
|
@@ -58,7 +60,9 @@ from diskmelts import consub
|
|
|
58
60
|
__all__ = [
|
|
59
61
|
"consub",
|
|
60
62
|
"MODEL_SPECS",
|
|
63
|
+
"SIGMA2_MODEL_SPECS",
|
|
61
64
|
"load_fitting_models",
|
|
65
|
+
"synthesize_spectrum",
|
|
62
66
|
"fit_stage",
|
|
63
67
|
"fit_observation",
|
|
64
68
|
"fit_grid_stage",
|
|
@@ -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,
|