Algorithm Theoretical Basis Document (ATBD)#
Issued. This ATBD defines the algorithm basis by which
s2_msi_raw_generatorruns an Sentinel-2B L1B backwards through the exact inverse of the operational L0→L1B radiometric chain (invert offset, relative-response/PRNU G⁻¹, on-board equalization, dark, un-bin, SWIR re-stage, defective, crosstalk) to reconstruct L1A → L0plus (CCSDS-122 ISP) → Synthetic L0. MTF-deconvolution is OFF, so PSF and noise are NOT re-applied. Success is the reconstructed L0 measured against the reference ESA L0img(10/20 m bands ≤~4 DN). Operational numerical values are populated: per-band gains/TDI/timing from products, the SRF spectral characterisation, and the operational S2A GIPP (per-pixel dark + relative response), with CCSDS-122 lossless codec for the L0plus. The calibration sub-set derives the coefficients from CSM-diffuser + dark acquisitions to build a cal-DB (inverse-crime cure). Implemented from the public L1 ATBD + GIPP data only.
1. INTRODUCTION#
1.1 Project description#
s2_msi_raw_generator (a reverse reconstructor) inverts the operational L0→L1B radiometric
chain of the msi-processor (a generic high-resolution push-broom MSI processor, EOPF CPM 2.8.1,
L0c→L2A, 8 units, CI-green). Where the processor applies the corrections that carry L0 up to L1B
(radiometric calibration, PSF deconvolution, co-registration, orthorectification, atmospheric
correction), this tool runs the exact inverse of each radiometric correction: it takes a
Sentinel-2 L1B product (already in per-detector sensor geometry) and reconstructs its
L1A → L0plus → Synthetic L0 products (focal-plane digital numbers, 12 staggered detectors × 13 bands).
Because L1B is already sensor-geometry, the chain is radiometric-only — there is no geometry
inversion (orthorectification undo) to perform (Issue #17). An L1C entry + geometry-reverse module was
considered and cancelled: with an L1B entry there is nothing to de-orthorectify.
The reconstruction is validated end-to-end against ground truth: the Synthetic L0 DN is
compared with the reference ESA L0 img (10/20 m bands ≤~4 DN). As a supporting check, the L0plus
CCSDS-122 codec round-trip is bit-exact — decode(L0plus) == L1A. Implemented from the public
L1 ATBD + operational GIPP data only — no external processor.
1.2 Purpose of document#
Present the L1B→L1A→L0plus→Synthetic L0 reverse-reconstruction data flow and the physical/mathematical
treatment at each stage — reconstructing the L1A/L0plus/Synthetic L0 products by inverting each operational
forward correction, with explicit traceability to the msi-processor forward function each reverse
step conjugates.
1.3 Scope#
Algorithm-theoretical basis only; software design, ICD, and V&V plan are separate DRDs. Reverse entry level is L1A/L1B at-sensor radiance (Issue #17); the L1C-entry
geometry-reverse module is cancelled (not applicable to an L1A/L1B entry).
1.4 References#
1.4.1 Applicable documents#
AD 1 |
|
AD 2 |
|
AD 3 |
|
AD 4 |
ECSS-E-ST-40C; ECSS-E-ST-10-02C (Verification) |
1.4.2 Reference documents#
RD 2 |
ESA Sentinel-2 Spectral Response Functions (S2-SRF), doc COPE-GSEG-EOPG-TN-15-0007 v4.0 (2024) |
RD 3 |
SentiWiki Sentinel-2 MSI — instrument/mission parameters |
RD 4 |
PyRawS — Sentinel-2 raw (L0-like) granule structure & per-detector layout |
RD 5 |
S2 datastrip metadata — |
RD 6 |
Sentinel-2 Products Specification Document (PSD) — L1C/Synthetic L0 format |
1.5 Glossary#
1.5.1 Acronyms#
ADF (Auxiliary Data File), BOA (Bottom Of Atmosphere), DN (Digital Number), DSNU (Dark Signal
Non-Uniformity), E2ES (End-to-End performance Simulator), ESUN (mean exo-atmospheric solar
irradiance), GSD (Ground Sampling Distance), MSI (MultiSpectral Instrument), MTF (Modulation
Transfer Function), NUC (Non-Uniformity Correction), PRNU (Photo-Response Non-Uniformity),
PSF (Point Spread Function), RT (Radiative Transfer), SRF (Spectral Response Function),
TOA (Top Of Atmosphere), TDI (Time-Delay Integration), CSM (Calibration & Shutter
Mechanism), GRI (Global Reference Image), SSO (Sun-Synchronous Orbit), MGRS (Military Grid
Reference System). [extend as needed]
1.5.2 Definitions#
Reverse step (R#): an operation that inverts one
msi-processorforward correction.Conjugate: the processor forward function a reverse step inverts.
Invert (exact inverse): apply the analytic inverse of the operational forward correction to reconstruct the down-level (L1A/L0plus/Synthetic L0) product from the level above.
1.5.3 Definition of quantities#
Symbol |
Name |
Units |
|---|---|---|
L |
at-sensor band radiance (L1B input) |
W·m⁻²·sr⁻¹·µm⁻¹ |
DN |
digital number (Synthetic L0 RAW output) |
none, [0, 2¹²−1] |
g_phys |
per-band physical gain (DN↔radiance, value Annex A.11) |
— |
g_nuc, o_nuc, k_dark |
per-detector PRNU gain/offset, dark offset |
— |
PSF_b |
per-band point spread function kernel (DC=1) |
none |
ρ_TOA |
TOA reflectance (cancelled L1C-entry module — unused) |
none, [0,1] |
ESUN_b, θ_s, d |
solar irradiance (from SRF), solar zenith, Earth–Sun dist (cancelled L1C-entry module — unused) |
mixed |
1.5.4 Note on coordinates#
Three coordinate sets: detector (focal-plane pixel, the Synthetic L0 RAW frame),
image/granule (native acquisition grid), map (UTM/WGS-84, MGRS-tiled — cancelled L1C-entry module).
The v1 reverse operates entirely in detector geometry (input L1A/L1B is already there). Detector
array: 2592 px across-track
per module @ 10 m, 1296 px @ 20 m, ≈432 px @ 60 m; 12 staggered modules per focal plane,
odd/even two-row stagger (Annex A.5). [TBD: exact per-band sub-window origins / stagger offsets — from ASGARD/GRI or PyRawS].
2. OVERVIEW#
The Sentinel-2 MSI is a solar-reflective push-broom instrument: 13 spectral bands
(B01 443 nm → B12 2202 nm; no panchromatic band), GSDs of 10/20/60 m, two focal planes
(VNIR Si-CMOS + SWIR MCT) each with 12 staggered detector modules across a 20.6° FOV,
on-board sun-diffuser (CSM) radiometric calibration, 12-bit quantization (DN 0–4095).
TDI: the product tdi_configuration_list shows TDI APPLIED on B03, B04, B11, B12 (2 VNIR +
2 SWIR); model as a per-band config. Full sourced values in Annex A.
Reverse-reconstruction data-flow — S2 L1B → L1A → L0plus → Synthetic L0, radiometric-only:
flowchart TD
IN["S2B L1B<br/>(downlink DN, per-detector geometry)"]
A["+ offset (R2PARA)"]
B["G⁻¹ invert relative response / PRNU (R2EQOG)"]
C["invert on-board equalization non-linearity (REOB2)"]
D["+ L0 dark pedestal (L0_DARK_LSB × COEFF_D shape)"]
E["×3 un-bin 60 m (B01/B09/B10)"]
F["SWIR re-stage (RSWIR)"]
G["re-stamp defective / re-insert blind (R2DEPI / BLINDP)"]
H["+ crosstalk (RCRCO)"]
QZ["quantize → uint16 (12-bit)"]
L1A["L1A (reconstructed)"]
ISP["CCSDS-122 lossless + ISP packetize"]
L0P["L0plus (CCSDS ISP; decode == L1A, bit-exact)"]
L0["L0 (156 frames + telemetry + STAC)"]
OFF["MTF-deconvolution OFF ⇒ PSF & noise NOT re-applied"]
IN --> A --> B --> C --> D --> E --> F --> G --> H --> QZ --> L1A --> ISP --> Synthetic L0P --> Synthetic L0
OFF -.-> B
No geometry inversion (L1B already sensor geometry).
3. DATA PRODUCTS#
Role |
Short name |
Description |
|---|---|---|
Input |
S2 L1A/L1B |
At-sensor radiance (L1B float32; L1A rawer), per-detector geometry ( |
Output |
Synthetic L0 RAW |
Focal-plane uint16 DN per detector, 12 detectors × 13 bands, native geometry, quality annotations, STAC metadata. |
Output container (EOPF L0 Zarr = the normative ICD-IF-L0; Annex A.9): measurements/d{DD}/b{BB}/band{BB}
uint16 DN (156 arrays); conditions/anc_data/s{APID}/isp (CCSDS ISP/SAD telemetry); quality/d{DD}/b{BB}/mask
uint8; root STAC + sensor config (tdi_configuration_list, spectral_band_info incl. physical_gains,
line_period, nuc_table_id, active_detectors_list).
4. REVERSE PROCESSING FLOW#
The processor’s operational L0→L1B forward chain, inverted. Two sub-flows:
Main reverse-reconstruction chain (reverse_l1b_to_l0, §5.R): the S2 L1B is run backwards
through the inverse of the full operational L0→L1B radiometric chain, in reverse order —
+offset → G⁻¹ relative-response → invert on-board-eq → +dark → un-bin(60 m) → SWIR re-stage → defective/blind → crosstalk → quantize → CCSDS-122 + ISP → Synthetic L0 — reconstructing L1A → L0plus → Synthetic L0.
MTF-deconvolution is OFF, so PSF re-blur and noise are NOT re-applied. The step-level physics is
detailed in §5; §5.R is the authoritative S2 L1B flow.
Calibration sub-set (s2_msi_raw_generator/calibration.py): the S2 two-reference radiometric
calibration in the reflective domain, which derives the cal-DB. The high-signal reference is the
on-board CSM sun-diffuser (uniform full-field), the zero reference is a dark (CSM closed /
night). The sub-set synthesises both L0 acquisitions from the true ADF, then derives the
coefficients back (L1 ATBD §4.1.1.2.2):
\(D(j) = \langle X_\mathrm{dark} \rangle_i\), \(g(j) = A \cdot \langle L_\mathrm{diff} \rangle / \langle X_\mathrm{diff} - D \rangle_i\) with \(\langle g(j) \rangle_j = 1\) → fixes A. The processor then
uses the derived coefficients (estimated_adf), not the truth used to build the references —
closing the loop breaks inverse crime (verified: derived dark recovers truth to <0.05 DN,
relative response correlation >0.99, A≈cal_gain; the small residual is the calibration
uncertainty). ADF_REQOG.
5. PROCESSING-BLOCK DESCRIPTIONS (the operational corrections being inverted)#
Each block below states one operational L0→L1B forward correction, its ADF, and the msi-processor
conjugate. The reverse reconstructor applies the analytic inverse of each. The authoritative
S2 L1B flow — how these inverses are actually composed on a S2B L1B — is §5.R; the entry is
the downlink DN domain (a S2 L1B is already digital counts), not synthetic radiance. Real
per-band values in Annex A.6/A.11.
5.S1 Radiometric gain/offset (the DN-domain equation inverted)#
Model. The official L1 ATBD raw equation (S2-PDGS-MPC-ATBD-L1 §4.1.1) is
whose terms the reverse chain inverts in the DN domain:
the absolute-calibration term \(A\) (
Band.cal_gain);the relative sensitivity \(G\) (S7, inverted as \(G^{-1}\));
the dark signal \(D\) (S11).
Domain note. A S2 L1B is already digital counts, so the reverse chain does not perform a synthetic
radiance→DN entry; it enters in the downlink DN domain and inverts the operational gain/offset directly
(see §5.R). The product’s physical_gains (Annex A.11) are carried for metadata; the DN-domain
inversion of offset and relative response is applied per §5.S4/§5.S7.
ADF: ADF_RABCA. Conjugate: toa.dn_to_radiance (\(L = \mathrm{DN}/A\)).
5.S3 Undo framing & round/clamp#
Forward. Extend to a continuous detector strip; restore sub-pixel precision.
ADF: ADF_PRDLO, ADF_RPARA. Conjugate: l0_decode framing.
5.S4 Undo radiometric offset#
Forward. DN −= offset, with radio_add_offset = −100 (L1B; −1000 for L1C, PB04.00).
ADF: ADF_RPARA. Conjugate: —
5.S5 Undo 60 m binning (B01/B09/B10)#
Forward. De-bin to detector level (the 20 m → 60 m forward bin, reversed).
ADF: ADF_RBINN. Conjugate: georeference.resample_to_grid.
5.S7 Invert relative response (G⁻¹)#
Reverse. Invert the on-ground equalization \(Y = G(Z)\) — VNIR cubic \(A\,Z^3 + B\,Z^2 + C\,Z\) /
SWIR bilinear (knee at Zs) — applying the analytic inverse \(G^{-1}\) per pixel to reconstruct the
un-equalized DN.
Real values. The per-pixel gains come straight from the operational S2A GIPP R2EQOG
(COEFF_A/B/C cubic / COEFF_A1/A2/Zs bilinear; \(C \approx 1.0\)–\(1.2\) dominant), parsed by
s2_msi_raw_generator.gipp and applied via the analytic inverse \(G^{-1}\) in
forward_radiometric_atbd.inverse_equalize (BandADF.from_gipp).
ADF: ADF_REQOG. Conjugate: radiometric.apply_nuc.
5.S8 Re-insert SWIR arrangement (B10/B11/B12)#
Forward. Restore the staggered SWIR readout layout (the TDI “rearrangement”); TDI is APPLIED on
B03, B04, B11, B12 (tdi_configuration_list).
Method. PyRawS shift_lut.csv deterministic per-(satellite, detector, band-pair) shifts (Annex A.9).
ADF: ADF_RSWIR.
5.S9 Re-apply crosstalk#
Forward. Inject optical + electrical channel crosstalk,
of magnitude <0.5 % channel-to-channel. The matrix is the GIPP R2CRCO (per-band
OPTICAL+ELECTRICAL row; ≈0 for S2A → identity).
ADF: ADF_RCRCO. Conjugate: none (S2-specific; a named residual).
5.S10 Re-insert blind/defective pixels#
Forward. Insert masked blind columns and inject defective pixels (3 in B11, 1 in B12, per S2C Cal/Val).
ADF: ADF_BLIND (blind), ADF_RDEPI (defective). Conjugate: radiometric.replace_bad_pixels.
5.S11 Reconstruct the dark pedestal#
Reverse. DN += dark[pixel] — reconstruct the L0 dark pedestal that the operational chain
subtracted (see the §5.R downlink-dark domain note).
Real values. The per-pixel dark signal \(D(j)\) comes from the operational S2A GIPP
R2EQOG COEFF_D (s2_msi_raw_generator.gipp, BandADF.from_gipp) — mean 440–522 LSB per band,
matching the DQR (OMPC.CS.DQR.01.02-2023) range but now resolved per pixel. Fallback when no GIPP:
DARK_PEDESTAL_LSB 440–520 + per-pixel DSNU \(< 0.5/1.0\) LSB (Band.dark_dsnu).
ADF: ADF_REOB2 / ADF_REQOG.
5.S12 Re-apply onboard equalization#
Forward. Invert the R2EQOG equalization — multiplicative (cubic VNIR \(Z = \sum_n G_n \cdot Y^n\) /
bilinear SWIR) on the dark-subtracted signal (Clerc et al. 2026, S2C cal/val; equalization_mode = true,
nuc_table_id = 3). Linearized here as \(\mathrm{DN}_\mathrm{raw} = \mathrm{DN}_\mathrm{eq}/\mathrm{gain}_\mathrm{ob}\),
with the per-detector gain stability 0.05 % 1σ (paper Table 3, Ra factor; sensor.EQ_GAIN_STD) and
no offset (the dark is the S11 pedestal).
ADF: ADF_REOB2. Conjugate: radiometric.estimate_nuc.
5.S14 Quantize#
Forward. clip(round(DN), 0, 4095) → uint16 (12-bit at sensor); no-data 0, saturated 65535.
ADF: ADF_CONVE. Conjugate: radiometric.flag_saturation.
5.S15 Generate ISP packets & telemetry#
Forward. Two sub-steps mirroring the onboard chain:
Onboard image compression — the Sentinel-2 compresses MSI video data onboard with the proprietary MRCPB wavelet scheme (bit-plane coding, per-band tuned rates ≈ 2.4–2.97, CoReCi ASIC); a CCSDS-compression ASIC is the documented alternative. This generator implements that alternative: CCSDS 122.0-B, lossless profile (
s2_msi_raw_generator/ccsds122.py) — 3-level integer DWT 9/7-M (§3.3 lifting withfloor(·+1/2)rounding, whole-sample symmetric extension), 8×8 block/family structure and 16-block gaggles (§4.1), self-describing segment headers carrying the Part-1A/3/4 content (§4.2), DC and per-blockBitDepthACDPCM + per-gaggle Rice coding (§4.3/§4.4). Documented divergence: the §4.5 AC stages keep their semantics and scan order but the per-stage bits are packed raw instead of §4.5.3 word-mapped VLCs — bit-exact lossless, structurally 122-shaped, not interoperable with reference decoders (the matching decoder ships in the module). Segments default to one block row = 8 image lines, giving line-accurate packet datation.Packetization — the compressed stream is carried in CCSDS space packets; per-line timestamps from
line_period = 1.5658736 ms; SAD packets per APID.
Note the level split of the S2 L1B chain: L0plus stores the compressed, annotated ISPs; the ground
L1A step decompresses (SentiWiki S2 Products). Choosing the lossless profile (operational MRCPB is
lossy) keeps the L0plus codec round-trip bit-exact — decode(L0plus) == L1A — a supporting check
on the reconstruction (distinct from the end-to-end Synthetic L0 vs reference ESA L0 validation, §5.R). The L0plus
achieves a lossless compression ratio of ~3.66× with bit-exact ground decode.
Output. The 156-frame L0 (Annex A.9).
ADF: ADF_SADMP, ADF_DATAT. Conjugate: ground decompression + l0_decode.
Calibration sub-set (inverse-crime cure — implemented s2_msi_raw_generator/calibration.py): synthetic
CSM sun-diffuser + dark acquisitions → derive D, g, A (L1 ATBD §4.1.1.2.2) → estimated ADF
(estimated_adf, the cal-DB) handed to the processor, not the truth used to build the references.
Cancelled L1C-entry module (Issue #17): an L1C entry would have required prepending
de-orthorectification (ground→detector via the S2 viewing model — ASGARD,
ADF_VDIRP/SPAMO/GPARA/RESAM/TILEP/DEM) + reflectance→radiance. This module is dropped: the
adopted L1A/L1B entry is already in native detector geometry, so there is nothing to de-orthorectify.
(L1C orthorectification destroys the native detector alignment the radiometric reverse relies on —
the very reason an L1C entry was rejected; PRNU paper.)
5.R REAL L1B → L1A → L0plus → Synthetic L0 FULL REVERSE — AUTHORITATIVE FLOW (reverse_l1b_to_l0)#
This is the central reverse-reconstruction flow; §5.S1–S14 give the per-step physics it composes.
A S2B EOPF L1B is already digital counts, so the reverse enters in the downlink DN domain
and inverts the full operational L0→L1B radiometric chain (EOPF AllRadiometricCorrectionL1B — every
feature_flag_* = True except deconvolution/denoising) in reverse order to reconstruct
L1A → L0plus → Synthetic L0:
+offset (R2PARA) → G⁻¹ relative response (R2EQOG) → on-board-eq non-linearity (REOB2) → +L0 dark (L0_DARK_LSB × R2EQOG COEFF_D shape) → ×3 un-bin (60 m) → SWIR re-arrangement (RSWIR) → re-stamp defective (R2DEPI). Crosstalk (RCRCO) is added back phase-level across same-resolution bands; blind
columns are re-inserted from BLINDP; CCSDS-122 + ISP then package the L0 (S15).
MTF restoration / deconvolution (forward step 8) is deliberately skipped — it is off in the
operational chain (feature_flag_with_deconvolution = False, ADF_RPARA restoration; SentiWiki:
“restoration disabled by default — instrument MTF already high”). L1B therefore still carries the full
instrument PSF, so S6 PSF re-blur and S13 noise are NOT re-applied — they would double-count and are
non-invertible anyway (deconvolution is lossy; the exact noise realization is unrecoverable).
Domain note. The added dark is the downlink L0 dark (L0_DARK_LSB ≈ 51), not the raw-detector
COEFF_D (≈ 440): REOB2 has near-unity slope (S2B a1 ≈ 1.005, a2 ≈ 0.995) and its dark d ≈ 455
cancels COEFF_D, so REOB2 contributes only its a1/a2 non-linearity in the downlink domain.
ADF sources (EOPF json, auto-found next to ADF_REQOG): ADF_RSWIR
(swir_band_list/swir_band/detector per-column ±1 shift + B10 3-tap kernel), ADF_REOB2
(new_table/coeff_{a1,a2,zs,d}), ADF_RCRCO (13×13 optical+electrical). Parsers: gipp.read_rswir_eopf
/ read_reob2_eopf / read_rcrco_eopf; ops: forward_radiometric_atbd.restage_swir_lines /
reapply_onboard_eq.
Validation (2024-04-08 S2B PPB, d05, CCSDS round-trip): the Synthetic L0 vs the
reference ESA L0 img RMSE ≤ 3 DN on all 13 bands (B11/B12 fixed by S8 from ~50 → ~3 DN;
success criterion ≤~4 DN on the 10/20 m bands), framing-aligned via ADF_PRDLO
with zero line-drift — see the S2 L1B-E2E run report and the
DPM parameter/data list.
6. SENSOR-MODEL ADF v0 (the conjugate bridge)#
Jointly change-controlled with the processor (per AD 1). Conjugate subset (both halves read):
spectral: per-band S2 SRF samples (central λ Annex A.1); ESUN_b derived from the same SRF, matched to the product’s satellite (S2A/B/C; Risk 2) — per-unit centre/bandwidth/equivalent wavelength from the SRF doc are insensor.py.radiometric: per-band gain —physical_gainsfrom the product metadata (Annex A.11, no credentialed ADF needed);radio_add_offset = −100(L1B). Source ADF:ADF_RABCA.nuc/dark/badpixel: per-detector PRNU (1D per-detector model; residuals from Zenodorecords/18433006), DSNU + dark (ADF_REOB2, nighttime-ocean), defect/blind (ADF_BLIND/ADF_RDEPI, 3×B11 + 1×B12), crosstalkADF_RCRCO(<0.5 %).nuc_table_id = 3, equalization on.psf: per-band, per-unit kernel (DC=1) — the official ESA PSF matrices (SentiWikiS2{A,B,C}_PSF, Annex A.4), integrated from the 33×33 oversampled matrix to the detector grid.viewing_model: focal length 600 mm / F4 (TMA, 150 mm pupil), pixel pitch 7.5/15 µm, 12-detector stagger, per-band GSD (Annex A.2),line_period1.5658736 ms. (Was only needed by the cancelled L1C-entry module.)
E2ES-only block (processor never reads): noise model (a,b for \(\sigma=\sqrt{a+b\cdot\mathrm{DN}}\), ADF_RNOMO),
crosstalk kernel, temporal gain drift (VNIR 0.1–0.35 %/months, SWIR faster).
ADF access — all now. Every radiometric ADF the chain needs is ESA-sourced: gain/TDI/timing/offset
from the products; PSF = the official ESA matrices (SentiWiki); spectral = the SRF
(COPE-GSEG-EOPG-TN-15-0007); noise = the per-band α, β from the L1A product
(quality_indicators_info/.../noise_model), \(\sigma=\sqrt{\alpha^2+\beta\cdot\mathrm{DN}}\) (S2-RUT, reproduces SNR@Lref). The
previously-modelled per-pixel PRNU + dark are now the operational S2A GIPP: R2EQOG
carries, per detector and per across-track pixel, the dark signal COEFF_D (≈440–522 LSB, matching
the DQR) and the relative-response gains (VNIR cubic A/B/C, SWIR bilinear A1/A2/Zs); R2DEPI the
defective/blind columns; R2PARA the −100/−1000 offsets; R2CRCO≈0. These GIPP data files are
parsed by s2_msi_raw_generator.gipp (an original reader) into per-pixel arrays (BandADF.from_gipp).
7. ERROR ANALYSIS#
Per-stage error-budget table, reflective-domain terms. Populate numerically via sensitivity sweeps.
Step |
Dominant error term |
Driver |
Budget |
|---|---|---|---|
S1/S4 |
gain / offset inversion residual |
radiometric |
abs. <5 % (goal 3 %); per-unit SRF up to ~15 % if mismatched |
S7/S12 |
relative-response G⁻¹ + on-board-eq inversion residual |
radiometric |
inter-band rel. 3 %; linearity 1 % |
S5 |
un-bin (60 m) reconstruction residual |
resample |
sub-DN on uniform fields |
S8 |
SWIR re-stage mis-alignment |
detector |
B11/B12 dominant (fixed ~50 → ~3 DN) |
S9 |
crosstalk residual (no processor inverse) |
detector |
<0.5 % channel-to-channel |
S14 |
quantization |
12-bit (0–4095) |
≈ Lref/SNR LSB |
end-to-end |
Synthetic L0 vs reference ESA L0 |
composite |
≤~4 DN (10/20 m bands); multi-temporal rel. ≤1 % |
Method note: re-derive the dominant terms for the reflective domain. The end-to-end claim is
absolute verification against ground truth — the Synthetic L0 DN measured directly against the
reference ESA L0 img, not a self-consistency round-trip.
8. OPEN POINTS#
Reverse entry level — RESOLVED: L1B (Issue #17); the L1C-entry + geometry-reverse module is cancelled.
L0 ICD: adopt the EOPF L0 Zarr structure (Annex A.9) as ICD-IF-Synthetic L0.
SRF: DONE — per-unit band centre/bandwidth/equivalent wavelength from the official SRF doc (COPE-GSEG-EOPG-TN-15-0007) are in
sensor.py.PRNU/dark per-pixel GIPP — RESOLVED (supersedes the early “credentialed GIPP” blocker #36): the operational
S2A_OPER_GIP_R2EQOG(per-pixel darkCOEFF_D+ relative response) is read directly bygipp.py/BandADF.from_gippand is publicly fetchable (bucketGIP_*TGZs are anonymous-GET; verified 2026-07-02). The reverse reconstruction runs on it and validates against the reference ESA L0imgat RMSE ≤~4 DN (10/20 m bands; see §5.R). Still open in the narrow sense: a dark-calibration granule (night-over-ocean) is not in this dataset — per-pixel dark therefore comes from the GIPP, not from a dark acquisition. L1B-derived PRNU remains available via the pipeline’sderive-adfphase.
Annex A — Sentinel-2 MSI parameter data list (sourced)#
Externally sourced, verified values. Primary sources: SentiWiki (Copernicus)
sentiwiki.copernicus.eu, ESA SP-1322/2, S2 L1 ATBD, eoPortal, S2 User Handbook;
cross-checked vs the official S2-SRF table (COPE-GSEG-EOPG-TN-15-0007). See A.8 for provenance and
unverified/derived flags. Values to be migrated into the sensor-model ADF v0 (§6).
A.1 Spectral bands — central wavelength & bandwidth (FWHM), S2A / S2B#
(Central λ cross-verified to ~0.3 nm; bandwidths are S2-SRF-version-sensitive — cite a version.)
Band |
S2A λ (nm) |
S2A BW (nm) |
S2B λ (nm) |
S2B BW (nm) |
GSD |
|---|---|---|---|---|---|
B01 |
442.7 |
21 |
442.2 |
21 |
60 m |
B02 |
492.4 |
66 |
492.1 |
66 |
10 m |
B03 |
559.8 |
36 |
558.9 |
36 |
10 m |
B04 |
664.6 |
31 |
664.9 |
31 |
10 m |
B05 |
704.1 |
15 |
703.8 |
16 |
20 m |
B06 |
740.5 |
15 |
739.1 |
15 |
20 m |
B07 |
782.8 |
20 |
779.7 |
20 |
20 m |
B08 |
832.8 |
106 |
832.9 |
106 |
10 m |
B8A |
864.7 |
21 |
864.0 |
22 |
20 m |
B09 |
945.1 |
20 |
943.2 |
21 |
60 m |
B10 |
1373.5 |
31 |
1376.9 |
30 |
60 m |
B11 |
1613.7 |
91 |
1610.4 |
94 |
20 m |
B12 |
2202.4 |
175 |
2185.7 |
185 |
20 m |
No panchromatic band. B08 bandwidth has the largest cross-source divergence (106 vs 115/118 nm).
A.2 GSD per band#
10 m: B02, B03, B04, B08
20 m: B05, B06, B07, B8A, B11, B12
60 m: B01, B09, B10
A.3 ESUN — extraterrestrial solar irradiance (W·m⁻²·µm⁻¹), Thuillier 2003#
(= the SOLAR_IRRADIANCE stored per band in L1C metadata; S2A ≠ S2B because of distinct SRFs.)
Band |
ESUN S2A |
ESUN S2B |
Band |
ESUN S2A |
ESUN S2B |
|---|---|---|---|---|---|
B01 |
1884.69 |
1874.30 |
B08 |
1041.63 |
1041.28 |
B02 |
1959.66 |
1959.75 |
B8A |
955.32 |
953.93 |
B03 |
1823.24 |
1824.93 |
B09 |
812.92 |
817.58 |
B04 |
1512.06 |
1512.79 |
B10 |
367.15 |
365.41 |
B05 |
1424.64 |
1425.78 |
B11 |
245.59 |
247.08 |
B06 |
1287.61 |
1291.13 |
B12 |
85.25 |
87.75 |
B07 |
1162.08 |
1175.57 |
A.4 Optics#
Telescope: Three-Mirror Anastigmat (TMA), off-axis, SiC mirrors + structure. Mirror sizes M1 442×190, M2 147×118, M3 556×291 mm. Optics identical on S2A/S2B.
Entrance pupil / aperture: 150 mm. Focal length: 600 mm (0.60 m) — now confirmed (Languille 2015 “focal length is 0.60 m”), F-number F/4. FOV 20.6° across-track (→ 290 km swath @ 786 km); IFOV ≈ 21° × 3.5°.
Distortion: line-of-sight of edge detector (#12) reaches 2.8° tilt vs a distortion-free telescope; distortion pattern varies with across-track position.
MTF at Nyquist (combined system spec — telescope + detector + smear): 10 m & 20 m → >0.15 and <0.30; 60 m → <0.45. (Phrasing discrepancy: SentiWiki/eoPortal place the 20 m bands in the <0.45 bracket; the 10/20 m → 0.15–0.30 framing matches Drusch 2012.)
Official PSF matrices ARE published (SentiWiki
S2{A,B,C}_PSF.zip, packaged ins2_msi_raw_generator/data/psf/): per-band, per-unit 33×33 matrices, oversampling 5, centre at (17, 17), normalised (\(\Sigma = 1\)), for L1B focal-plane geometry (after binning). Computed from measured Nyquist MTF (along-track + across-track), Gaussian-modelled — S2A/S2C from 2024, S2B from 2023 — for all bands except B10 (water-vapour, does not see the ground). Kept as reference data (s2_msi_raw_generator/data/psf/) for sensor characterisation; because MTF-deconvolution is OFF in the operational chain, the reverse reconstruction does not re-apply the PSF (no re-blur step — see §5.R).
A.5 Detector / focal plane#
Two focal planes (dichroic split): VNIR = monolithic Si CMOS (0.35 µm) @ ~293 K, 10 bands; SWIR = MCT/HgCdTe hybridised on CMOS ROIC @ 195 ± 0.2 K, 3 bands (B10, B11, B12). Per-band separation by stripe filters.
12 detector modules per focal plane, two staggered rows across the 20.6° FOV.
Pixel pitch: VNIR 7.5 µm (10 m bands) / 15 µm (20 m bands); SWIR 15 µm. Total across-track px: 31,152 @ 10 m, 15,576 @ 20 m.
Per-detector RAW image shape [along-track × across-track] (PyRawS
BANDS_RAW_SHAPE_DICT): 10 m bands B02/B03/B04/B08 = 2304 × 2592; 20 m bands B05/B06/B07/B8A = 1152 × 1296; 60 m bands B01/B09 = 384 × 1296; SWIR B11/B12 (20 m) = 1152 × 1296; B10 (60 m) = 384 × 1296.Inter-detector across-track overlap ≈ 2 km (120–200 px for 10 m bands).
Cross-detector parallax (odd/even, same band): 0.022°–0.059° → sub-km baseline, near-simultaneous views. (The earlier “~46 km inter-detector” figure was ERRONEOUS — corrected.) Cross-band parallax within a detector: B2–B9 = 0.018° (VNIR max), B10–B12 = 0.010° (SWIR max).
Band-to-band along-track time delay: ~20 ms (B6–B11, min) to 2.6 s (B2–B9, max); detector along-track footprint ≈ 34 km; ground velocity ≈ 6700 m/s; delay knowledge < 0.15 ms.
TDI — UNCERTAIN/conflicting in public sources: the Martimort 2007 / eoPortal spec table lists a ~2-line TDI stage for BOTH VNIR and SWIR (SWIR adds 2 lines for pixel deselection); one search result (SP-1322/2) cited per-band SWIR B10=3, B11/B12=4 lines — unresolved. Treat the TDI line count as a configurable per-focal-plane ADF parameter (default: 2-line stage; SWIR per-band counts
[TBD]). TDI drives the yaw-steering requirement (ground velocity ⊥ arrays). S2 “SWIR rearrangement” (msi-processorADF_RSWIR) realigns SWIR columns for this readout.
A.6 Radiometry#
Quantization: 12-bit at acquisition (DN 0–4095), stored 16-bit unsigned. On-board wavelet compression (~450 Mbit/s); RAW = decompressed L0 + metadata.
Absolute radiometric uncertainty < 5 % (goal 3 %); inter-band relative 3 %; multi-temporal relative 1 %; linearity 1 % (residual after γ-correction ~0.4 %); channel-to-channel cross-talk < 0.5 %; diffuser non-uniformity 1 %; stray-light bias 0.3 % (VNIR) / 0.15 % (SWIR); polarisation < 1 % VNIR (B1 = 1.2 %), ~1.7 % SWIR.
On-board calibration: CSM full-field/full-pupil sun diffuser (700 × 250 mm²), ~monthly (over North Pole). Dark signal: updated ~every 2 weeks from night-over-ocean (CSM open), averaged ≥ 10.8 s; stability VNIR < 1 DN, SWIR up to ~5 DN; DS uncertainty ~0.4 %.
L1C DN ↔ reflectance scaling [PROC; Processing Baseline 04.00, from 25 Jan 2022]:
QUANTIFICATION_VALUE= 10000 (scale 1e-4);RADIO_ADD_OFFSET= −1000 DN (L1C; L1B = −100; L2ABOA_ADD_OFFSET= −1000), stored in<Radiometric_Offset_List>.Inverse (user / reverse-entry):
ρ = (DN + RADIO_ADD_OFFSET) / QUANTIFICATION_VALUE = (DN − 1000)/10000.Forward (product encode):
DN = ρ·10000 − RADIO_ADD_OFFSET = ρ·10000 + 1000.No-data DN = 0; saturated DN = 65535. Pre-PB04.00 products carry no offset.
TOA-reflectance equation (PSD): \(\rho = \pi \cdot C_N \cdot d^2 / (A \cdot E_\mathrm{SUN} \cdot \cos\theta_s)\), CN = equalised count after L1B offset,
A= absolute calibration coefficient per band (in GIPP/ADF — not published numerically).
Instrument noise model (Gorroño & Gascon, S2-RUT): \(\mathrm{Noise}(Z) = \sqrt{\alpha_Z^2 + \beta_Z \cdot Z}\), Z = equalised signal; \(\alpha_Z\) = std of dark-signal frames (read + dark + electronic floor), \(\beta_Z\) = shot/Poisson from sun-diffuser. Equivalent generic form \(\sigma^2 = a \cdot \mathrm{DN} + b\). Components: dark + readout + electronic
shot. Per-band α_Z/β_Z are NOT public → fit to the SNR@Lref anchor + dark-noise floor.
Reference radiance Lref (W·m⁻²·sr⁻¹·µm⁻¹) and required SNR @ Lref (S2A/S2B spec, identical):
Band |
Lref |
SNR |
Band |
Lref |
SNR |
|---|---|---|---|---|---|
B01 |
129.11 |
129 |
B08 |
103.00 |
174 |
B02 |
128.00 |
154 |
B8A |
52.39 |
72 |
B03 |
128.00 |
168 |
B09 |
8.77 |
114 |
B04 |
108.00 |
142 |
B10 |
6.00 |
50 |
B05 |
74.60 |
117 |
B11 |
4.00 |
100 |
B06 |
68.23 |
89 |
B12 |
1.70 |
100 |
B07 |
66.70 |
105 |
A.7 Geometry / orbit#
Sun-synchronous, near-polar; altitude 786 km (range ~788–818 km over an orbit); semi-major axis 7164.26 km; eccentricity 0.0011584; inclination 98.62° (mission value; OCD/Binet 2022 gives 98.49° — discrepancy, see A.10); arg. of perigee 90.74°; period 100.6 min; LTDN 10:30 (LTAN ≈ 22:30, derived/uncited); repeat 10 d, 143 orbits/cycle, 14.3 orbits/day; revisit 5 d at equator (2-sat, 180° phased); swath 290 km; ground-track dead-band ±2 km.
Tiling: UTM/WGS-84 MGRS; tile 110 × 110 km on a 100 km grid step (~10 km overlap).
Geolocation: req. without GCP 20 m (2σ) (measured ~11–14.5 m); with GRI 12.5 m (CE95 < 12.5 m; block 8 m CE95); multi-temporal registration ≤ 0.3 px (= 3 / 6 / 18 m for 10/20/60 m); inter-band co-registration ≤ 0.30 coarser-pixel. GRI = global cloud-free mono-spectral B04 L1B/C images (2015–2018, ~1000), geolocated by spatio-triangulation, uncertainty < 6 m; operational worldwide since Aug 2021.
A.8 Viewing & datation (line-time) model#
Viewing model = datation (per-line start dates) + orbit + attitude + per-pixel viewing directions (spacecraft frame); geolocation = viewing-vector ∩ Earth model. COTS library ASGARD performs direct/inverse location (map ↔ detector), GCP-chip projection, footprint recompute.
ADFs:
ADF_VDIRP(per-pixel viewing directions),ADF_DATAT(datation),ADF_VIEDI,ADF_SPAMO,ADF_G2PRA/G2PRE. Per-pixel LOS for every band & detector lives in L1B “expertise”.Public per-detector viewing grids: L1C
MTD_TL.xml→Viewing_Incidence_Angles_Gridsgive viewing zenith + azimuth per band, per detector on a 5 km grid (23×23 nodes, 5000 m); overlap nodes carry two values. In-orbit LOS calibration < 0.1 px; main LOS geocentric; yaw-steering keeps ground velocity ⊥ detector arrays.De-orthorectify (cancelled L1C-entry module — for reference only): ortho pixel → ground (ITRF/WGS84) → inverse location (ASGARD) → detector (col, line). Push-broom: line index is linearly related to acquisition date. Not implemented: the adopted L1A/L1B entry is already in detector geometry.
Datation / line-time: nadir ground velocity ≈ 6700 m/s; line period (DERIVED = GSD/Vground) ≈ 1.49 ms (10 m) / 2.99 ms (20 m) / 8.96 ms (60 m); relative dating < 0.15 ms; absolute line-date < 2 ms; ephemeris sampling 1 Hz; solar-array attitude perturbation sine at 0.032 Hz (~2 ms peak). Inter-band time delays (Binet 2022 Tbl 2): B2–B4 = 1.005 s, B3–B2 = 0.527 s, B6–B11 ≈ 20 ms (min), B2–B9 = 2.586 s (max).
A.9 L0 / RAW format & PyRawS coregistration#
L0 = downlinked, on-board-compressed; RAW = decompressed L0 + metadata.
Granule = 13 bands × 12 detectors = 156 per-detector focal-plane images, raw geometry, NOT co-registered, ~3.6 s acquisition each.
Focal-plane along-track band order: B02, B08, B03, B10, B04, B05, B11, B06, B07, B8A, B12, B01, B09 — filter sort order inverted between odd/even detectors.
PyRawS deterministic coregistration (the known-shift fork):
pyraws/database/shift_lut.csv, keyed by (satellite S2A/S2B, registration_mode up/down-sampling, detector 1–12); each cell = [along-track, across-track] pixel shift for a band-pair vs a reference band. Along-track up to ~240 px (e.g. S2A det-1 B05↔ref = [239, −2]), across-track 0–34 px; sign flips with detector parity (odd +, even −). Directly usable for S8 SWIR de-arrangement (the cancelled L1C de-coregistration would also have used it; no SIFT).L1B = radiometrically corrected, per-detector geometry (retains parallax + overlap); L1C = orthorectified, band-co-registered, UTM tiles.
A.10 Provenance & unverified/derived#
Verified (multi-source): wavelengths; GSD; orbit; bit depth; radiometric-accuracy specs; Lref/SNR; detector tech; MTF@Nyquist; TMA / 150 mm / 600 mm / F4 (Languille 2015); mirror sizes; per-detector raw px shapes (PyRawS); focal-plane band order; PyRawS shift LUT; DN scaling PB04.00 (QUANT 10000, offset −1000); noise-model form; ASGARD / viewing grids; line period.
Single source: ESUN (SentiWiki Tbl 1 = L1C
SOLAR_IRRADIANCE; a TSIS-1 2021 set also exists); Lref/SNR (SentiWiki); dark/linearity/crosstalk detail (Gorroño & Gascon S2-RUT).Version-sensitive: band bandwidths (esp. B08 106 vs 115/118 nm) — fix to a named S2-SRF rev.
Derived: F-number; line periods (from Vground 6700 m/s); LTAN ≈ 22:30; 60 m ACT px count.
Conflicting / UNVERIFIED: TDI line counts — Martimort spec ~2-line for VNIR+SWIR vs one source citing SWIR B10=3/B11-12=4 (per-band unresolved); inclination 98.62° (mission) vs 98.49° (OCD/Binet). The earlier “~46 km inter-detector parallax” was erroneous (cross-detector parallax is sub-km, 0.022°–0.059°).
Not public (in ADF/GIPP binaries): absolute cal coefficient A(b); per-band noise α_Z/β_Z; PRNU/DSNU magnitudes; crosstalk matrix; full SRF curves (user will provide).
Environment caveat:
sentinel.esa.intwas DNS-unreachable during sourcing; ESA figures were taken from SentiWiki / SP-1322 / eoPortal / peer-reviewed mirrors carrying the same official values.
A.11 REAL values extracted from the product metadata (2026-06-29)#
Pulled from the EOPF reference product S02MSIL1B_20240403T000000_0001_A123_T000.zarr.zip
(other_metadata/image_data_info/...) — no credentialed ADF needed. The matched chain
L0P+L1A+L1B @ 20240403 enables empirical derivation; the L0 (S02MSIL0__) is the output reference.
Per-band physical_gains (DN↔radiance) + integration time:
band |
physical_gain |
integ (ms) |
band |
physical_gain |
integ (ms) |
|---|---|---|---|---|---|
B01 |
4.10503 |
7.4474 |
B08 |
6.14137 |
1.2705 |
B02 |
3.75138 |
1.2822 |
B8A |
5.11991 |
2.5587 |
B03 |
4.17678 |
1.3230 |
B09 |
8.50206 |
7.5934 |
B04 |
4.50915 |
1.3873 |
B10 |
55.05589 |
5.6990 |
B05 |
5.19263 |
2.8441 |
B11 |
35.29882 |
1.4036 |
B06 |
4.85731 |
2.7251 |
B12 |
106.15880 |
1.5004 |
B07 |
4.52068 |
2.7489 |
radio_add_offset= −100 (L1B; L1C = −1000, PB04.00).compression_rateper band 2.4–2.97.tdi_configuration_list= {B03: APPLIED, B04: APPLIED, B11: APPLIED, B12: APPLIED} (definitive).line_period= 1.5658736 ms;nuc_table_id= 3;compress_mode/equalization_mode= true; equalization per band = DSNU + offset proc.active_detector= 07 (these test products are single-detector subsets — d07).Local data:
/media/cando/T7/01_cdk/59_gitlab_repos/Copernicus/raw-data-gen/data/(5.8 GB, all levels L0__/Synthetic L0P/L1A/L1B/L1C/L2A) +reference/(l0_product_structure.json, reverse_chain_adf_analysis.json).