Constants¶
Every tuning bound, offset and weight in one place.
All frozen numbers in one place: DEBRA’s tuning constants and the classic Dust RGB recipe.
Every (MIN, MAX) scaling bound, offset, and weight from Miller et al. (2017), JGR Atmospheres, doi:10.1002/2017JD027365, using the 26 Feb 2020 erratum versions of Eqs. 7, 21, 22, 24, 25. The paper notes “minor retuning” may be needed per sensor; retune here, nowhere else.
Sign/orientation conventions follow the printed equations exactly.
The sensor facts here (Band and the channel maps) are not from the
paper; they are what each instrument calls the roles the algorithms read.
- class shachen.constants.Bounds[source]¶
Bases:
object(MIN, MAX) pair for the Eq. 3 normalization primitive.
- class shachen.constants.Band[source]¶
Bases:
StrEnumSpectral roles the algorithms read (nominal wavelengths in um).
Seven of these are DEBRA’s inputs (
DEBRA_BANDS);TIR_112exists only for the classic Dust RGB green gun.- VIS_064 = 'vis_064'¶
cloud mask + day baseline image
- NIR_160 = 'nir_160'¶
daytime cloud test (reserved)
- SWIR_39 = 'swir_39'¶
night thin-cirrus test CM4
- WV_62 = 'wv_62'¶
deep-convection test CM2
- TIR_86 = 'tir_86'¶
dust test DT2 (8.4-8.6 um)
- TIR_104 = 'tir_104'¶
clean window reference (10.3-10.4 um)
- TIR_112 = 'tir_112'¶
classic Dust RGB green gun only (11.2 um; not a DEBRA input)
- TIR_123 = 'tir_123'¶
dirty window, RSW / DT1 (12.3 um)
- __new__(value)¶
- shachen.constants.ABI_BANDS: dict[Band, str] = {Band.NIR_160: 'C05', Band.SWIR_39: 'C07', Band.TIR_104: 'C13', Band.TIR_112: 'C14', Band.TIR_123: 'C15', Band.TIR_86: 'C11', Band.VIS_064: 'C02', Band.WV_62: 'C08'}¶
Spectral role -> GOES-R ABI channel name (satpy dataset names).
- shachen.constants.AHI_BANDS: dict[Band, str] = {Band.NIR_160: 'B05', Band.SWIR_39: 'B07', Band.TIR_104: 'B13', Band.TIR_112: 'B14', Band.TIR_123: 'B15', Band.TIR_86: 'B11', Band.VIS_064: 'B03', Band.WV_62: 'B08'}¶
Spectral role -> Himawari AHI band name (satpy dataset names).
- shachen.constants.DEBRA_BANDS: tuple[Band, ...] = (Band.VIS_064, Band.NIR_160, Band.SWIR_39, Band.WV_62, Band.TIR_86, Band.TIR_104, Band.TIR_123)¶
The seven DEBRA algorithm input roles (Miller et al. 2017 Table 1).
Band.TIR_112exists only for the classic Dust RGB comparison baseline (shachen.dustrgb); pipelines that feed DEBRA alone load these.
- shachen.constants.BAND_CENTER_UM: dict[Band, float] = {Band.NIR_160: 1.61, Band.SWIR_39: 3.9, Band.TIR_104: 10.33, Band.TIR_112: 11.19, Band.TIR_123: 12.3, Band.TIR_86: 8.44, Band.VIS_064: 0.64, Band.WV_62: 6.19}¶
Nominal central wavelengths (um) used to interpolate the UWBF emissivity hinge points to sensor band centers (ABI values; AHI within tolerance).
- class shachen.constants.DustTestConstants[source]¶
Bases:
objectEqs. 13-15.
- dt1_max_rsw_k: float = 3.5¶
DT1 (Eq. 13): (RSW_obs - RSW_bg) / (max_rsw_k - RSW_bg), RSW = BT12.3 - BT10.4
- class shachen.constants.ConfidenceConstants[source]¶
Bases:
objectEqs. 16-22 (Eqs. 21-22 per erratum).
- class shachen.constants.ImageryConstants[source]¶
Bases:
objectEqs. 23-29 (Eqs. 24-25 per erratum).
- shachen.constants.COLOR_DIMMING: dict[str, tuple[float, float, float]] = {'blue': (0.25, 0.25, 1.0), 'green': (0.1, 1.0, 0.1), 'pink': (1.0, 0.25, 0.25), 'yellow': (1.0, 1.0, 0.1)}¶
Per-gun dimming triples (D_red, D_grn, D_blu) generalizing Eqs. 27-29: each gun is BI*(1 - min(CF, cf_cap)) + D_gun*CF, a full gun has D = 1.0. Presets from the paper’s section 4.2 text (“dust can be made pink by applying D = 0.25 to equations (28) and (29), green by applying D = 0.10 to equations (27) and (29), or blue by applying D = 0.25 to (27) and (28)”).
- shachen.constants.COMPOSITE_WINDOW_DAYS: int = 14¶
Cloud-cleared composite background (paper section 3.2, Option B): rolling window length (“multiday (e.g., 14 day) composites”) and the fewest composite days accepted at load time before the background is refused.
- class shachen.constants.DustRGBConstants[source]¶
Bases:
objectOne classic Dust RGB stretch set. Not part of DEBRA (Eqs. 1-29).
Each gun is
N(x; MIN, MAX) ** (1/gamma)over the GOES-R/Himawari band mix of the CIRA Dust RGB Quick Guide (satpy’sdustcomposite): 12.3-10.3, 11.2-8.4, 10.3 — note the green minuend is 11.2 um, not the 10.8 um of SEVIRI’sIR10.8 - IR8.7.The stretch values are per sensor:
DUST_RGB(SEVIRI) andDUST_RGB_ABIare the two published sets, dispatched byDUST_RGB_BY_READER. Seeshachen.dustrgbfor the references.
- shachen.constants.DUST_RGB = DustRGBConstants(red=Bounds(min=-4.0, max=2.0), green=Bounds(min=0.0, max=15.0), green_gamma=2.5, blue=Bounds(min=261.0, max=289.0))¶
The original SEVIRI stretches (Lensky and Rosenfeld 2008, as formalised in EUMeTrain’s recipe compilation; satpy’s generic
dust_defaultenhancement). Applied to Himawari here, which is what satpy does too: it ships nodust_ahioverride. Also the fallback for an unknown sensor.
- shachen.constants.DUST_RGB_ABI = DustRGBConstants(red=Bounds(min=-6.7, max=2.6), green=Bounds(min=-0.5, max=20.0), green_gamma=2.5, blue=Bounds(min=261.2, max=288.7))¶
The ABI-adjusted stretches from the CIRA GOES-R Dust RGB Quick Guide (satpy’s sensor-specific
dust_abienhancement), converted from the Quick Guide’s degrees Celsius. Berndt et al. (2018) is the method behind the adjustment: ABI’s channels do not sit where SEVIRI’s do, so the SEVIRI numbers put the clear-sky land background at the wrong end of the red stretch.
- shachen.constants.DUST_RGB_BY_READER: dict[str, DustRGBConstants] = {'abi_l1b': DustRGBConstants(red=Bounds(min=-6.7, max=2.6), green=Bounds(min=-0.5, max=20.0), green_gamma=2.5, blue=Bounds(min=261.2, max=288.7)), 'ahi_hsd': DustRGBConstants(red=Bounds(min=-4.0, max=2.0), green=Bounds(min=0.0, max=15.0), green_gamma=2.5, blue=Bounds(min=261.0, max=289.0))}¶
satpy reader -> the stretch set that sensor’s operational product uses.
shachen.pipeline.run_dust_rgb()reads this offscene.attrs["reader"]so a baseline rendered here matches the image forecasters see. The same rule is why there is no single canonical recipe to freeze: the scheme is retuned per imager (satpy carriesash_abi,convection_abiand the night-microphysics variants for the same reason).
- class shachen.constants.DebraConstants[source]¶
Bases:
objectThe whole tuning surface, one group per stage of the algorithm.
- cloud_mask: CloudMaskConstants¶
- dust_tests: DustTestConstants¶
- confidence: ConfidenceConstants¶
- imagery: ImageryConstants¶
- __init__(cloud_mask: CloudMaskConstants = <factory>, dust_tests: DustTestConstants = <factory>, confidence: ConfidenceConstants = <factory>, imagery: ImageryConstants = <factory>) None¶
- shachen.constants.DEFAULTS = DebraConstants(cloud_mask=CloudMaskConstants(cm1_cold_offset_k=50.0, cm2=Bounds(min=0.0, max=25.0), cm3=Bounds(min=2.0, max=4.5), cm4=Bounds(min=5.0, max=8.0), r1=Bounds(min=0.0, max=3.5), r2=Bounds(min=-1.0, max=3.0), cm_norm=Bounds(min=0.45, max=0.8)), dust_tests=DustTestConstants(dt1_max_rsw_k=3.5, dt2_max_btd_k=3.0, dt3_shift_land_k=-10.0, dt3_shift_ocean_k=5.0, dt3_depth_k=50.0), confidence=ConfidenceConstants(dt3_weight_trm=0.5, dt3_weight_ngt=0.5, cf_norm=Bounds(min=0.25, max=2.5), blend_exponent=1.5, ngt_trm_zenith_deg=Bounds(min=105.0, max=90.0), trm_day_zenith_deg=Bounds(min=90.0, max=75.0)), imagery=ImageryConstants(bg_blend_zenith_deg=Bounds(min=79.0, max=89.0), bg_blend_exponent=1.5, cf_cap=0.5, blue_dimming=0.1, gun_max=1.2))¶
The paper-tuned default constant set.
- shachen.constants.ABI_TUNED = DebraConstants(cloud_mask=CloudMaskConstants(cm1_cold_offset_k=50.0, cm2=Bounds(min=0.0, max=25.0), cm3=Bounds(min=2.0, max=4.5), cm4=Bounds(min=5.0, max=8.0), r1=Bounds(min=0.0, max=3.5), r2=Bounds(min=-1.0, max=3.0), cm_norm=Bounds(min=0.45, max=0.8)), dust_tests=DustTestConstants(dt1_max_rsw_k=3.5, dt2_max_btd_k=3.0, dt3_shift_land_k=-10.0, dt3_shift_ocean_k=5.0, dt3_depth_k=50.0), confidence=ConfidenceConstants(dt3_weight_trm=0.5, dt3_weight_ngt=0.5, cf_norm=Bounds(min=0.4, max=2.5), blend_exponent=1.5, ngt_trm_zenith_deg=Bounds(min=105.0, max=90.0), trm_day_zenith_deg=Bounds(min=90.0, max=75.0)), imagery=ImageryConstants(bg_blend_zenith_deg=Bounds(min=79.0, max=89.0), bg_blend_exponent=1.5, cf_cap=0.5, blue_dimming=0.1, gun_max=1.2))¶
Optional retune for the ABI + MERRA-2 + CAMEL stack. Single deviation from the paper: the Eq. 19 lower bound is raised 0.25 -> 0.40. Rationale: on this ancillary stack DT3 carries a 0.2-0.5 clear-sky floor over land (MERRA-2 skin T runs warmer than BT10.4, plus the -10 K land shift), which leaks through low-cloud-mask pixels as a faint yellow tint over vegetated and low-cloud areas. Sweeping the bound over the three reference cases: 0.40 removes 92% of the tinted area (SE-US box, fraction CF > 0.05: 0.37 -> 0.028) while the 2017-03-23 plume mean CF drops only 5% (0.476 -> 0.452) and the 2020-12-23 plume core stays distinct (p90 0.40). The paper itself anticipates “minor retuning” per sensor.