π§Ό The clean_data Schemaο
SounderPy converts supported atmospheric-profile data sources into a common dictionary structure called clean_data. This common structure is the interface between SounderPyβs data-retrieval, analysis, plotting, and export tools.
In other words:
RAOB βββββββββ
ACARS ββββββββ€
BUFKIT βββββββ€
RAP / RUC ββββ€
ERA5 βββββββββΌββ> clean_data ββ> calculations
NCEP βββββββββ€ ββ> sounding
WRF ββββββββββ€ ββ> hodograph
CM1 ββββββββββ€ ββ> composite
custom data ββ ββ> export
Once a profile has been converted into clean_data, the same SounderPy functions can be used regardless of the original data source.
Core Schemaο
A valid SounderPy profile contains the following core fields:
Key |
Variable |
Standard unit |
Description |
|---|---|---|---|
|
Pressure |
hPa |
Atmospheric pressure at each profile level. |
|
Height |
m |
Vertical coordinate associated with each profile level. |
|
Temperature |
degC |
Environmental air temperature. |
|
Dewpoint |
degC |
Environmental dewpoint temperature. |
|
U-component wind |
knots |
Zonal wind component. |
|
V-component wind |
knots |
Meridional wind component. |
|
Profile metadata |
β |
Dictionary describing the source, location, and valid time of the profile. |
Profile Array Requirementsο
The six atmospheric-profile variables:
p
z
T
Td
u
v
must follow several rules.
1. Each variable must be one-dimensional.
For example:
data["T"].shape
might return:
(73,)
2. All profile arrays must have the same length.
A single index must represent the same atmospheric level across all variables:
i = 10
print(data["z"][i])
print(data["p"][i])
print(data["T"][i])
print(data["Td"][i])
print(data["u"][i])
print(data["v"][i])
3. Profile arrays must carry physical units.
SounderPy uses Pint/MetPy quantities rather than unitless NumPy arrays.
For example:
print(data["p"][0])
print(data["T"][0])
print(data["u"][0])
may produce values similar to:
970 hectopascal
24.3 degree_Celsius
12.5 knot
4. The vertical profile should be ordered from the surface upward.
Generally:
zincreases monotonically with array index;pdecreases monotonically with array index.
Conceptually:
index z p
----- ------ ------
0 0 m 970 hPa
1 250 m 942 hPa
2 500 m 915 hPa
... ... ...
n 15000 m 120 hPa
Unitsο
SounderPy normally uses the following units internally:
Variable |
Unit |
|---|---|
|
hectopascals ( |
|
meters ( |
|
degrees Celsius ( |
|
degrees Celsius ( |
|
knots ( |
|
knots ( |
These values should remain unit-aware when constructing custom SounderPy profiles.
For example:
from metpy.units import units
pressure = pressure_values * units.hPa
height = height_values * units.m
temperature = temperature_values * units.degC
dewpoint = dewpoint_values * units.degC
u_wind = u_values * units.kt
v_wind = v_values * units.kt
site_info Metadataο
Profile metadata are stored in:
data["site_info"]
The exact metadata available can vary with the original data source.
Common SounderPy metadata fields include:
Key |
Meaning |
|---|---|
|
Station, airport, or profile identifier. |
|
Human-readable site name. |
|
Location description. |
|
|
|
Surface/site elevation. |
|
Description of the original data source. |
|
Model identifier when applicable. |
|
Forecast hour when applicable. |
|
Model initialization time when applicable. |
|
Valid time of the atmospheric profile. |
Some data sources may contain additional metadata such as box_area.
For example, a model profile may contain:
data["site_info"] = {
"site-id": "no-site-id",
"site-name": "no-site-name",
"site-lctn": "no-site-location",
"site-latlon": [44.58, -100.82],
"site-elv": 520.0,
"source": "MODEL REANALYSIS",
"model": "RAP",
"fcst-hour": "F00",
"run-time": ["2024", "08", "28", "18"],
"valid-time": ["2024", "08", "28", "18"],
"box_area": "0.25Β° x 0.25Β° BOX AVG",
}
Plot Titlesο
Many SounderPy-generated profiles also contain a titles dictionary used for figure annotation.
data["titles"]
A typical example is:
{
"top_title": "MODEL REANALYSIS VERTICAL PROFILE | 18Z RAP F00",
"left_title": "18Z RAP F00 | VALID: 08/28/2024 18Z",
"right_title": "44.58, -100.82 | 0.25Β° x 0.25Β° BOX AVG",
}
Optional Profile Variablesο
Some SounderPy data sources contain additional atmospheric variables.
Examples include:
Key |
Variable |
Typical unit |
|---|---|---|
|
Relative humidity |
percent |
|
Pressure vertical velocity |
Pa s^-1 |
These fields are not part of the minimum ``clean_data`` contract required for general SounderPy plotting and analysis.
Additional source-specific fields may also be present. For example omega is available for model forecasts and reanalysis but not for observations.
Example clean_data Dictionaryο
A simplified SounderPy profile can be represented as:
from metpy.units import units
clean_data = {
"p": [1000, 950, 900, 850] * units.hPa,
"z": [0, 500, 1000, 1500] * units.m,
"T": [24, 21, 18, 14] * units.degC,
"Td": [20, 18, 14, 10] * units.degC,
"u": [10, 15, 20, 25] * units.kt,
"v": [5, 10, 15, 20] * units.kt,
"site_info": {
"site-id": "EXAMPLE",
"site-name": "Example Profile",
"site-lctn": "North Dakota",
"site-latlon": [47.9, -97.0],
"site-elv": 250,
"source": "CUSTOM PROFILE",
"model": "no-model",
"fcst-hour": "no-fcst-hour",
"run-time": ["none", "none", "none", "none"],
"valid-time": ["2026", "09", "01", "18"],
},
"titles": {
"top_title": "CUSTOM VERTICAL PROFILE",
"left_title": "VALID: 09/01/2026 18Z",
"right_title": "47.9, -97.0",
},
}
Inspecting a Profileο
You can inspect the structure of any retrieved SounderPy profile with:
print(data.keys())
and:
print(data["site_info"])
To inspect units:
for key in ["p", "z", "T", "Td", "u", "v"]:
print(key, data[key].units)
Why the Schema Mattersο
The clean_data schema allows SounderPyβs major tools to operate independently of the original data source.
For example:
spy.build_sounding(data)
spy.build_hodograph(data)
general, thermo, kinem, intrp = spy.sounding_params(data).calc()
spy.to_file("csv", data)
all consume the same general profile structure.
This means data retrieval and atmospheric analysis remain separate:
retrieve / import
β
clean_data
β
ββββββββΌββββββββββ
β β β
plot calculate export