Purpose

This repository provides Ruby code for calculating values defined in the following standards:

  • International Standard Atmosphere (ISA) from ISO 2533:1975, ISO 2533:1975/ADD 1:1985 and ISO 2533:1975/ADD 2:1997

  • ICAO Standard Atmosphere (ICAO Doc 7488/3, 1994)

  • ISO 5878 reference atmospheres for aerospace use, including wind distribution calculations (Rice/circular normal distribution)

The ISO 2533 and ICAO Doc 7488/3 standards are technically identical but different in presentation and units (the ICAO document includes ft in addition to m).

This library serves as a reference implementation for the values defined in ISO CD 2533:2025 and ISO/DIS 5878.

Usage

General

This library contains code for two separate, but related, purposes.

  • Calculating atmospheric properties at different altitudes. The algorithms are based on ISO 2533.

  • Generating tables of atmospheric properties at different altitudes. This library is used to data tables provided by the full ISO 2533 series:

    • ISO 2533:1975

    • ISO 2533:1975/ADD 1:1985

    • ISO 2533:1975/ADD 2:1997

    • ISO CD 2533:2025

For the typical user who wishes to calculate atmospheric properties, there is no need to worry about how the tables work.

To calculate atmospheric properties, either use the formulas directly or use the Atmospheris::Export::AltitudeAttrs class to bulk obtain the values needed.

Prerequisites

Include the atmospheris gem in your Gemfile:

gem 'atmospheris'

Then use require in code:

require 'atmospheris'

Atmospheric attributes by altitude

The Atmospheris::Export::AltitudeAttrs class provides a way to obtain the atmospheric properties at a particular given altitude, geopotential or geometric.

The resulting object can also be easily serialized, courtesy of the lutaml-model library.

Syntax:

require 'atmospheris'

Atmospheris::Export::AltitudeAttrs.new.set_altitude(
  value: {altitude-value} <b class="conum">(1)</b>
  type: {altitude-type} <b class="conum">(2)</b>
  unit: {altitude-unit} <3>,
  precision: {precision-mode} <b class="conum">(4)</b>
)
  1. Value of the altitude desired. Integer.

  2. Type of altitude. Symbol. One of :geometric, :geopotential.

  3. Unit of the altitude. Symbol. One of :meters, :feet.

  4. Precision mode. Symbol. One of :normal, :high, :reduced. Default is :normal.

Each attribute of the AltitudeAttrs object is wrapped in a defined data class which is associated with a UnitsML unit.

Behavior of the precision mode:

:reduced

(default) Uses Isa::NormalPrecision for calculations with signficant digits rounding according to the original ISO 2533 specification.

:normal

Uses Isa::NormalPrecision for calculations without value modification.

:high

Uses Isa::HighPrecision for calculations without value modifications. This mode uses BigDecimal.

Depending on the type of the value, it is in one of the following classes:

  • Integer. Class: UnitValueInteger

  • Float. Class: UnitValueFloat

The AltitudeAttrs object provides the following attributes:

All attributes are represented as collections (arrays) to support multiple units:

geometric_altitudes

Array of geometric altitude values. Units: m, ft.

geopotential_altitudes

Array of geopotential altitude values. Units: m, ft.

temperatures

Array of temperature values. Units: K, degC.

pressures

Array of pressure values. Units: mbar, mm_Hg.

densities

Array of density values. Units: kg*m^-3.

accelerations

Array of acceleration values. Units: m*s^-2.

ppns

Array of pressure ratio values (unitless).

rhorhons

Array of density ratio values (unitless).

sqrt_rhorhons

Array of sqrt of density ratio values (unitless).

speeds_of_sound

Array of speed of sound values. Units: m*s^-1.

dynamic_viscosities

Array of dynamic viscosity values. Units: Pa*s.

kinematic_viscosities

Array of kinematic viscosity values. Units: m2*s-1.

thermal_conductivities

Array of thermal conductivity values. Units: W*m-1*K-1.

pressure_scale_heights

Array of pressure scale height values. Units: m.

specific_weights

Array of specific weight values. Units: N*m^-3.

air_number_densities

Array of air number density values. Units: m^-3.

mean_speeds

Array of mean speed values. Units: m*s^-1.

frequencies

Array of frequency values. Units: s^-1.

mean_free_paths

Array of mean free path values. Units: m.

Each attribute value is wrapped in UnitValueFloat or UnitValueInteger with UnitsML unit metadata.

require 'atmospheris'
attrs = Atmospheris::Export::AltitudeAttrs.new.set_altitude(
  value: -2000,
  type: :geopotential,
  unit: :meters
)

# Access collection values
attrs.geometric_altitudes[0].value  #=> -1999 (meters)
attrs.geometric_altitudes[1].value  #=> -6560 (feet)
attrs.geopotential_altitudes[0].value #=> -2000 (meters)
attrs.geopotential_altitudes[1].value #=> -6562 (feet)
attrs.temperatures[0].value           #=> 301.15 (Kelvin)
attrs.temperatures[1].value           #=> 28.0 (Celsius)
attrs.pressures[0].value             #=> 1277.74 (mbar)
attrs.pressures[1].value             #=> 958.382 (mm_Hg)

The object can be serialized into YAML or XML.

Example 1. AltitudeAttrs in YAML
attrs = Atmospheris::Export::AltitudeAttrs.new.set_altitude(
  value: -2000,
  type: :geopotential,
  unit: :meters
)

attrs.to_yaml
geometric-altitude:
- value: -1999
  unitsml: m
  type: integer
- value: -6560
  unitsml: ft
  type: integer
geopotential-altitude:
- value: -2000
  unitsml: m
  type: integer
- value: -6562
  unitsml: ft
  type: integer
