Skip to content

Class Diagram

Accurate class and module structure of GEE ACOLITE. Organised by where each component lives: client (local Python process) or server (GEE cloud).


Client-Side Components

These classes and functions run in the local Python process. They block until complete and cannot be deferred to GEE.

classDiagram namespace gee_acolite { class ACOLITE { +get_ancillary_data() dict +select_lut() tuple +estimate_aot_per_lut() dict +select_best_model() tuple +compute_correction_with_fixed_aot() tuple +dask_spectrum_fitting() dict } } namespace acolite_pkg { class AcoliteLUTs { +import_luts() dict +import_rsky_luts() dict +gas_transmittance() ndarray +rsr_dict() dict } class AcoliteMisc { +settings_parse() dict +ancillary_get() dict } } namespace numeric { class NumPySciPy { +interp() ndarray +minimize() OptimizeResult } } ACOLITE --> AcoliteLUTs : loads LUTs + gas transmittance ACOLITE --> AcoliteMisc : parses settings + ancillary ACOLITE --> NumPySciPy : AOT interpolation + model selection

Client Method Responsibilities

Method Role
__load_settings() Parse settings via acolite.acolite.settings.parse()
get_ancillary_data() Fetch pressure/wind/ozone from NASA Earthdata
select_lut() Load LUT files from disk for each atmospheric model
estimate_aot_per_lut() np.interp() — AOT at 550 nm per model, per band
select_best_model() RMSD / dtau / CV comparison → best LUT + fixed AOT
compute_correction_with_fixed_aot() Extract romix, dutott, astot, tg from best LUT
dask_spectrum_fitting() Orchestrates DSF: calls select_lut → returns atmospheric params

Server-Side Components

These classes and functions return ee.Image / ee.ImageCollection. They are lazy — no computation runs until .getInfo(), .export(), or tile rendering is triggered.

classDiagram namespace gee_acolite_server { class ACOLITE_GEE { +correct() tuple +l1_to_l2() ImageCollection +compute_pdark() dict +compute_rhos() Image +deglint_alternative() Image } class WaterQuality { +compute_water_mask() Image +compute_water_bands() Image +spm_nechad2016_665() Image +spm_nechad2016_704() Image +spm_nechad2016_740() Image +tur_nechad2016_665() Image +chl_oc2() Image +chl_oc3() Image +chl_re_mishra() Image +pSDB_green() Image +pSDB_red() Image +rrs() Image } class Bathymetry { +optical_deep_water_model() Image +calibrate_sdb() dict +apply_calibration() Image +multi_image() Image } } namespace utils_server { class L1Convert { +l1_to_rrs() ImageCollection +DN_to_rrs() Image +get_mean_band_angle() Image +resample() Image } class Masks { +mask_negative_reflectance() Image +toa_mask() Image +cirrus_mask() Image +non_water() Image +add_cloud_bands() Image +add_shadow_bands() Image +add_cld_shdw_mask() Image +cld_shdw_mask() Image } class Search { +search() ImageCollection +search_list() ImageCollection +search_with_cloud_proba() ImageCollection +join_s2_with_cloud_prob() ImageCollection } } namespace sensors { class Sentinel2 { +list SENTINEL2_BANDS +dict BAND_BY_SCALE } } ACOLITE_GEE --> L1Convert : l1_to_rrs() ACOLITE_GEE --> WaterQuality : compute_water_bands() ACOLITE_GEE --> Masks : masking pipeline WaterQuality --> Masks : water mask WaterQuality --> Sentinel2 : SENTINEL2_BANDS L1Convert --> Sentinel2 : BAND_BY_SCALE

Server Method Responsibilities

