16 - Illumination and atmosphere¶
The illumination of a scene has two parts: the sun (less.Sun) gives the direction of the sun and the solar spectrum at the top of the atmosphere; the atmosphere model computes the direct sunlight and diffuse skylight reaching the ground, and some models also compute the atmospheric effects between the ground and the sensor.
import less
scene = less.Scene()
scene.size = 20
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.2))
scene.illumination = less.Illumination(
source=less.Sun(zenith=30, azimuth=150),
atmosphere=less.SimpleSpectralAtmosphere(turbidity=2.5),
)
Without a spectrum, Sun uses the built-in top-of-atmosphere solar spectrum. Sun(wavelengths=..., irradiance=...) supplies your own spectrum in W m⁻² nm⁻¹, as irradiance at the top of the atmosphere on a plane perpendicular to the sun's rays.
Choosing an atmosphere model¶
| Model | Use | Notes |
|---|---|---|
less.Atmosphere |
Satellite and airborne images, top-of-atmosphere reflectance | Layered radiative transfer; computes ground illumination and transmission to the sensor |
less.SixSAtmosphere |
When you work with 6S parameters | Requires less3d[atmosphere] |
less.PrescribedAtmosphere |
Known direct and diffuse transmittances | Gives the transmittances directly |
less.SimpleSpectralAtmosphere |
Fast broadband simulations | Simplified spectral attenuation, isotropic skylight |
less.HosekWilkieAtmosphere |
Visible wavelengths with a realistic sky brightness distribution | 320–720 nm |
less.NoAtmosphere |
No atmosphere | Sunlight is not attenuated; no skylight |
The layered atmosphere Atmosphere¶
scene.illumination = less.Illumination(
source=less.Sun(zenith=30, azimuth=150),
atmosphere=less.Atmosphere.standard(
"midlatitude_summer",
aerosol="continental",
aot550=0.10,
ground_altitude_km=0.0,
streams=8,
sky_mode="anisotropic",
),
)
Standard profiles:
| Name | Typical conditions |
|---|---|
"tropical" |
Tropics |
"midlatitude_summer" |
Mid-latitude summer |
"midlatitude_winter" |
Mid-latitude winter |
"subarctic_summer" |
Subarctic summer |
"subarctic_winter" |
Subarctic winter |
"us_standard", "us76" |
US Standard Atmosphere 1976 |
Aerosol types are "continental", "maritime", "urban", "desert", "biomass_burning" and "stratospheric". aot550 is the aerosol optical thickness at 550 nm; larger values attenuate direct sunlight more. ground_altitude_km is the elevation of the ground. sky_mode="anisotropic" keeps the directional variation of sky brightness, while "isotropic" treats skylight as the same from all directions.
Custom profiles¶
profile = less.AtmosphericProfile.standard("us76")
print(profile.surface_pressure(0.0)) # hPa
print(profile.column("h2o", ground_altitude_km=0.5))
custom = less.Atmosphere(profile=profile, aerosol="maritime", aot550=0.05)
A custom AtmosphericProfile uses heights in km, pressure in hPa, temperature in K and gas number densities in cm⁻³.
Computing the atmosphere on its own¶
The illumination and transmittances of an atmosphere can be computed without a scene:
import numpy as np
atmosphere = less.Atmosphere.standard("us76", aot550=0.10)
wavelengths = np.arange(400.0, 1001.0, 5.0)
result = atmosphere.solve(wavelengths, sun_zenith=40, output_altitudes_km=[2.0, 8.0, 20.0])
direct = result.direct_normal_irradiance # direct irradiance at the ground, normal to the rays
diffuse = result.diffuse_horizontal_irradiance # diffuse sky irradiance on a horizontal surface
up = result.upward_transmittance(view_zenith=10, observer_altitude_km=8.0)
| Result | Meaning |
|---|---|
direct_normal_irradiance |
Direct irradiance at the ground on a plane perpendicular to the rays |
diffuse_horizontal_irradiance |
Diffuse sky irradiance on a horizontal surface at the ground |
direct_transmittance |
Direct-beam transmittance |
upward_transmittance(...) |
Directional transmittance from the ground up to a given height |
path_radiance(...) |
Atmospheric path radiance in the viewing direction |
to_observer(...) |
Propagates ground radiance up to a given height |
directional_sky_radiance(...) |
Sky radiance by direction |
Irradiance is in W m⁻² nm⁻¹ and radiance in W m⁻² sr⁻¹ nm⁻¹.
Images at airborne and satellite altitude¶
With Atmosphere, optical sensors can return radiance at a given altitude or at the top of the atmosphere:
projection = less.Orthographic(image_size=64, view_zenith=10, view_azimuth=180)
airborne = scene.simulate(less.OpticalImager(
projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
observation_altitude_km=8.0))
top_of_atmosphere = scene.simulate(less.OpticalImager(
projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
observation_level="toa"))
observation_altitude_km is an altitude above sea level and is independent of the projection's geometric height in the scene. The atmosphere also affects other sensors: fluorescence images include the upward transmittance at the emission wavelengths, thermal images include downwelling longwave radiation and the atmosphere's own emission, and LiDAR includes the two-way attenuation.
6S¶
six_s = less.SixSAtmosphere(
atmosphere_profile="midlatitude_summer",
aerosol_type="continental",
aot550=0.1,
ground_altitude=0.0,
)
Profile names are the same as above; aerosol types are no_aerosols, continental, maritime, urban, desert and biomass_burning. Use it as Illumination(atmosphere=...).
Prescribed transmittances¶
When the direct and diffuse transmittances of the atmosphere are known:
scene.illumination = less.Illumination(
source=less.Sun(zenith=40, azimuth=160,
wavelengths=[450, 550, 650],
irradiance=[1.85, 1.88, 1.55]),
atmosphere=less.PrescribedAtmosphere(
wavelengths=[450, 550, 650],
direct_beam_transmittance=[0.60, 0.70, 0.78],
diffuse_horizontal_transmittance=[0.20, 0.14, 0.09],
),
)
The two coefficients are defined differently:
direct_beam_transmittance= direct irradiance at the ground (perpendicular to the rays) / solar irradiance at the top of the atmosphere (perpendicular to the rays);diffuse_horizontal_transmittance= diffuse sky irradiance on a horizontal surface at the ground / top-of-atmosphere solar irradiance on a horizontal surface.
So for a solar zenith angle θ and top-of-atmosphere irradiance E:
direct irradiance at the ground (perpendicular to the rays) = E × direct_beam_transmittance
diffuse irradiance on a horizontal surface = E × cos θ × diffuse_horizontal_transmittance
Both coefficients may be numbers or spectral arrays; at each wavelength their sum may not exceed 1.
Simple models¶
quick = less.SimpleSpectralAtmosphere(turbidity=2.5) # 300–2500 nm, isotropic sky
visible_sky = less.HosekWilkieAtmosphere(turbidity=2.5) # visible, sky brightness varies with direction
vacuum = less.NoAtmosphere()
turbidity describes how hazy the atmosphere is: around 2 for a clear sky, 5 or more for a hazy one.
The sky in the thermal infrared¶
Thermal simulations also need the sky's longwave radiation. less.Atmosphere computes it; NoAtmosphere has none; the other models need the sky's brightness temperature, or microclimate conditions at simulation time:
When the energy balance is used, the downwelling longwave radiation in less.Microclimate (estimated from air temperature and humidity if not given) also serves as the thermal sky. See chapter 26.