temperature:
- value: 301.15
  unitsml: K
  type: float
- value: 28.0
  unitsml: degC
  type: float
pressure:
- value: 1277.74
  unitsml: mbar
  type: float
- value: 958.382
  unitsml: mm_Hg
  type: float
density:
- value: 1.47808
  unitsml: kg*m^-3
  type: float
acceleration:
- value: 9.8128
  unitsml: m*s^-2
  type: float
ppn:
- value: 1.26103
  type: float
rhorhon:
- value: 1.20659
  type: float
sqrt-rhorhon:
- value: 1.09845
  type: float
speed-of-sound:
- value: 347.886
  unitsml: m*s^-1
  type: float
dynamic-viscosity:
- value: 1.8514e-05
  unitsml: Pa*s
  type: float
kinematic-viscosity:
- value: 1.2526e-05
  unitsml: m^2*s^-1
  type: float
thermal-conductivity:
- value: 0.026359
  unitsml: W*m^-1*K^-1
  type: float
pressure-scale-height:
- value: 8809.5
  unitsml: m
  type: float
specific-weight:
- value: 14.504
  unitsml: N*m^-3
  type: float
air-number-density:
- value: 3.0734e+25
  unitsml: m^-3
  type: float
mean-speed:
- value: 469.18
  unitsml: m*s^-1
  type: float
frequency:
- value: 8535100000.0
  unitsml: s^-1
  type: float
mean-free-path:
- value: 5.4971e-08
  unitsml: m
  type: float
precision: reduced
Example 2. AltitudeAttrs in XML
attrs = Atmospheris::Export::AltitudeAttrs.new.set_altitude(
  value: -2000,
  type: :geopotential,
  unit: :meters,
  precision: :normal
)

attrs.to_xml
<atmosphere-attributes xmlns="urn:iso:std:iso:2533:tech:xsd">
  <geometric-altitude unitsml="m" type="integer">-1999</geometric-altitude>
  <geometric-altitude unitsml="ft" type="integer">-6560</geometric-altitude>
  <geopotential-altitude unitsml="m" type="integer">-2000</geopotential-altitude>
  <geopotential-altitude unitsml="ft" type="integer">-6562</geopotential-altitude>
  <temperature unitsml="K" type="float">301.15</temperature>
  <temperature unitsml="degC" type="float">28.0</temperature>
  <pressure unitsml="mbar" type="float">1277.74</pressure>
  <pressure unitsml="mm_Hg" type="float">958.38</pressure>
  <density unitsml="kg*m^-3" type="float">1.47808</density>
  <acceleration unitsml="m*s^-2" type="float">9.81282</acceleration>
  <ppn type="float">1.26103</ppn>
  <rhorhon type="float">1.20659</rhorhon>
  <sqrt-rhorhon type="float">1.09845</sqrt-rhorhon>
  <speed-of-sound unitsml="m*s^-1" type="float">347.886</speed-of-sound>
  <dynamic-viscosity unitsml="Pa*s" type="float">1.8514e-05</dynamic-viscosity>
  <kinematic-viscosity unitsml="m^2*s^-1" type="float">1.2526e-05</kinematic-viscosity>
  <thermal-conductivity unitsml="W*m^-1*K^-1" type="float">0.026359</thermal-conductivity>
  <pressure-scale-height unitsml="m" type="float">8809.5</pressure-scale-height>
  <specific-weight unitsml="N*m^-3" type="float">14.504</specific-weight>
  <air-number-density unitsml="m^-3" type="float">3.0734e+25</air-number-density>
  <mean-speed unitsml="m*s^-1" type="float">469.18</mean-speed>
  <frequency unitsml="s^-1" type="float">8535100000.0</frequency>
  <mean-free-path unitsml="m" type="float">5.4971e-08</mean-free-path>
  <precision>normal</precision>
</atmosphere-attributes>

Altitude by pressure

The Atmospheris::Export::PressureAttrs class provides a way to obtain the altitude at a given pressure value (mbar, mmhg).

Syntax:

require 'atmospheris'

Atmospheris::Export::PressureAttrs.new.set_pressure(
  value: {pressure-value}, <b class="conum">(1)</b>
  unit: {pressure-unit}, <b class="conum">(2)</b>
  precision: {precision-mode} <b class="conum">(3)</b>
)
  1. Value of the pressure desired. Float.

  2. Unit of the pressure. Symbol. One of :mbar, :mmhg.

Note
The set_pressure method does not yet support high-precision mode.

Behavior of the precision mode:

:reduced

(default) Uses Isa::NormalPrecision for calculations with signficant digits rounding according to the original ISO 2533/ADD 2 specification.

:normal

Uses Isa::NormalPrecision for calculations without value modification.

:high

Uses Isa::HighPrecision for calculations without value modifications. This mode uses BigDecimal.

Each attribute of the PressureAttrs object is wrapped in a defined data class which is associated with a UnitsML unit.

Depending on the type of the value, it is in one of the following classes:

  • Integer. Class: UnitValueInteger

  • Float. Class: UnitValueFloat

The PressureAttrs object provides the following attributes:

All attributes are represented as collections (arrays) to support multiple units:

pressures

Array of pressure values. Units: mbar, mm_Hg.

geometric_altitudes

Array of geometric altitude values. Units: m, ft.

geopotential_altitudes

Array of geopotential altitude values. Units: m, ft.

attrs = Atmospheris::Export::PressureAttrs.new.set_pressure(
  value: 5.0,
  unit: :mbar
)

# Access collection values
attrs.pressures[0].value           #=> 5.0 (mbar)
attrs.pressures[1].value           #=> 3.7503084135 (mm_Hg)
attrs.geopotential_altitudes[0].value #=> 35776.5 (meters)
attrs.geopotential_altitudes[1].value #=> 117377.0 (feet)
attrs.geometric_altitudes[0].value #=> 35979.0 (meters)
attrs.geometric_altitudes[1].value #=> 118041.0 (feet)

