Algorithm Theoretical Basis Document (ATBD)

Contents

Algorithm Theoretical Basis Document (ATBD)#

Issued. This ATBD defines the algorithm basis by which s2_msi_raw_generator runs 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 L0 img (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

e2es-coupling-decision.md — org/interface ADR (two groups; processor pinned wheel; sensor-model ADF bridge)

AD 2

msi-processor ICD <5.3.x> (Synthetic L0 RAW container, processor-owned)

AD 3

msi-processor ATBD <5.7> (forward algorithm definitions, the conjugates)

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 — SOLAR_IRRADIANCE (ESUN) per band

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-processor forward 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 &amp; 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 (measurements/d{DD}/b{BB}/img, e.g. [9216,2552] @10 m), 13 bands. Already sensor-geometry ⇒ no geometry inversion (Issue #17).

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

\[X_k = A_k \cdot G_k(j,L) \cdot L_k + D_k\]

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,

\[\mathrm{DN}_i \mathrel{+}= \sum_j \mathrm{xtalk}[i,j] \cdot \mathrm{DN}_j\]

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:

  1. 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 with floor(·+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-block BitDepthAC DPCM + 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.

  2. 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-exactdecode(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 in sensor.py.

  • radiometric: per-band gain — physical_gains from 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 Zenodo records/18433006), DSNU + dark (ADF_REOB2, nighttime-ocean), defect/blind (ADF_BLIND/ADF_RDEPI, 3×B11 + 1×B12), crosstalk ADF_RCRCO (<0.5 %). nuc_table_id = 3, equalization on.

  • psf: per-band, per-unit kernel (DC=1) — the official ESA PSF matrices (SentiWiki S2{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_period 1.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 img RMSE per band

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 dark COEFF_D + relative response) is read directly by gipp.py / BandADF.from_gipp and is publicly fetchable (bucket GIP_* TGZs are anonymous-GET; verified 2026-07-02). The reverse reconstruction runs on it and validates against the reference ESA L0 img at 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’s derive-adf phase.


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 in s2_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-processor ADF_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; L2A BOA_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.xmlViewing_Incidence_Angles_Grids give 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.int was 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_rate per 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).