Method GEE Primitive
correct() / l1_to_l2() Orchestration — calls l1_to_rrs then per-image DSF loop
compute_pdark() reduceRegion(Reducer.percentile)getInfo() bridge
compute_rhos() image.expression() — applies correction formula per band
deglint_alternative() image.subtract() + updateMask()
non_water() / cirrus_mask() / toa_mask() B11.lt() / B10.lt() / band.lt()
add_cld_shdw_mask() directionalDistanceTransform(), focal_min/max()
spm_nechad2016* / tur_nechad2016* image.expression('A*R/(1-R/C)')
chl_oc2() / chl_oc3() image.log() + polynomial expression
rrs() image.divide(math.pi)
multi_image() qualityMosaic(band)

Client ↔ Server Communication

There are exactly two points where the client blocks waiting for GEE to return data:

sequenceDiagram participant Client as Local Python participant GEE as GEE Server Note over Client: DSF loop — per image Client->>GEE: compute_pdark()
reduceRegion(percentile or min) GEE-->>Client: .getInfo() → dark spectrum
{ B1: 0.032, B2: 0.028, … }
~13 floats, < 1 KB Note over Client: AOT estimation (numpy)
Model selection (scipy)
Extract atmospheric params Client->>GEE: compute_rhos(atm_params)
image.expression(correction_formula)
→ lazy ee.Image (no blocking) Note over Client,GEE: ─── Bathymetry only ─── Client->>GEE: calibrate_sdb()
sampleRegions() + Reducer.linearFit() GEE-->>Client: .getInfo() → { slope, offset }
2 floats

Performance note

getInfo() is called once per image in compute_pdark(). All other GEE operations are lazy and batched. Processing time scales linearly with the number of images.

Data transferred at each bridge point

Call Direction Payload Blocking
compute_pdark().getInfo() GEE → Client 13 floats (dark spectrum) Yes, per image
calibrate_sdb().getInfo() GEE → Client 2 floats (slope, offset) Yes, once
compute_rhos(atm_params) Client → GEE 4 floats per band × 13 bands No (lazy)

Module Dependency Graph

graph TD PKG[gee_acolite] CORR[correction.py] WQ[water_quality.py] BATH[bathymetry.py] SEARCH[utils/search.py] L1C[utils/l1_convert.py] MSK[utils/masks.py] S2[sensors/sentinel2.py] AC[ACOLITE submodule] PKG --> CORR PKG --> WQ PKG --> BATH CORR --> L1C CORR --> MSK CORR --> WQ CORR --> AC WQ --> MSK WQ --> S2 L1C --> S2 style AC fill:#fef3c7,stroke:#d97706 style PKG fill:#dbeafe,stroke:#3b82f6

Water Quality — PRODUCTS Registry

graph LR P["PRODUCTS dict"] P --> A[spm_nechad2016] P --> B[spm_nechad2016_704] P --> C[spm_nechad2016_740] P --> D[tur_nechad2016] P --> E[tur_nechad2016_704] P --> F[tur_nechad2016_740] P --> G[chl_oc2] P --> H[chl_oc3] P --> I[chl_re_mishra] P --> J[pSDB_green] P --> K[pSDB_red] P --> L["Rrs_B1 … Rrs_B12"]

Masking Pipeline

flowchart TD A[compute_water_mask] --> B[non_water
B11 < threshold] A --> C[cirrus_mask
B10 < threshold] A --> D[toa_mask
band < threshold] A --> E[add_cld_shdw_mask
optional] B --> F[Combined mask — updateMask] C --> F D --> F E --> F style A fill:#e1f5ff style F fill:#e1ffe1

Sentinel-2 Band Configuration

Band Wavelength (nm) Resolution Role
B1 443 60m Coastal aerosol
B2 490 10m Blue (pSDB numerator)
B3 560 10m Green
B4 665 10m Red (SPM, Turbidity)
B5 705 20m Red Edge 1 (Chl-a NDCI)
B6 740 20m Red Edge 2
B7 783 20m Red Edge 3
B8 842 10m NIR (water mask, shadows)
B8A 865 20m Narrow NIR
B9 945 60m Water vapour
B10 1375 60m Cirrus detection
B11 1610 20m SWIR 1 (water/land mask)
B12 2190 20m SWIR 2 (glint reference)