The object can be serialized into YAML or XML.

Example 3. PressureAttrs in YAML
attrs = Atmospheris::Export::PressureAttrs.new.set_pressure(
  value: 5.0,
  unit: :mbar
)

attrs.to_yaml
pressure:
- value: 5.0
  unitsml: mbar
  type: float
- value: 3.7503084135
  unitsml: mm_Hg
  type: float
geopotential-altitude:
- value: 35776.5
  unitsml: m
  type: float
- value: 117377.0
  unitsml: ft
  type: float
geometric-altitude:
- value: 35979.0
  unitsml: m
  type: float
- value: 118041.0
  unitsml: ft
  type: float
Example 4. PressureAttrs in XML
attrs = Atmospheris::Export::PressureAttrs.new.set_pressure(
  value: 5.0,
  unit: :mbar
)

attrs.to_xml
<hypsometrical-attributes xmlns="urn:iso:std:iso:2533:tech:xsd">
  <pressure unitsml="mbar" type="float">5.0</pressure>
  <pressure unitsml="mm_Hg" type="float">3.7503084135</pressure>
  <geometric-altitude unitsml="m" type="float">35979.0</geometric-altitude>
  <geometric-altitude unitsml="ft" type="float">118041.0</geometric-altitude>
  <geopotential-altitude unitsml="m" type="float">35776.5</geopotential-altitude>
  <geopotential-altitude unitsml="ft" type="float">117377.0</geopotential-altitude>
</hypsometrical-attributes>

Algorithms

General

For users who wish to access the algorithms directly, the Atmospheris::Isa::Algorithms class provides a set of methods for calculating atmospheric properties at different altitudes.

ISO 2533 specifies a number of formulas for the calculation of atmospheric properties at different altitudes.

These algorithms are implemented in the Atmospheris::Isa::Algorithms class.

There are two ways to use the Atmospheris::Isa::Algorithms class:

  • as a singleton class, using one of the precision modes (see below)

  • as a class instance

require 'atmospheris'
# Singleton class
instance = Atmospheris::Isa::NormalPrecision.instance.instance
instance.geometric_altitude_from_geopotential(100).to_f
=> 100.00157315171192

# Class instance
instance = Atmospheris::Isa::Algorithms.new(precision: :high)
instance.geometric_altitude_from_geopotential(100).to_f
=> 100.00157315171192

Formulas and calculations

The Algorithms class supports the following methods for calculating atmospheric properties.

Syntax:

require 'atmospheris'
instance = Atmospheris::Isa::Algorithms.new.{method_name} <b class="conum">(1)</b>
  1. method_name is one of the methods listed below.

The available methods are:

Converting between geometric and geopotential altitudes:

  • geometric_altitude_from_geopotential(geopotential_altitude)

  • geopotential_altitude_from_geometric(geometric_altitude)

Obtaining the temperature value from an altitude:

  • temperature_at_layer_from_geopotential(geopotential_altitude) (Kelvin)

  • temperature_at_layer_celcius(geopotential_altitude) (Celcius)

Obtaining the pressure value from an altitude:

  • pressure_from_geopotential_mbar(geopotential_altitude) (mbar/hPa)

  • pressure_from_geopotential_mmhg(geopotential_altitude) (mmHg)

Obtaining other atmospheric properties from an altitude:

  • density_from_geopotential(geopotential_altitude)

  • gravity_at_geopotential(geopotential_altitude)

  • p_p_n_from_geopotential(geopotential_altitude)

  • rho_rho_n_from_geopotential(geopotential_altitude)

  • root_rho_rho_n_from_geopotential(geopotential_altitude)

  • speed_of_sound_from_geopotential(geopotential_altitude)

  • dynamic_viscosity_from_geopotential(geopotential_altitude)

  • kinematic_viscosity_from_geopotential(geopotential_altitude)

  • thermal_conductivity_from_geopotential(geopotential_altitude)

  • pressure_scale_height_from_geopotential(geopotential_altitude)

  • specific_weight_from_geopotential(geopotential_altitude)

  • air_number_density_from_geopotential(geopotential_altitude)

  • mean_air_particle_speed_from_geopotential(geopotential_altitude)

  • air_particle_collision_frequency_from_geopotential(geopotential_altitude)

  • mean_free_path_of_air_particles_from_geopotential(geopotential_altitude)

Obtaining thermal conductivity from temperature:

  • thermal_conductivity_from_temp(temp)

Obtaining geopotential altitude from a given pressure:

  • geopotential_altitude_from_pressure_mbar(mbar)

  • geopotential_altitude_from_pressure_mmhg(mmhg)

Precision modes

There are two precision modes available for calculations.

High precision mode

Uses more accurate constants and number calculations through Ruby’s BigDecimal to provide results with higher precision. Suitable for applications where the utmost accuracy is required.

Normal precision mode (default)

Uses standard constants and number calculations to provide results with sufficient accuracy for most applications.

To use the high precision mode, you can either:

  • use the Atmospheris::Isa::HighPrecision class

  • use the Atmospheris::Isa::Algorithms class then call the set_precision(:high) method

require 'atmospheris'

# High precision mode
high_precision_instance = Atmospheris::Isa::HighPrecision.instance

speed_h = Atmospheris::Isa::HighPrecision.instance.speed_of_sound_from_temp(100)
=> 0.200467958523516054299360531511514627125051490111885121917578012786288944852326625441743718038552367514555018117e3

speed_h.class
=> BigDecimal

# Normal precision mode (default)
normal_precision_instance = Atmospheris::Isa::NormalPrecision.instance.instance

