lated 0.1.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.
Files changed (79) hide show
  1. lated-0.1.0/CHANGELOG.md +22 -0
  2. lated-0.1.0/LICENSE +21 -0
  3. lated-0.1.0/MANIFEST.in +4 -0
  4. lated-0.1.0/PKG-INFO +157 -0
  5. lated-0.1.0/README.md +123 -0
  6. lated-0.1.0/examples/quickstart.ipynb +506 -0
  7. lated-0.1.0/pyproject.toml +54 -0
  8. lated-0.1.0/setup.cfg +4 -0
  9. lated-0.1.0/src/lated/__init__.py +35 -0
  10. lated-0.1.0/src/lated/cli.py +72 -0
  11. lated-0.1.0/src/lated/config.py +258 -0
  12. lated-0.1.0/src/lated/data/filters/F070W.dat +201 -0
  13. lated-0.1.0/src/lated/data/filters/F090W.dat +255 -0
  14. lated-0.1.0/src/lated/data/filters/F1000W.dat +479 -0
  15. lated-0.1.0/src/lated/data/filters/F1130W.dat +342 -0
  16. lated-0.1.0/src/lated/data/filters/F115W.dat +342 -0
  17. lated-0.1.0/src/lated/data/filters/F1280W.dat +609 -0
  18. lated-0.1.0/src/lated/data/filters/F140M.dat +257 -0
  19. lated-0.1.0/src/lated/data/filters/F1500W.dat +817 -0
  20. lated-0.1.0/src/lated/data/filters/F150W.dat +447 -0
  21. lated-0.1.0/src/lated/data/filters/F150W2.dat +1502 -0
  22. lated-0.1.0/src/lated/data/filters/F162M.dat +296 -0
  23. lated-0.1.0/src/lated/data/filters/F164N.dat +72 -0
  24. lated-0.1.0/src/lated/data/filters/F1800W.dat +1035 -0
  25. lated-0.1.0/src/lated/data/filters/F182M.dat +384 -0
  26. lated-0.1.0/src/lated/data/filters/F187N.dat +80 -0
  27. lated-0.1.0/src/lated/data/filters/F200W.dat +611 -0
  28. lated-0.1.0/src/lated/data/filters/F2100W.dat +1455 -0
  29. lated-0.1.0/src/lated/data/filters/F210M.dat +337 -0
  30. lated-0.1.0/src/lated/data/filters/F212N.dat +85 -0
  31. lated-0.1.0/src/lated/data/filters/F250M.dat +237 -0
  32. lated-0.1.0/src/lated/data/filters/F2550W.dat +1482 -0
  33. lated-0.1.0/src/lated/data/filters/F277W.dat +806 -0
  34. lated-0.1.0/src/lated/data/filters/F300M.dat +457 -0
  35. lated-0.1.0/src/lated/data/filters/F322W2.dat +1367 -0
  36. lated-0.1.0/src/lated/data/filters/F323N.dat +89 -0
  37. lated-0.1.0/src/lated/data/filters/F335M.dat +559 -0
  38. lated-0.1.0/src/lated/data/filters/F356W.dat +918 -0
  39. lated-0.1.0/src/lated/data/filters/F360M.dat +555 -0
  40. lated-0.1.0/src/lated/data/filters/F405N.dat +124 -0
  41. lated-0.1.0/src/lated/data/filters/F410M.dat +631 -0
  42. lated-0.1.0/src/lated/data/filters/F430M.dat +333 -0
  43. lated-0.1.0/src/lated/data/filters/F444W.dat +1029 -0
  44. lated-0.1.0/src/lated/data/filters/F460M.dat +382 -0
  45. lated-0.1.0/src/lated/data/filters/F466N.dat +135 -0
  46. lated-0.1.0/src/lated/data/filters/F470N.dat +131 -0
  47. lated-0.1.0/src/lated/data/filters/F480M.dat +455 -0
  48. lated-0.1.0/src/lated/data/filters/F560W.dat +338 -0
  49. lated-0.1.0/src/lated/data/filters/F770W.dat +539 -0
  50. lated-0.1.0/src/lated/data/filters/RomanF062.dat +70 -0
  51. lated-0.1.0/src/lated/data/filters/RomanF087.dat +62 -0
  52. lated-0.1.0/src/lated/data/filters/RomanF106.dat +75 -0
  53. lated-0.1.0/src/lated/data/filters/RomanF129.dat +90 -0
  54. lated-0.1.0/src/lated/data/filters/RomanF146.dat +243 -0
  55. lated-0.1.0/src/lated/data/filters/RomanF158.dat +109 -0
  56. lated-0.1.0/src/lated/data/filters/RomanF184.dat +98 -0
  57. lated-0.1.0/src/lated/data/filters/RomanF213.dat +109 -0
  58. lated-0.1.0/src/lated/dust.py +40 -0
  59. lated-0.1.0/src/lated/engine.py +582 -0
  60. lated-0.1.0/src/lated/filters.py +198 -0
  61. lated-0.1.0/src/lated/lines.py +183 -0
  62. lated-0.1.0/src/lated/presets.py +26 -0
  63. lated-0.1.0/src/lated/server/__init__.py +0 -0
  64. lated-0.1.0/src/lated/server/app.py +140 -0
  65. lated-0.1.0/src/lated/server/static/app.css +579 -0
  66. lated-0.1.0/src/lated/server/static/app.js +1147 -0
  67. lated-0.1.0/src/lated/server/static/index.html +244 -0
  68. lated-0.1.0/src/lated/server/static/plot.js +718 -0
  69. lated-0.1.0/src/lated.egg-info/PKG-INFO +157 -0
  70. lated-0.1.0/src/lated.egg-info/SOURCES.txt +77 -0
  71. lated-0.1.0/src/lated.egg-info/dependency_links.txt +1 -0
  72. lated-0.1.0/src/lated.egg-info/entry_points.txt +2 -0
  73. lated-0.1.0/src/lated.egg-info/requires.txt +9 -0
  74. lated-0.1.0/src/lated.egg-info/top_level.txt +1 -0
  75. lated-0.1.0/tests/test_api.py +130 -0
  76. lated-0.1.0/tests/test_case_b_and_draws.py +112 -0
  77. lated-0.1.0/tests/test_engine.py +214 -0
  78. lated-0.1.0/tests/test_improvements.py +152 -0
  79. lated-0.1.0/tests/test_parity.py +191 -0
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-07-08)
4
+
5
+ Initial public release, accompanying LATED Paper I.
6
+
7
+ - Transparent fitting engine: power-law continuum + emission lines fitted
8
+ through real filter transmission curves, with every parameter's role
9
+ (free / fixed / tied) explicit and user-configurable.
10
+ - Exact numerical parity with the LATED paper pipeline in bootstrap mode;
11
+ a posterior (truncated-Gaussian Gibbs) sampler as the statistically
12
+ preferred alternative for upper/lower limits.
13
+ - Balmer-ratio ties from Osterbrock & Ferland (2006) Case A/B tables,
14
+ selectable by (T_e, n_e); dust via Calzetti or SMC with A_V uncertainty
15
+ propagation.
16
+ - 46 bundled JWST NIRCam + MIRI and Roman WFI filter curves (SVO).
17
+ - Line-ratio verdicts (measured / 2-sigma upper / lower limit /
18
+ unconstrained) with per-line flux sensitivities and depth warnings.
19
+ - FastAPI + vanilla-JS web application (`lated serve`): SED and corner
20
+ plots as publication-ready SVG/PDF, literature one-click examples,
21
+ full parameter-role controls.
22
+ - Python API quickstart notebook in `examples/`.
lated-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mingyu Li
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ # sdist extras beyond what setuptools includes automatically
2
+ include CHANGELOG.md
3
+ recursive-include tests *.py
4
+ recursive-include examples *.ipynb
lated-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,157 @@
1
+ Metadata-Version: 2.4
2
+ Name: lated
3
+ Version: 0.1.0
4
+ Summary: LATED photometric emission-line recovery: transparent continuum + line fits through real filter curves, with a web application
5
+ Author-email: Mingyu Li <lmytime@hotmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/lmytime/lated
8
+ Project-URL: Repository, https://github.com/lmytime/lated
9
+ Project-URL: Documentation, https://github.com/lmytime/lated#readme
10
+ Keywords: astronomy,astrophysics,photometry,emission-lines,JWST,NIRCam,SED,high-redshift
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy>=1.20
26
+ Requires-Dist: scipy>=1.7
27
+ Requires-Dist: pydantic>=2.0
28
+ Requires-Dist: fastapi>=0.100
29
+ Requires-Dist: uvicorn>=0.20
30
+ Provides-Extra: test
31
+ Requires-Dist: pytest; extra == "test"
32
+ Requires-Dist: httpx; extra == "test"
33
+ Dynamic: license-file
34
+
35
+ # LATED
36
+
37
+ **Measure emission lines you can't spectroscopically resolve, straight from photometry.**
38
+
39
+ [![PyPI version](https://img.shields.io/pypi/v/lated.svg)](https://pypi.org/project/lated/)
40
+ [![Python versions](https://img.shields.io/pypi/pyversions/lated.svg)](https://pypi.org/project/lated/)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
42
+ [![Tests](https://github.com/lmytime/lated/actions/workflows/ci.yml/badge.svg)](https://github.com/lmytime/lated/actions/workflows/ci.yml)
43
+
44
+ You have JWST (or Roman) photometry of a galaxy, and one of the bands looks
45
+ too bright: an emission line is boosting it. `lated` turns that excess into a
46
+ number. It fits a simple continuum + emission-line model *through the real
47
+ filter curves* and reports the line fluxes, rest-frame equivalent widths and
48
+ line ratios (for example `[O III] 5007 / Hβ`) that the photometry implies.
49
+
50
+ When a line is genuinely there, you get a measurement with uncertainties.
51
+ When it isn't, you get an **honest upper limit**, not a fabricated value. That
52
+ distinction is the whole point of the tool.
53
+
54
+ Use it two ways: a point-and-click **web app** (no coding), or a small
55
+ **Python API** for scripting and batch work.
56
+
57
+ ![The lated web workbench](https://raw.githubusercontent.com/lmytime/lated/main/docs/webapp.png)
58
+
59
+ ## Install
60
+
61
+ ```bash
62
+ pip install lated
63
+ ```
64
+
65
+ That is everything: the Python library, the command line, and the web app.
66
+ Python 3.9+ (depends only on NumPy, SciPy, pydantic and FastAPI).
67
+
68
+ ## The web app
69
+
70
+ ```bash
71
+ lated serve # open http://127.0.0.1:8321
72
+ ```
73
+
74
+ Pick a redshift, tick the bands you have, paste your fluxes, and press run.
75
+ You get a verdict card (measurement or limit), an SED figure and a corner
76
+ plot, all exportable to PDF. Start from one of the built-in literature
77
+ examples to see the whole workflow in a single click. Everything on the board
78
+ is editable: the line list, which lines are free / tied / off, the nebular
79
+ conditions that set the Balmer ratios (Osterbrock & Ferland 2006 Case A/B by
80
+ temperature and density), the continuum slope, dust, and the error budget.
81
+
82
+ ## From Python
83
+
84
+ ```python
85
+ from lated import FitConfig, fit
86
+
87
+ photometry = {"F200W": (0.0136, 0.0019), # {band: (flux, error)} in microJansky
88
+ "F277W": (0.0249, 0.0016),
89
+ "F356W": (0.0040, 0.0014)}
90
+
91
+ res = fit(photometry, FitConfig.three_band(z=3.193))
92
+ print(res.ratios[0].status) # 'upper_limit', 'measured', ...
93
+ ```
94
+
95
+ That is the whole idea. The [example notebook](examples/quickstart.ipynb)
96
+ walks through reading the results, plotting the SED and corner, editing line
97
+ roles, choosing nebular conditions, and the posterior error budget.
98
+
99
+ ## What you get back
100
+
101
+ Every line ratio carries a **status**, so a number is never mistaken for a
102
+ measurement it isn't:
103
+
104
+ | status | meaning | quote |
105
+ |---|---|---|
106
+ | `measured` | both lines detected | the value with 16/50/84 percentiles |
107
+ | `upper_limit` | numerator consistent with zero | `< p97.5` (2σ) |
108
+ | `lower_limit` | denominator consistent with zero | `> p2.5` |
109
+ | `unconstrained` | no band covers the line | nothing usable |
110
+
111
+ Each line also reports the faintest flux your photometry could have detected,
112
+ so every non-detection comes with its depth.
113
+
114
+ ## How it works
115
+
116
+ Per band, the predicted flux is the photon-weighted mean of
117
+
118
+ ```
119
+ f_λ(λ) = C (λ/λ0)^β + Σ_l F_l · δ(λ − λ_l (1+z))
120
+ ```
121
+
122
+ integrated through the real transmission curve and compared to your photometry
123
+ with a Gaussian likelihood; amplitudes are solved by error-weighted
124
+ non-negative least squares over a grid of slopes. Every parameter has an
125
+ explicit role (free, fixed, or tied) that you can change, and invalid setups
126
+ (unknown bands, tie cycles, non-positive errors, under-constrained fits) are
127
+ raised as errors rather than silently ignored.
128
+
129
+ ## Command line
130
+
131
+ ```bash
132
+ lated serve # run the web app
133
+ lated fit input.json # fit from a JSON file
134
+ lated bands # list the bundled filter curves
135
+ lated lines # show the default line registry
136
+ ```
137
+
138
+ The web app also exposes a small REST API (`/api/meta`,
139
+ `/api/filters/{name}`, `/api/fit`) with interactive docs at `/docs`.
140
+
141
+ ## Citing
142
+
143
+ If `lated` contributes to your research, please cite Li et al. (2026, LATED
144
+ Paper I).
145
+
146
+ ## Development
147
+
148
+ ```bash
149
+ git clone https://github.com/lmytime/lated
150
+ cd lated
151
+ pip install -e ".[test]"
152
+ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest tests/ -q
153
+ ```
154
+
155
+ Issues and contributions are welcome at
156
+ [github.com/lmytime/lated](https://github.com/lmytime/lated).
157
+ Released under the [MIT License](LICENSE).
lated-0.1.0/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # LATED
2
+
3
+ **Measure emission lines you can't spectroscopically resolve, straight from photometry.**
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/lated.svg)](https://pypi.org/project/lated/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/lated.svg)](https://pypi.org/project/lated/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+ [![Tests](https://github.com/lmytime/lated/actions/workflows/ci.yml/badge.svg)](https://github.com/lmytime/lated/actions/workflows/ci.yml)
9
+
10
+ You have JWST (or Roman) photometry of a galaxy, and one of the bands looks
11
+ too bright: an emission line is boosting it. `lated` turns that excess into a
12
+ number. It fits a simple continuum + emission-line model *through the real
13
+ filter curves* and reports the line fluxes, rest-frame equivalent widths and
14
+ line ratios (for example `[O III] 5007 / Hβ`) that the photometry implies.
15
+
16
+ When a line is genuinely there, you get a measurement with uncertainties.
17
+ When it isn't, you get an **honest upper limit**, not a fabricated value. That
18
+ distinction is the whole point of the tool.
19
+
20
+ Use it two ways: a point-and-click **web app** (no coding), or a small
21
+ **Python API** for scripting and batch work.
22
+
23
+ ![The lated web workbench](https://raw.githubusercontent.com/lmytime/lated/main/docs/webapp.png)
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install lated
29
+ ```
30
+
31
+ That is everything: the Python library, the command line, and the web app.
32
+ Python 3.9+ (depends only on NumPy, SciPy, pydantic and FastAPI).
33
+
34
+ ## The web app
35
+
36
+ ```bash
37
+ lated serve # open http://127.0.0.1:8321
38
+ ```
39
+
40
+ Pick a redshift, tick the bands you have, paste your fluxes, and press run.
41
+ You get a verdict card (measurement or limit), an SED figure and a corner
42
+ plot, all exportable to PDF. Start from one of the built-in literature
43
+ examples to see the whole workflow in a single click. Everything on the board
44
+ is editable: the line list, which lines are free / tied / off, the nebular
45
+ conditions that set the Balmer ratios (Osterbrock & Ferland 2006 Case A/B by
46
+ temperature and density), the continuum slope, dust, and the error budget.
47
+
48
+ ## From Python
49
+
50
+ ```python
51
+ from lated import FitConfig, fit
52
+
53
+ photometry = {"F200W": (0.0136, 0.0019), # {band: (flux, error)} in microJansky
54
+ "F277W": (0.0249, 0.0016),
55
+ "F356W": (0.0040, 0.0014)}
56
+
57
+ res = fit(photometry, FitConfig.three_band(z=3.193))
58
+ print(res.ratios[0].status) # 'upper_limit', 'measured', ...
59
+ ```
60
+
61
+ That is the whole idea. The [example notebook](examples/quickstart.ipynb)
62
+ walks through reading the results, plotting the SED and corner, editing line
63
+ roles, choosing nebular conditions, and the posterior error budget.
64
+
65
+ ## What you get back
66
+
67
+ Every line ratio carries a **status**, so a number is never mistaken for a
68
+ measurement it isn't:
69
+
70
+ | status | meaning | quote |
71
+ |---|---|---|
72
+ | `measured` | both lines detected | the value with 16/50/84 percentiles |
73
+ | `upper_limit` | numerator consistent with zero | `< p97.5` (2σ) |
74
+ | `lower_limit` | denominator consistent with zero | `> p2.5` |
75
+ | `unconstrained` | no band covers the line | nothing usable |
76
+
77
+ Each line also reports the faintest flux your photometry could have detected,
78
+ so every non-detection comes with its depth.
79
+
80
+ ## How it works
81
+
82
+ Per band, the predicted flux is the photon-weighted mean of
83
+
84
+ ```
85
+ f_λ(λ) = C (λ/λ0)^β + Σ_l F_l · δ(λ − λ_l (1+z))
86
+ ```
87
+
88
+ integrated through the real transmission curve and compared to your photometry
89
+ with a Gaussian likelihood; amplitudes are solved by error-weighted
90
+ non-negative least squares over a grid of slopes. Every parameter has an
91
+ explicit role (free, fixed, or tied) that you can change, and invalid setups
92
+ (unknown bands, tie cycles, non-positive errors, under-constrained fits) are
93
+ raised as errors rather than silently ignored.
94
+
95
+ ## Command line
96
+
97
+ ```bash
98
+ lated serve # run the web app
99
+ lated fit input.json # fit from a JSON file
100
+ lated bands # list the bundled filter curves
101
+ lated lines # show the default line registry
102
+ ```
103
+
104
+ The web app also exposes a small REST API (`/api/meta`,
105
+ `/api/filters/{name}`, `/api/fit`) with interactive docs at `/docs`.
106
+
107
+ ## Citing
108
+
109
+ If `lated` contributes to your research, please cite Li et al. (2026, LATED
110
+ Paper I).
111
+
112
+ ## Development
113
+
114
+ ```bash
115
+ git clone https://github.com/lmytime/lated
116
+ cd lated
117
+ pip install -e ".[test]"
118
+ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest tests/ -q
119
+ ```
120
+
121
+ Issues and contributions are welcome at
122
+ [github.com/lmytime/lated](https://github.com/lmytime/lated).
123
+ Released under the [MIT License](LICENSE).