MyFilter is a web app for interactive visualization of astronomical filter transmission curves.
https://preview.lmytime.com/myfilter
JWST NIRCam customized version:
https://preview.lmytime.com/myfilter?cus=JWST
- Interactive transmission curves for common astronomical filters
- Overlay multiple filters for comparison
- Zoom in on specific wavelength ranges
- Check emission or absorption lines at any redshift
- Narrow-band / broad-band emission-line decomposition (
/emline)
Select filters from the sidebar. Hover the graph for details, and:
| Gesture | Effect |
|---|---|
| Drag | Zoom |
| Shift + drag | Adjust line redshift |
| Alt/Option + drag | Pan the wavelength window |
| Double-click | Zoom out |
Presets are available via the cus query parameter: ?cus=JWST, ?cus=CSST,
?cus=Roman, ?cus=NIJI. The Share button builds a link that restores the
current filter set, redshift, and preset.
The app runs entirely on Cloudflare: a static single-page app plus a small Worker, with filter data in R2. There is no application server.
Browser ──► Cloudflare Worker ──► R2 (filters/v1/…)
│ │
│ ├─ /getfilter CSV of resampled curves
│ ├─ /myfilter/getemlineparam emission-line parameters
│ └─ /api/v1/… instrument index + bundles
└── static assets (SPA) served directly from the edge
Python is a build-time dependency only. It mirrors the SVO catalog and compiles it into per-instrument JSON bundles; it does not run in production.
| Path | Purpose |
|---|---|
src/ |
Vue 3 + TypeScript SPA |
src/lib/ |
Numerics shared between the browser and the Worker |
worker/ |
Cloudflare Worker: API routes and R2 access |
pipeline/ |
Python: SVO mirror → instrument bundles → R2 |
data/custom_filters/ |
User-contributed curves, tracked in git |
tests/fixtures/ |
Golden outputs frozen from the original Python |
/getfilter and the emission-line endpoint were ported from SciPy/pyphot to
TypeScript. To make that safe, the original Python was run over real curves —
including the sparsest (4-point) and densest (15,730-point) in the catalog — and
its outputs frozen as golden fixtures. The port must reproduce them exactly.
Two consequences are worth knowing before you "fix" something that looks wrong:
- The resampling grid step is
(wmax + wmin) / precision— a sum, not a difference.precisionis therefore not a point count. This is preserved deliberately; changing it would alter every CSV the app has ever served. - CSV floats follow Python's
repr, not JavaScript'sString. They differ on integral values, on the scientific-notation threshold, and on exponent padding.src/lib/pyfloat.tsreproduces Python's rules and is validated against 11,689 real tokens.
Requires Node 20+ and Python 3.9+.
npm install
npm run devTests — the pure numerics run in Node, the Worker routes run in the real Workers runtime with a simulated R2 binding:
npm testThe SVO mirror (~11,000 curves, 114 MB) is not tracked in git; it is
reproducible. Custom curves in data/custom_filters/ are tracked — see
PROVENANCE.md.
npm run sync:svo # refresh the local SVO mirror (incremental)
npm run data:build # compile curves into dist-data/filters/v1/
npm run data:publish # upload changed objects to R2Code and data deploy separately.
- Code — Cloudflare Workers Builds deploys on every push to
main. The build command isnpm run ci:verify, so a type error or a failing test aborts the deploy rather than shipping it. - Data — a manual GitHub Actions workflow (Publish filter data to R2) syncs SVO, validates, builds bundles, and uploads the changed ones.
See docs/deployment.md for one-time setup: creating the R2 bucket, the three GitHub secrets, and the Workers Builds dashboard settings.
To deploy by hand instead:
npm ci && npm run deploy- Most curves come from the SVO Filter Profile Service.
JWST_*— JWST ETC v2.0.CTIO-Merian— filters designed for the Merian Survey.Subaru-MOIRCS— Subaru MOIRCS.CSST-MS,CSST-MCI25— CSST instrument teams.
Contributions are welcome — please open an issue or a pull request. To add a filter, see PROVENANCE.md.
MIT.
If you publish work that uses MyFilter, please cite it via the Zenodo DOI:
In bibtex:
@misc{MyFilter,
author = {Li, Mingyu},
title = {{MyFilter: A Web Application for Interactive Visualization of Astronomical Filter Transmission Curves}},
month = nov,
year = 2023,
publisher = {Zenodo},
version = {1.0.0},
doi = {10.5281/zenodo.10210201},
url = {https://doi.org/10.5281/zenodo.10210201}
}Optionally, attach the GitHub repo link in a footnote:
\footnote{\url{https://github.com/lmytime/MyFilter}}