speed_n = Atmospheris::Isa::NormalPrecision.instance.instance.speed_of_sound_from_temp(100)
=> 200.46795852351607

speed_n.class
=> Float

ISO 5878 — Wind characteristics

The library implements wind speed distribution calculations per ISO 5878 (Reference atmospheres for aerospace use). Wind speed is modeled using the circular normal (Rice) distribution, which derives scalar wind speed statistics from observed vector components.

Quick start — Wind distribution

require 'atmospheris'

# Compute derived wind characteristics from observed parameters
wind = Atmospheris::Iso5878.compute_wind_derived(-3.9, -1.2, 5.9)

wind.vr     #=> 4.08 — vector mean wind magnitude (m/s)
wind.vsc    #=> 6.03 — scalar mean wind speed (m/s)
wind.sigma  #=> 4.17 — per-component standard deviation (m/s)

# Percentile wind speeds
wind.percentiles[1].high    #=> ~14.7 (not exceeded on 99% of occasions)
wind.percentiles[10].low    #=> ~0.5
wind.percentiles[10].high   #=> ~12.0
wind.percentiles[20]        #=> PercentilePair with low and high

WindObservation

The Atmospheris::Iso5878::WindObservation class encapsulates a single altitude-level wind observation with its empirically measured parameters and lazily computed derived statistics.

require 'atmospheris'

obs = Atmospheris::Iso5878::WindObservation.new(
  geopotential_altitude: 1000,
  vx: -3.9,
  vy: -1.2,
  sigma_r: 5.9,
  vsa: 7.6   # optional: observed scalar mean speed
)

obs.vr                          #=> 4.08
obs.theta                       #=> direction in radians from east
obs.vsc                         #=> 6.03 (calculated)
obs.percentile_bounds[1].high   #=> ~14.7
obs.derived_fields              #=> WindDerivedFields struct

Parameters:

  • geopotential_altitude — Altitude in metres

  • vx — Mean zonal wind component (m/s)

  • vy — Mean meridional wind component (m/s)

  • sigma_r — Standard deviation of vector mean wind (m/s)

  • vsa — (optional) Observed scalar mean speed (m/s)

  • nu_max — (optional) Max observed speed once in 10 years (m/s)

  • use_absolute_vx — (default: false) For zones > 20°N where Vy ≈ 0

RiceDistribution

The Atmospheris::Iso5878::RiceDistribution class encapsulates a Rice distribution with fixed parameters (Vr, sigma_r), providing lazy-cached statistical computations.

require 'atmospheris'

dist = Atmospheris::Iso5878::RiceDistribution.new(vr: 4.08, sigma_r: 5.9)

dist.mean              #=> 6.03 (scalar mean wind speed Vsc)
dist.pdf(5.0)          #=> probability density at 5 m/s
dist.cdf(10.0)         #=> P(wind ≤ 10 m/s)
dist.quantile(0.99)    #=> ~14.7 (wind speed exceeded on 1% of occasions)
dist.percentile_bounds #=> { 1 => Pair, 10 => Pair, 20 => Pair }

Methods:

  • pdf(nu) — Probability density at wind speed nu

  • cdf(x) — Cumulative distribution function

  • quantile(p) — Inverse CDF (quantile function)

  • mean — Analytical Rice distribution mean (Vsc, Eq. 4)

  • percentile_bounds — Hash mapping percentage (1, 10, 20) to PercentilePair

Low-level functions

Module-level functions in Atmospheris::Iso5878 for direct access to the underlying mathematical operations:

Method Description

bessel_i0(x)

Modified Bessel function of the first kind, order zero

bessel_i1(x)

Modified Bessel function of the first kind, order one

rice_pdf(nu, vr, sigma_r)

Rice distribution PDF (Eq. 3)

rice_cdf(x, vr, sigma_r)

Rice distribution CDF (adaptive Simpson quadrature)

rice_inv_cdf(p, vr, sigma_r)

Rice inverse CDF via bisection

rice_mean(vr, sigma_r)

Rice analytical mean (Eq. 4)

compute_wind_derived(vx, vy, sigma_r, use_absolute_vx:)

Compute all derived wind fields

Wind table export

The Atmospheris::Export::Iso5878.generate_wind_table method augments empirical wind observation YAML data with computed derived fields (Vsc, percentile bounds):

require 'atmospheris'

wind_data = YAML.load_file('table1.yaml')
augmented = Atmospheris::Export::Iso5878.generate_wind_table(wind_data)
File.write('table1-computed.yaml', YAML.dump(augmented))

Empirical fields (Vx, Vy, sigma-r, Vsa, nu-max) are never overwritten. Only blank computed fields (Vsc, percentile bounds) are filled.

Data structures

PercentilePair — Struct with low and high fields (keyword init):

pair = Atmospheris::Iso5878::PercentilePair.new(low: 0.5, high: 14.7)
pair.low   #=> 0.5
pair.high  #=> 14.7

WindDerivedFields — Struct with vr, sigma, vsc, percentiles (keyword init):

fields = Atmospheris::Iso5878::WindDerivedFields.new(
  vr: 4.08,
  sigma: 4.17,
  vsc: 6.03,
  percentiles: { 1 => pair, 10 => pair2, 20 => pair3 }
)

ISO 5878 — Reference atmosphere profiles

ISO 5878 defines reference atmospheres as temperature layer structures for selected latitudes (15°, 30°, 45°, 60°, 80°) and seasons, anchored to latitude-specific surface conditions. The library models these with SurfaceParameters, AtmosphereProfile and AtmosphereModelRegistry.

SurfaceParameters

Latitude-dependent constants per ISO 5878 Eq. 0 (Lambert’s equation for sea-level gravity), Eq. 13 (nominal earth radius), Eq. 7–9 (altitude conversions using latitude-specific gravity and radius):

