RSRF
RSRF is a repository-backed Python toolkit and curated data repository for canonical optical sensor spectral response definitions.
It keeps the pieces that usually drift apart in one place:
- a read API for sampled response curves and metadata-only band specs
- a CLI for inspection, validation, and registry operations
- manifest-driven ingest and provenance tracking for official upstream artifacts
- checked-in canonical outputs, QA assets, and documentation visualizations
The distribution name is RSRF. The import package is rsrf.
Documentation: https://marcyin.github.io/spectral_response/
Interactive visualization: https://marcyin.github.io/spectral_response/visualizations/
What Lives In This Repository
- canonical sampled curves under
data/canonical/sampled_curve/ - canonical metadata-only band specs under
data/canonical/band_spec/ - parquet registries under
data/registry/ - raw, extracted, and manifest-tracked source artifacts under
sources/ - Python package code under
src/rsrf/ - MkDocs content and browser visualization assets under
docs/
The current repository includes both multispectral and hyperspectral coverage, including Sentinel-2, Sentinel-3 OLCI and SLSTR, Landsat, MODIS, VIIRS, ASTER, PlanetScope, SkySat, PROBA-V, PRISMA, EMIT, EnMAP, PACE OCI, Pleiades, FORMOSAT-5, Amazonia-1, and CBERS-4A families.
Installation
For repository development:
python3 -m pip install -e ".[dev]"
For a minimal install from a checkout:
python3 -m pip install .
Optional extras are split by workflow:
.[ingest]for HDF5, NetCDF, and xarray-based source parsers.[qa]for validation plots.[docs]for MkDocs site builds.[release]for packaging checks.[lint]for ruff-based code quality checks
The .[dev] extra composes all of the above.
Repository-Backed Data Access
The Python package still ships code separately from the full repository snapshot, but installed-package workflows no longer need a manual checkout. When RSRF is used outside a repository checkout and no explicit root is provided, it downloads the matching GitHub release snapshot into a local cache and reads canonical data from there.
Root resolution now follows this order:
- pass
root=or--root /path/to/custom/root - set
RSRF_ROOT=/path/to/custom/root - run from inside a repository checkout
- fall back to the cached GitHub release snapshot for the installed version
Quick Start
From a repository checkout:
python3 -m rsrf --help
export RSRF_ROOT="$PWD"
rsrf show-layout
rsrf list-sensors
rsrf list-bands sentinel-2c_msi --variant band_average
rsrf show-response sentinel-2c_msi B03 --variant band_average
rsrf show-metadata prisma_hsi --variant metadata_band_spec
rsrf validate-sensor sentinel-2c_msi --variant band_average
From Python:
from pathlib import Path
from rsrf import get_metadata, list_sensors, load_response_definition
root = Path(".")
sensors = list_sensors(root=root)
metadata = get_metadata("sentinel-2c_msi", "band_average", root=root)
response = load_response_definition("sentinel-2c_msi", "B03", "band_average", root=root)
From an installed package outside a checkout, the same calls work without setting root; the first read will populate the local cache from the matching GitHub release.
load_response_definition() returns either a SampledCurve or a BandSpec, depending on the representation variant.
For runtime custom inputs, use coerce_response_definition() with either sampled points (wavelength_nm + response, or wavelength + relative_spectral_response), a band spec (center_wavelength_nm + fwhm_nm), or a zero-argument callable returning one of those forms. Downstream helpers realize center+FWHM inputs as Gaussian curves when they need sampled responses.
For whole-sensor interchange, use get_sensor_definition() for registry sensors and coerce_sensor_definition() or load_sensor_definition() for custom payloads. These APIs normalize canonical and user-supplied sensors into the same versioned SensorDefinition contract with per-band response_definition payloads and namespaced extensions.
Manifest And Registry Workflows
Manifest-aware commands accept either explicit paths or checked-in manifest filenames from the manifest library. From the repository root, these work without the full manifest path:
rsrf validate-manifest rsrf_source_manifest_sentinel2c_v2.json
rsrf show-registry-rows rsrf_source_manifest_prisma_hsi_v2.json
rsrf register-manifest rsrf_source_manifest_prisma_hsi_v2.json
Planning catalog support is exposed separately:
rsrf list-planned-sensors
rsrf register-planned-sensors
Checked-in manifests live under sources/manifests/official/, planning catalogs under sources/manifests/planning/, and templates under sources/manifests/templates/.
Data Model
RSRF currently works with two canonical representation types:
sampled_curve: full spectral response samples stored incurves.parquetband_spec: metadata-only band definitions stored inband_specs.parquet
Each sensor representation also carries a metadata.json sidecar, and sampled-curve variants can include trusted overlay references at:
sources/extracted/<sensor_unit_id>/<representation_variant>/overlay_reference.csv
When only metadata-level band specs are available, RSRF can realize approximate sampled curves for QA and visualization workflows.
Repository Structure
.
|-- data/
| |-- canonical/
| |-- common_grid/
| |-- realized/
| `-- registry/
|-- docs/
|-- plans/
|-- scripts/
| |-- build/
| |-- ingest/
| `-- validate/
|-- sources/
| |-- extracted/
| |-- manifests/
| | |-- official/
| | |-- planning/
| | `-- templates/
| `-- raw/
|-- src/rsrf/
| |-- commands/
| `-- parsers/
`-- tests/
Useful code entry points:
src/rsrf/api.pyfor read-side access to canonical sensor definitionssrc/rsrf/commands/for CLI parser, dispatch, and output helperssrc/rsrf/ingest.pyfor canonical artifact writing and registry updatessrc/rsrf/manifests.pyfor manifest library lookup and path resolutionsrc/rsrf/planning.pyfor registry-first planning catalog supportsrc/rsrf/qa.pyfor validation reports and plot exportsrc/rsrf/registry.pyfor repository layout and parquet registry helperssrc/rsrf/visualization.pyandsrc/rsrf/docs_site.pyfor docs visualization asset export and site preparation
Documentation
Project documentation is built with MkDocs and published at https://marcyin.github.io/spectral_response/.
Key entry points:
- getting started:
docs/getting-started.md - Python API reference:
docs/python-api.md - interactive visualizations:
docs/visualizations.md - CLI reference:
docs/cli.md - data model:
docs/data-model.md - repository layout:
docs/repository-layout.md - development guide:
docs/development.md - release guide:
docs/releasing.md
To refresh the generated docs site files and versioned visualization bundles:
python3 scripts/build/prepare_docs_site.py --root .
This refreshes docs/assets/visualization/, renders docs/visualizations.md from its template, and syncs the versioned JS and CSS bundles referenced by mkdocs.yml.
Development
Run the local verification stack with:
ruff check src/ tests/ scripts/
ruff format --check src/ tests/ scripts/
python3 -m unittest discover -s tests/unit
python3 -m unittest discover -s tests/regression
python3 scripts/build/prepare_docs_site.py --root .
python3 -m build
python3 -m twine check dist/*
mkdocs build --strict
Project Status
Active design and implementation history lives under plans/, including:
Metadata
Release files for RSRF 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rsrf-0.3.1.tar.gz | 103.1 kB | With provenance | Details for rsrf-0.3.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rsrf-0.3.1-py3-none-any.whl | Python 3 | none | any | Details for rsrf-0.3.1-py3-none-any.whl |
Total release size: 185.5 kB
Release files / rsrf-0.3.1.tar.gz
| Download URL | rsrf-0.3.1.tar.gz |
|---|---|
| Size | 103.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37a22a7ef9a262dfcbf2c4e4fd89ffa269638dba07bf34caa78313eeb37d8746
|
|
BLAKE2b-256 checksum How to use checksums |
75cd46164b17791125a59b4a5b2e9a761c3539b778de640c88c188f687f78a6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 6, 2026.
Transparency logRelease files / rsrf-0.3.1-py3-none-any.whl
| Download URL | rsrf-0.3.1-py3-none-any.whl |
|---|---|
| Size | 82.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f391fddd01a03b08c502687331c2f1018689619ab69187eb75f03eb2ce50d6e
|
|
BLAKE2b-256 checksum How to use checksums |
1326d9f025c3a4a437ccd19cc3d93bbbaface94afcabe19ab64cd6b2da014e57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 6, 2026.
Transparency logSecurity for RSRF 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for rsrf-0.3.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.