require 'atmospheris'

sp = Atmospheris::Iso5878::SurfaceParameters.new(45)

sp.gravity_at_sea_level        #=> 9.80616 (m/s^2)
sp.nominal_earth_radius        #=> 6356364 (m)
sp.geopotential_from_geometric(5000)   #=> ~4995.8 (m)
sp.gravity_at_geometric(10_000)        #=> 9.7754 (m/s^2)

AtmosphereProfile

An AtmosphereProfile is an Isa::Algorithms subclass whose constants and temperature layers are injected instead of using the ISO 2533 defaults:

require 'atmospheris'

sp = Atmospheris::Iso5878::SurfaceParameters.new(45)

layers = Atmospheris::Iso5878::TemperatureLayerStructure.from_yaml_rows([
  { geopotential_altitude: 0.0,     temperature_K: 272.65 },
  { geopotential_altitude: 16_500,  temperature_K: 216.65 },
  # ...
]).to_a

profile = Atmospheris::Iso5878::AtmosphereProfile.new(
  surface_params: sp,
  surface_temperature: 272.65,
  surface_pressure: 101_800.0,
  layers: layers
)

profile.temperature_at_layer_from_geopotential(5000)
profile.pressure_from_geopotential(5000)
profile.density_from_geopotential(5000)

AtmosphereModelRegistry

The registry maps model IDs to latitude, season and surface conditions (ISO 5878 Table 2), and builds profiles from Table 16/19 layer data. Available model IDs:

15-annual, 30-winter, 30-summer, 45-winter, 45-summer, 60-winter, 60-summer, 60-warm, 60-cold, 80-winter, 80-summer, 80-warm, 80-cold.

require 'atmospheris'
require 'yaml'

table16 = YAML.load_file('table16.yaml')

profile = Atmospheris::Iso5878::AtmosphereModelRegistry.create("45-winter", table16)

profile.temperature_at_layer_from_geopotential(0)     #=> 272.62 (K)
profile.pressure_from_geopotential(5000)              #=> 52999.1 (Pa)
profile.density_from_geopotential(5000)               #=> 0.74254 (kg/m^3)

Atmospheris::Iso5878::AtmosphereModelRegistry.model_ids
#=> ["15-annual", "30-winter", ...]

Atmosphere profile export

The Atmospheris::Export::Iso5878.generate_atmosphere_profile method generates ISO 5878 atmosphere table YAML data for a given model:

require 'atmospheris'
require 'yaml'

table16 = YAML.load_file('table16.yaml')

data = Atmospheris::Export::Iso5878.generate_atmosphere_profile(
  "45-winter", table16,
  table_id: "atmosphere-table-5",
  title_en: "January reference atmosphere, 45N",
  geometric_altitudes: [0, 5000, 10_000, 20_000]
)

data["rows-h"][0]
#=> {"geometrical-altitude"=>0, "geopotential-altitude"=>0,
#     "temperature-K"=>272.62, "temperature-C"=>-0.53,
#     "p-mbar"=>1018.0, "density"=>1.300853}

Generating ISO 2533 tables

ISO 2533:1975

All tables in the 1975 edition are arranged in these steps in meters:

ISO 2533:1975 table range: step 50 from -2k, 100 from 32k, 200 from 51k to 80k
(-2000..31999).step(50) +
(32000..50999).step(100) +
(51000..80000).step(200)

Tables 5 to 7 all have height information as collections (arrays) with UnitsML unit metadata:

  • geometric-altitude (collection: m, ft)

  • geopotential-altitude (collection: m, ft)

All YAML tables generated contain these two keys which group altitude values as the ISO 2533 tables are rendered in both types of altitudes:

  • by-geopotential-altitude

  • by-geometric-altitude

Table 5

Title: "Temperature (T and t), Pressure (p), Density (p) and Acceleration of free fall (g) in terms of geometric altitude (h) and geopotential altitude (H)"

Provides the following values in addition to geopotential and geometric height:

  • temperature (collection: K, degC)

  • pressure (collection: mbar, mm_Hg)

  • density

  • acceleration

Atmospheris::Export::Iso25331975.table_5         #=> Lutaml::Model
Atmospheris::Export::Iso25331975.table_5.to_yaml #=> YAML

Table 6

Title: "Relations of p’pn, p/pn and bar(p/pn), Speed of sound (a), Dynamic viscosity (p), Kinematic viscosity (v) and Thermal conductivity (lambda) in terms of geometric altitude (h), and geopotential altitude (H)"

Provides the following values in addition to geopotential and geometric height:

  • ppn

  • rhorhon

  • sqrt-rhorhon

  • speed-of-sound

  • dynamic-viscosity

  • kinematic-viscosity

  • thermal-conductivity

Atmospheris::Export::Iso25331975.table_6         #=> Lutaml::Model
Atmospheris::Export::Iso25331975.table_6.to_yaml #=> YAML

Table 7

Title: "Pressure scale height (H_p) Specific weight (gamma), Air number density (n), Mean air-particle speed (v), Air-particle collision frequency (omega) and Mean free path of air particles (l) in terms of geometric altitude (h) and geopotential altitude (H)"

  • pressure-scale-height

  • specific-weight

  • air-number-density

  • mean-speed

  • frequency

  • mean-free-path

Atmospheris::Export::Iso25331975.table_7         #=> Lutaml::Model
Atmospheris::Export::Iso25331975.table_7.to_yaml #=> YAML

ISO 2533 ADD 1:1985

Addendum 1 adds "Hypsometrical tables".

Table 1 (hPa)

Title: "Geopotential altitude as a function of barometric pressure for 5 ⇐ p < 20 hPa at intervals of 0.01 hPa"

For the range of (5.0..19.99).step(0.01) in hPa.

Provides:

  • pressure (collection: mbar, mm_Hg)

  • geopotential-altitude

Atmospheris::Export::Iso25331985.table_1         #=> Lutaml::Model
Atmospheris::Export::Iso25331985.table_1.to_yaml #=> YAML

Table 2 (hPa)

Title: "Geopotential altitude as a function of barometric pressure for 20 ⇐ p < 1200 hPa at intervals of 0.1 hPa"

Same as Table 1 but for the range of (20.0..1199.9).step(0.1) in hPa.

Atmospheris::Export::Iso25331985.table_2         #=> Lutaml::Model
Atmospheris::Export::Iso25331985.table_2.to_yaml #=> YAML

Table 3 (mmHg)

Title: "Geopotential altitude as a function of barometric pressure for 4 ⇐ p < 10 mmHg at intervals of 0.01 mmHg"

Same as Table 1 but for the range of (4.0..9.99).step(0.01) and results in mmhg.

Provides:

  • pressure (collection: mbar, mm_Hg)

  • geopotential-altitude

Atmospheris::Export::Iso25331985.table_3         #=> Lutaml::Model
Atmospheris::Export::Iso25331985.table_3.to_yaml #=> YAML

Table 4 (mmHg)

Title: "Geopotential altitude as a function of barometric pressure for 10 ⇐ p < 900 mmHg at intervals of 0.1 mmHg"

Same as Table 3 but for the range of (10.0..899.9).step(0.1) and results in mmhg.

Atmospheris::Export::Iso25331985.table_4         #=> Lutaml::Model
Atmospheris::Export::Iso25331985.table_4.to_yaml #=> YAML

Table 5 (hPa) and Table 6 (mmHg)

The difference is Table 5 is in hPa while Table 6 is in mmHg.

Title: "Barometric pressure, in hectopascals, as a function of geopotential altitude for -1000 ⇐ H < +4600 m at intervals of 1m"

Provides:

  • geopotential-altitude

  • pressure (collection: mbar, mm_Hg)

Range of (-1000..4599).step(1).

Atmospheris::Export::Iso25331985.table_56         #=> Lutaml::Model
Atmospheris::Export::Iso25331985.table_56.to_yaml #=> YAML

ISO 2533 ADD 2:1997

Addendum 2 is exactly like ISO 2533:1975 with the tables but extended the tables:

  • 1975’s range is -2km to 80km. 1997 provides -5km to 2km (yes -2km to 2km overlaps…​)

  • 1975 tables only provide H and h in meters. 1997 adds a lookup table of H and h in feet.

ISO 2533 ADD 2:1997 Tables 1 to 3 have height range in meters
(-5000..2000).step(50)
ISO 2533 ADD 2:1997 Tables 4 to 6 have height range in feet
(-16500..-13999).step(250) +
(-14000..104999).step(200) +
(105000..262500).step(500)

Table 1 (-5km to 2km)

Title: "Temperature (T and t), pressure (p), density (p) and acceleration of free fall (g) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in metres"

Exactly same as ISO 2533:1975 Table 5, but with a different height range.

In addition, pressure at mmHg is no longer produced, but the implementation still provides it for completeness.

Atmospheris::Export::Iso25331997.table_1         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_1.to_yaml #=> YAML

Table 2 (-5km to 2km)

Title: "Relations of p’pn, p/pn and bar(p/pn), Speed of sound (a), Dynamic viscosity (p), Kinematic viscosity (v) and Thermal conductivity (lambda) in terms of geometric altitude (h), and geopotential altitude (H) — Altitudes in metres"

Exactly same as ISO 2533:1975 Table 6, but with a different height range.

Atmospheris::Export::Iso25331997.table_2         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_2.to_yaml #=> YAML

Table 3 (-5km to 2km)

Title: "Pressure scale height (H_p) Specific weight (gamma), Air number density (n), Mean air-particle speed (v), Air-particle collision frequency (omega) and Mean free path of air particles (l) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in metres"

Exactly same as ISO 2533:1975 Table 7, but with a different height range.

Atmospheris::Export::Iso25331997.table_3         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_3.to_yaml #=> YAML

Table 4 (-16.5kft to 262.5kft)

Title: "Temperature (T and t), pressure (p), density (p) and acceleration of free fall (g) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 5, but in feet and different range.

Pressure at mmHg is not produced, but the implementation still provides it for completeness.

Atmospheris::Export::Iso25331997.table_4         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_4.to_yaml #=> YAML

Table 5 (-16.5kft to 262.5kft)

Title: "Relations of p’pn, p/pn and bar(p/pn), Speed of sound (a), Dynamic viscosity (p), Kinematic viscosity (v) and Thermal conductivity (lambda) in terms of geometric altitude (h), and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 6, but in feet and different range.

Atmospheris::Export::Iso25331997.table_5         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_5.to_yaml #=> YAML

Table 6 (-16.5kft to 262.5kft)

Title: "Pressure scale height (H_p) Specific weight (gamma), Air number density (n), Mean air-particle speed (v), Air-particle collision frequency (omega) and Mean free path of air particles (l) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 7, but in feet and different range.

Atmospheris::Export::Iso25331997.table_6         #=> Lutaml::Model
Atmospheris::Export::Iso25331997.table_6.to_yaml #=> YAML

ISO 2533:2025

General

ISO 2533 is now being revised targeting a 2025 publication, which will be 50 years since the last edition (1975) and 28 years since it was last updated (1997).

It is currently in the CD stage (Committee Draft) and is expected to be published in 2025.

  • ISO NP 2533:2024. approved in 2024.

  • ISO WD 2533:2024. launched: 2024-11-22, closed: 2025-02-17.

  • ISO CD 2533:2024. pending.

ISO 2533:2025 covers all content in the previously published Addenda, including:

  • Standard atmosphere values from altitude -5km to 80km (geometric and geopotential)

    Note
    The 1975 edition provided values from -2km to 80km (even though it said 32km in the title).
    Note
    The 1997 ADD 2 provided values from -5km to 2km.
  • Standard atmosphere values from altitude -16,500ft to 262,500ft (geometric and geopotential)

    Note
    The 1997 ADD 2 provided these values.
  • Hypsometrical tables (altitude as a function of barometric pressure) (geometric and geopotential; hPa/mbar)

    Note
    The 1985 ADD 1 provided these hypsometrical tables in hPa/mbar and mmHg. In the 2024 edition only hPa/mbar is provided.

This document will also align to the values provided in ICAO Doc 7488/3.

All YAML tables generated contain these two keys which group altitude values as the ISO 2533 tables are rendered in both types of altitudes:

  • by-geopotential-altitude

  • by-geometric-altitude

The Iso25332025 class provides the following methods to generate tables:

table_atmosphere_meters

Atmosphere attributes by altitude (m). Grouped by by-geopotential-altitude and by-geometric-altitude. Each entry underneath is an AltitudeAttrs object. The altitude interval values follow these steps:

Step 50 from -5k, 100 from 32k, 200 from 51k to 80k.
(-5000..31950).step(50) +
(32000..50900).step(100) +
(51000..80000).step(200)
table_atmosphere_feet

Atmosphere attributes by altitude (ft). Grouped by by-geopotential-altitude and by-geometric-altitude. Each entry underneath is an AltitudeAttrs object. The altitude interval values follow these steps:

Step 250 from -16500, 200 from -14000, 500 from 105000 to 262500
(-16500..-13750).step(250) +
(-14000..104800).step(200) +
(105000..262500).step(500)
table_hypsometrical_altitude

Atmosphere attributes by altitude (m). This is the same as table_atmosphere_meters except with a modified step.

Step 1 from -1000 to 4599
(-1000..4599).step(1)
table_hypsometrical_mbar

Hypsometrical table by pressure (mbar). This is a table that provides altitude values per unit of pressure. Each entry underneath is a PressureAttrs object. It follows this step schedule:

Step 0.01 from 5 to 20, 0.1 from 20 to 1770.9
(5.0..19.99).step(0.01) +
(20.0..1770.9).step(0.1)
Example 5. Generating the ISO 2533:2025 tables
# Defaults to precision mode `:reduced`
Atmospheris::Export::Iso25332025.table_atmosphere_meters #=> Lutaml::Model
Atmospheris::Export::Iso25332025.table_atmosphere_meters.to_yaml #=> YAML

# To use precision mode `:high`
x = Atmospheris::Export::Iso25332025.table_atmosphere_meters(precision: :high)
x.to_yaml #=> YAML

The above table methods are used as the data sources for the data tables in ISO 2533:2025:

  • table_atmosphere_meters: Table 5 (meters), Table 6 (meters), Table 7 (meters). This data table is split into 3 tables for readability reasons.

  • table_atmosphere_feet: Table 8 (feet), Table 9 (feet), Table 10 (feet). Similarly, this data table is split into 3 tables for readability reasons.

  • table_hypsometrical_altitude: Table 11 (mbar).

  • table_hypsometrical_mbar: Table 12 (geopotential), Table 13 (geometric).

Table 5 (meters)

Note
This corresponds to ISO 2533:1975 Table 5 combined with ISO 2533:1975/ADD 1:1997 Table 1.

Title: "Temperature (T and t), Pressure (p), Density (p) and Acceleration of free fall (g) in terms of geometric altitude (h) and geopotential altitude (H)"

This table is a subset of the table_atmosphere_meters method.

Table 6 (meters)

Note
This corresponds to ISO 2533:1975 Table 6 combined with ISO 2533:1975/ADD 1:1997 Table 2.

Title: "Relations of p’pn, p/pn and bar(p/pn), Speed of sound (a), Dynamic viscosity (p), Kinematic viscosity (v) and Thermal conductivity (lambda) in terms of geometric altitude (h), and geopotential altitude (H)"

This table is a subset of the table_atmosphere_meters method.

Table 7 (meters)

Note
This corresponds to ISO 2533:1975 Table 7 combined with ISO 2533:1975/ADD 1:1997 Table 3.

Title: "Pressure scale height (H_p) Specific weight (gamma), Air number density (n), Mean air-particle speed (v), Air-particle collision frequency (omega) and Mean free path of air particles (l) in terms of geometric altitude (h) and geopotential altitude (H)"

This table is a subset of the table_atmosphere_meters method.

Table 8 (-16.5kft to 262.5kft)

Note
This corresponds to ISO 2533:1975/ADD 2:1997 Table 4.

Title: "Temperature (T and t), pressure (p), density (p) and acceleration of free fall (g) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 5, but in feet and different range.

Pressure at mmHg is not produced, but the implementation still provides it for completeness.

This table is a subset of the table_atmosphere_feet method.

Table 9 (-16.5kft to 262.5kft)

Note
This corresponds to ISO 2533:1975/ADD 2:1997 Table 5.

Title: "Relations of p’pn, p/pn and bar(p/pn), Speed of sound (a), Dynamic viscosity (p), Kinematic viscosity (v) and Thermal conductivity (lambda) in terms of geometric altitude (h), and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 6, but in feet and different range.

This table is a subset of the table_atmosphere_feet method.

Table 10 (-16.5kft to 262.5kft)

Note
This corresponds to ISO 2533:1975/ADD 2:1997 Table 6.

Title: "Pressure scale height (H_p) Specific weight (gamma), Air number density (n), Mean air-particle speed (v), Air-particle collision frequency (omega) and Mean free path of air particles (l) in terms of geometric altitude (h) and geopotential altitude (H) — Altitudes in feet"

Exactly same as ISO 2533:1975 Table 7, but in feet and different range.

This table is a subset of the table_atmosphere_feet method.

Table 11 (mbar)

Note
This corresponds to ISO 2533:1975/ADD 1:1985 Table 1 combined with Table 2.

Title: "Geometric and geopotential altitude as a function of barometric pressure for 5 ⇐ p < 20 hPa at intervals of 0.01 hPa and 20 ⇐ p < 1200 hPa at intervals of 0.1 hPa_"

For the range of (5.0..19.99).step(0.01) + (20.0..1199.9).step(0.1) in hPa.

Provides:

  • pressure (collection: mbar, mm_Hg)

  • geopotential-altitude (collection: m, ft)

  • geometric-altitude (collection: m, ft)

# Defaults to precision mode `:reduced`
Atmospheris::Export::Iso25332025.table_hypsometrical_mbar         #=> Lutaml::Model
Atmospheris::Export::Iso25332025.table_hypsometrical_mbar.to_yaml #=> YAML

# To use precision mode `:high`
x = Atmospheris::Export::Iso25332025.table_hypsometrical_mbar(precision: :high)
x.to_yaml #=> YAML

Table 12 (geopotential altitude, m)

Note
This corresponds to ISO 2533:1975/ADD 1:1985 Table 5 but in geopotential altitude.

Title: "Barometric pressure, in hectopascals, as a function of geopotential altitude for -1000 ⇐ H < +4600 m at intervals of 1m"

This table is a subset of the table_atmosphere_meters method.

Table 13 (geometric altitude, m)

Note
This corresponds to ISO 2533:1975/ADD 1:1985 Table 5, in geometric altitude.

Title: "Barometric pressure, in hectopascals, as a function of geometric altitude for -1000 ⇐ H < +4600 m at intervals of 1m"

This table is a subset of the table_atmosphere_meters method.

XML Schema

An XSD schema for the XML serialization format is provided at schema/atmospheris.xsd.

The schema uses the XML namespace urn:iso:std:iso:2533:tech:xsd following the RFC 5141 pattern for ISO technical XML schema resources. All elements are namespace-qualified (elementFormDefault="qualified").

The schema defines the following root elements:

atmospheris

Polymorphic root element. Two variants:

  • Hypsometrical table: contains <hypsometrical-attributes> records (pressure → altitude lookup).

  • ISO 2533:2025 table: contains <by-geometric-altitude> and <by-geopotential-altitude> sections, each with <atmospheris-attributes> records.

<!-- Hypsometrical table variant -->
<atmospheris xmlns="urn:iso:std:iso:2533:tech:xsd">
  <hypsometrical-attributes>
    <pressure unitsml="mbar" type="float">1013.25</pressure>
    <pressure unitsml="mm_Hg" type="float">760.0</pressure>
    <geometric-altitude unitsml="m" type="float">0.0</geometric-altitude>
    <geometric-altitude unitsml="ft" type="float">0.0</geometric-altitude>
    <geopotential-altitude unitsml="m" type="float">0.0</geopotential-altitude>
    <geopotential-altitude unitsml="ft" type="float">0.0</geopotential-altitude>
  </hypsometrical-attributes>
</atmospheris>

<!-- ISO 2533:2025 table variant -->
<atmospheris xmlns="urn:iso:std:iso:2533:tech:xsd">
  <by-geometric-altitude>
    <atmospheris-attributes>...</atmospheric-attributes>
  </by-geometric-altitude>
  <by-geopotential-altitude>
    <atmospheris-attributes>...</atmospheric-attributes>
  </by-geopotential-altitude>
</atmospheris>
atmosphere-attributes

Full atmospheric property record (ISO 2533:2025). Contains all altitude, temperature, pressure, density, and derived properties.

hypsometrical-attributes

Pressure-to-altitude record. Contains pressure and altitude values.

attributes-group

Wrapper for a collection of <atmospheris-attributes>.

All value elements share a common pattern:

  • Text content: the numeric value

  • unitsml attribute (optional): the UnitsML unit identifier (e.g., m, ft, K, mbar)

  • type attribute (required): either "float" or "integer"

<temperature unitsml="K" type="float">288.15</temperature>
<geometric-altitude unitsml="m" type="integer">5000</geometric-altitude>
<ppn type="float">0.53338</ppn>  <!-- dimensionless, no unitsml -->

Testing

General

$ bundle exec rake

Re-generate fixture tables

The spec/fixtures/iso* directories contains YAML files that are used to generate the ISO 2533 tables.

To re-generate the tables, run:

$ bundle exec rake clean generate

These tasks are defined in the Rakefile.

Algorithms

Tests are encoded in spec/fixtures/tests.yml in the following format:

- H: -2000.0
  h: -1999.0
  TK: 301.15
  TC: 28.0
  p_mbar: 1277.74
  p_mmhg: 958.382
  rho: 1.47808
  g: 9.8128
  p_p_n: 1.26103
  rho_rho_n: 1.20659
  root_rho_rho_n: 1.09845
  a: 347.886
  mu: 1.8514e-05
  v: 1.2526e-05
  lambda: 0.026359
  H_p: 8809.5
  gamma: 14.504
  n: 3.0734e+25
  v_bar: 469.18
  omega: 8535100000.0
  l: 549710000.0

Each of these values are associated with a cell in the tables of the source documents.

The only defining value in a tests is H (geopotential altitude). It is used to generate all the other values.

Copyright Ribose. Licensed under the 3-clause BSD license.