pycontrails 0.58.0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pycontrails might be problematic. Click here for more details.
- pycontrails/__init__.py +70 -0
- pycontrails/_version.py +34 -0
- pycontrails/core/__init__.py +30 -0
- pycontrails/core/aircraft_performance.py +679 -0
- pycontrails/core/airports.py +228 -0
- pycontrails/core/cache.py +889 -0
- pycontrails/core/coordinates.py +174 -0
- pycontrails/core/fleet.py +483 -0
- pycontrails/core/flight.py +2185 -0
- pycontrails/core/flightplan.py +228 -0
- pycontrails/core/fuel.py +140 -0
- pycontrails/core/interpolation.py +702 -0
- pycontrails/core/met.py +2931 -0
- pycontrails/core/met_var.py +387 -0
- pycontrails/core/models.py +1321 -0
- pycontrails/core/polygon.py +549 -0
- pycontrails/core/rgi_cython.cp314-win_amd64.pyd +0 -0
- pycontrails/core/vector.py +2249 -0
- pycontrails/datalib/__init__.py +12 -0
- pycontrails/datalib/_met_utils/metsource.py +746 -0
- pycontrails/datalib/ecmwf/__init__.py +73 -0
- pycontrails/datalib/ecmwf/arco_era5.py +345 -0
- pycontrails/datalib/ecmwf/common.py +114 -0
- pycontrails/datalib/ecmwf/era5.py +554 -0
- pycontrails/datalib/ecmwf/era5_model_level.py +490 -0
- pycontrails/datalib/ecmwf/hres.py +804 -0
- pycontrails/datalib/ecmwf/hres_model_level.py +466 -0
- pycontrails/datalib/ecmwf/ifs.py +287 -0
- pycontrails/datalib/ecmwf/model_levels.py +435 -0
- pycontrails/datalib/ecmwf/static/model_level_dataframe_v20240418.csv +139 -0
- pycontrails/datalib/ecmwf/variables.py +268 -0
- pycontrails/datalib/geo_utils.py +261 -0
- pycontrails/datalib/gfs/__init__.py +28 -0
- pycontrails/datalib/gfs/gfs.py +656 -0
- pycontrails/datalib/gfs/variables.py +104 -0
- pycontrails/datalib/goes.py +757 -0
- pycontrails/datalib/himawari/__init__.py +27 -0
- pycontrails/datalib/himawari/header_struct.py +266 -0
- pycontrails/datalib/himawari/himawari.py +667 -0
- pycontrails/datalib/landsat.py +589 -0
- pycontrails/datalib/leo_utils/__init__.py +5 -0
- pycontrails/datalib/leo_utils/correction.py +266 -0
- pycontrails/datalib/leo_utils/landsat_metadata.py +300 -0
- pycontrails/datalib/leo_utils/search.py +250 -0
- pycontrails/datalib/leo_utils/sentinel_metadata.py +748 -0
- pycontrails/datalib/leo_utils/static/bq_roi_query.sql +6 -0
- pycontrails/datalib/leo_utils/vis.py +59 -0
- pycontrails/datalib/sentinel.py +650 -0
- pycontrails/datalib/spire/__init__.py +5 -0
- pycontrails/datalib/spire/exceptions.py +62 -0
- pycontrails/datalib/spire/spire.py +604 -0
- pycontrails/ext/bada.py +42 -0
- pycontrails/ext/cirium.py +14 -0
- pycontrails/ext/empirical_grid.py +140 -0
- pycontrails/ext/synthetic_flight.py +431 -0
- pycontrails/models/__init__.py +1 -0
- pycontrails/models/accf.py +425 -0
- pycontrails/models/apcemm/__init__.py +8 -0
- pycontrails/models/apcemm/apcemm.py +983 -0
- pycontrails/models/apcemm/inputs.py +226 -0
- pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +183 -0
- pycontrails/models/apcemm/utils.py +437 -0
- pycontrails/models/cocip/__init__.py +29 -0
- pycontrails/models/cocip/cocip.py +2742 -0
- pycontrails/models/cocip/cocip_params.py +305 -0
- pycontrails/models/cocip/cocip_uncertainty.py +291 -0
- pycontrails/models/cocip/contrail_properties.py +1530 -0
- pycontrails/models/cocip/output_formats.py +2270 -0
- pycontrails/models/cocip/radiative_forcing.py +1260 -0
- pycontrails/models/cocip/radiative_heating.py +520 -0
- pycontrails/models/cocip/unterstrasser_wake_vortex.py +508 -0
- pycontrails/models/cocip/wake_vortex.py +396 -0
- pycontrails/models/cocip/wind_shear.py +120 -0
- pycontrails/models/cocipgrid/__init__.py +9 -0
- pycontrails/models/cocipgrid/cocip_grid.py +2552 -0
- pycontrails/models/cocipgrid/cocip_grid_params.py +138 -0
- pycontrails/models/dry_advection.py +602 -0
- pycontrails/models/emissions/__init__.py +21 -0
- pycontrails/models/emissions/black_carbon.py +599 -0
- pycontrails/models/emissions/emissions.py +1353 -0
- pycontrails/models/emissions/ffm2.py +336 -0
- pycontrails/models/emissions/static/default-engine-uids.csv +239 -0
- pycontrails/models/emissions/static/edb-gaseous-v29b-engines.csv +596 -0
- pycontrails/models/emissions/static/edb-nvpm-v29b-engines.csv +215 -0
- pycontrails/models/extended_k15.py +1327 -0
- pycontrails/models/humidity_scaling/__init__.py +37 -0
- pycontrails/models/humidity_scaling/humidity_scaling.py +1075 -0
- pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq +0 -0
- pycontrails/models/humidity_scaling/quantiles/era5-pressure-level-quantiles.pq +0 -0
- pycontrails/models/issr.py +210 -0
- pycontrails/models/pcc.py +326 -0
- pycontrails/models/pcr.py +154 -0
- pycontrails/models/ps_model/__init__.py +18 -0
- pycontrails/models/ps_model/ps_aircraft_params.py +381 -0
- pycontrails/models/ps_model/ps_grid.py +701 -0
- pycontrails/models/ps_model/ps_model.py +1000 -0
- pycontrails/models/ps_model/ps_operational_limits.py +525 -0
- pycontrails/models/ps_model/static/ps-aircraft-params-20250328.csv +69 -0
- pycontrails/models/ps_model/static/ps-synonym-list-20250328.csv +104 -0
- pycontrails/models/sac.py +442 -0
- pycontrails/models/tau_cirrus.py +183 -0
- pycontrails/physics/__init__.py +1 -0
- pycontrails/physics/constants.py +117 -0
- pycontrails/physics/geo.py +1138 -0
- pycontrails/physics/jet.py +968 -0
- pycontrails/physics/static/iata-cargo-load-factors-20250221.csv +74 -0
- pycontrails/physics/static/iata-passenger-load-factors-20250221.csv +74 -0
- pycontrails/physics/thermo.py +551 -0
- pycontrails/physics/units.py +472 -0
- pycontrails/py.typed +0 -0
- pycontrails/utils/__init__.py +1 -0
- pycontrails/utils/dependencies.py +66 -0
- pycontrails/utils/iteration.py +13 -0
- pycontrails/utils/json.py +187 -0
- pycontrails/utils/temp.py +50 -0
- pycontrails/utils/types.py +163 -0
- pycontrails-0.58.0.dist-info/METADATA +180 -0
- pycontrails-0.58.0.dist-info/RECORD +122 -0
- pycontrails-0.58.0.dist-info/WHEEL +5 -0
- pycontrails-0.58.0.dist-info/licenses/LICENSE +178 -0
- pycontrails-0.58.0.dist-info/licenses/NOTICE +43 -0
- pycontrails-0.58.0.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""Calculate tau cirrus on Met data."""
|
|
2
|
+
|
|
3
|
+
import dask.array
|
|
4
|
+
import xarray as xr
|
|
5
|
+
|
|
6
|
+
from pycontrails.core.met import MetDataset
|
|
7
|
+
from pycontrails.core.met_var import MetVariable
|
|
8
|
+
from pycontrails.physics import constants, thermo
|
|
9
|
+
from pycontrails.utils.types import ArrayLike
|
|
10
|
+
|
|
11
|
+
TauCirrus = MetVariable(
|
|
12
|
+
short_name="tau_cirrus",
|
|
13
|
+
standard_name="tau_cirrus",
|
|
14
|
+
long_name="Cirrus optical depth",
|
|
15
|
+
units="dimensionless",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _geopotential_height(met: MetDataset) -> xr.DataArray:
|
|
20
|
+
"""Extract geopotential height from MetDataset."""
|
|
21
|
+
|
|
22
|
+
# Attempt 1: Use geopotential height if available
|
|
23
|
+
try:
|
|
24
|
+
return met.data["geopotential_height"]
|
|
25
|
+
except KeyError:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
# Attempt 2: Use geopotential if available
|
|
29
|
+
try:
|
|
30
|
+
return met.data["geopotential"] / constants.g
|
|
31
|
+
except KeyError:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
# Attempt 3: Approximate geopotential height from altitude
|
|
35
|
+
# https://unidata.github.io/MetPy/latest/api/generated/metpy.calc.height_to_geopotential.html
|
|
36
|
+
altitude = met.data["altitude"]
|
|
37
|
+
return altitude * constants.radius_earth / (constants.radius_earth + altitude)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def tau_cirrus(met: MetDataset) -> xr.DataArray:
|
|
41
|
+
"""Calculate the optical depth of NWP cirrus around each pressure level.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
met : MetDataset
|
|
46
|
+
A MetDataset with the following variables:
|
|
47
|
+
|
|
48
|
+
- "air_temperature"
|
|
49
|
+
- "mass_fraction_of_cloud_ice_in_air", "specific_cloud_ice_water_content",
|
|
50
|
+
or "ice_water_mixing_ratio"
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
xr.DataArray
|
|
55
|
+
Array of tau cirrus values. Has the same dimensions as the input data.
|
|
56
|
+
|
|
57
|
+
Notes
|
|
58
|
+
-----
|
|
59
|
+
Implementation differs from original Fortran implementation in computing the
|
|
60
|
+
vertical derivative of geopotential height. In particular, the finite difference
|
|
61
|
+
at the top-most and bottom-most layers different from original calculation by a
|
|
62
|
+
factor of two. The implementation here is consistent with a numerical approximation
|
|
63
|
+
of the derivative.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
geopotential_height = _geopotential_height(met)
|
|
67
|
+
|
|
68
|
+
# TODO: these are not *quite* the same, though we treat them the same for now
|
|
69
|
+
# The generic "mass_fraction_of_cloud_ice_in_air" and ECMWF "specific_cloud_ice_water_content"
|
|
70
|
+
# are mass ice per mass of *moist* air,
|
|
71
|
+
# whereas GFS "ice_water_mixing_ratio" is mass ice per mass of *dry* air
|
|
72
|
+
#
|
|
73
|
+
# The method `cirrus_effective_extinction_coef` uses input of mass ice per mass of *dry* air,
|
|
74
|
+
# so only the GFS data is exactly right.
|
|
75
|
+
if "mass_fraction_of_cloud_ice_in_air" in met.data:
|
|
76
|
+
ciwc = met.data["mass_fraction_of_cloud_ice_in_air"]
|
|
77
|
+
elif "specific_cloud_ice_water_content" in met.data:
|
|
78
|
+
ciwc = met.data["specific_cloud_ice_water_content"]
|
|
79
|
+
elif "ice_water_mixing_ratio" in met.data:
|
|
80
|
+
ciwc = met.data["ice_water_mixing_ratio"]
|
|
81
|
+
else:
|
|
82
|
+
msg = "Could not find cloud ice variable"
|
|
83
|
+
raise KeyError(msg)
|
|
84
|
+
|
|
85
|
+
beta_e = cirrus_effective_extinction_coef(
|
|
86
|
+
ciwc,
|
|
87
|
+
met.data["air_temperature"],
|
|
88
|
+
met.data["air_pressure"],
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# dask.array.gradient expects at least 2 elements in each chunk
|
|
92
|
+
level_axis = geopotential_height.get_axis_num("level")
|
|
93
|
+
if geopotential_height.chunks:
|
|
94
|
+
level_chunks = geopotential_height.chunks[level_axis]
|
|
95
|
+
if any(chunk < 2 for chunk in level_chunks):
|
|
96
|
+
geopotential_height = geopotential_height.chunk(level=-1)
|
|
97
|
+
|
|
98
|
+
dz = -dask.array.gradient(geopotential_height, axis=level_axis)
|
|
99
|
+
dz = xr.DataArray(dz, dims=geopotential_height.dims)
|
|
100
|
+
|
|
101
|
+
da = beta_e * dz
|
|
102
|
+
|
|
103
|
+
da = da.cumsum(dim="level")
|
|
104
|
+
|
|
105
|
+
return _assign_attrs(da)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def cirrus_effective_extinction_coef(
|
|
109
|
+
ciwc: ArrayLike,
|
|
110
|
+
T: ArrayLike,
|
|
111
|
+
p: ArrayLike,
|
|
112
|
+
) -> ArrayLike:
|
|
113
|
+
r"""Calculate the effective extinction coefficient for spectral range 0.2-0.69 um.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
ciwc : ArrayLike
|
|
118
|
+
Cloud ice water content, [:math:`kg_{ice} kg_{dry \ air}^{-1}`].
|
|
119
|
+
Note that ECMWF provides specific ice water content per mass *moist* air.
|
|
120
|
+
T : ArrayLike
|
|
121
|
+
Air temperature, [:math:`K`]
|
|
122
|
+
p : ArrayLike
|
|
123
|
+
Air pressure, [:math:`Pa`]
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
ArrayLike
|
|
128
|
+
Effective extinction coefficient for spectral range 0.2-0.69 um, [:math:`m^{-1}`]
|
|
129
|
+
|
|
130
|
+
References
|
|
131
|
+
----------
|
|
132
|
+
- :cite:`schumannContrailCirrusPrediction2012`
|
|
133
|
+
- :cite:`sunParametrizationEffectiveSizes1999`
|
|
134
|
+
|
|
135
|
+
Notes
|
|
136
|
+
-----
|
|
137
|
+
References as noted in :cite:`schumannContrailCirrusPrediction2012`:
|
|
138
|
+
|
|
139
|
+
- Sun and Rikus QJRMS (1999), 125, 3037-3055
|
|
140
|
+
- Sun QJRMS (2001), 127, 267-271
|
|
141
|
+
- McFarquhar QJRMS (2001), 127, 261-265
|
|
142
|
+
"""
|
|
143
|
+
# ciwc has some negative values
|
|
144
|
+
# these become NaN when we raise them to powers down below
|
|
145
|
+
# explicitly clipping at 0
|
|
146
|
+
ciwc = ciwc.clip(min=0.0)
|
|
147
|
+
|
|
148
|
+
# Coefficients to calculate beta_e
|
|
149
|
+
a_0_beta = -1.30817e-4
|
|
150
|
+
a_1_beta = 2.52883e0
|
|
151
|
+
|
|
152
|
+
rho_air = thermo.rho_d(T, p)
|
|
153
|
+
riwc = ciwc * rho_air * 1000.0
|
|
154
|
+
|
|
155
|
+
# calculates the ice particle effective diameter in the NWP cirrus (in um)
|
|
156
|
+
# Computing these exponentials is expensive. If this is a bottleneck, numexpr
|
|
157
|
+
# should be used.
|
|
158
|
+
tiwc = T + constants.absolute_zero + 190.0
|
|
159
|
+
d_eff = 45.8966 * riwc**0.2214 + 0.7957 * tiwc * riwc**0.2535
|
|
160
|
+
|
|
161
|
+
# explicitly clipping at 10
|
|
162
|
+
d_eff = d_eff.clip(min=10.0)
|
|
163
|
+
|
|
164
|
+
return riwc * (a_0_beta + a_1_beta / d_eff)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _assign_attrs(da: xr.DataArray) -> xr.DataArray:
|
|
168
|
+
"""Assign name and attrs to xr.DataArray.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
da : xr.DataArray
|
|
173
|
+
DataArray to assign attributes to
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
xr.DataArray
|
|
178
|
+
DataArray with assigned attributes
|
|
179
|
+
"""
|
|
180
|
+
da.name = TauCirrus.standard_name
|
|
181
|
+
da.attrs = TauCirrus.attrs
|
|
182
|
+
|
|
183
|
+
return da
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Physical and thermodynamic relations."""
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Meteorological, thermophysical, and aircraft constants."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# -------
|
|
6
|
+
# General
|
|
7
|
+
# -------
|
|
8
|
+
|
|
9
|
+
# NOTE: Use a decimal point for each float-valued constant. This is important for
|
|
10
|
+
# converting to numpy arrays.
|
|
11
|
+
|
|
12
|
+
#: Absolute zero value :math:`[C]`
|
|
13
|
+
absolute_zero: float = -273.15
|
|
14
|
+
|
|
15
|
+
#: Gravitational acceleration :math:`[m \ s^{-2}]`
|
|
16
|
+
g: float = 9.80665
|
|
17
|
+
|
|
18
|
+
#: Radius of Earth :math:`[m]`
|
|
19
|
+
radius_earth: float = 6371229.0
|
|
20
|
+
|
|
21
|
+
#: Surface area of Earth :math:`[m^2]`
|
|
22
|
+
surface_area_earth: float = 5.10072e14
|
|
23
|
+
|
|
24
|
+
#: ISA height of the tropopause :math:`[m]`
|
|
25
|
+
#: :cite:`wikipediacontributorsInternationalStandardAtmosphere2023`
|
|
26
|
+
h_tropopause: float = 11000.0
|
|
27
|
+
|
|
28
|
+
#: Seconds in a Julian year :math:`[s]`
|
|
29
|
+
seconds_per_year: float = 3.15576e7
|
|
30
|
+
|
|
31
|
+
# -------------
|
|
32
|
+
# Thermodynamic
|
|
33
|
+
# -------------
|
|
34
|
+
|
|
35
|
+
#: Surface pressure, international standard atmosphere :math:`[Pa]`
|
|
36
|
+
#: :cite:`wikipediacontributorsInternationalStandardAtmosphere2023`
|
|
37
|
+
p_surface: float = 101325.0
|
|
38
|
+
|
|
39
|
+
#: Isobaric heat capacity of dry air :math:`[J \ kg^{-1} \ K^{-1}]`
|
|
40
|
+
c_pd: float = 1004.0 # 1005.7?
|
|
41
|
+
|
|
42
|
+
#: Isobaric heat capacity of water vapor :math:`[J \ kg^{-1} \ K^{-1}]`
|
|
43
|
+
c_pv: float = 1870.0
|
|
44
|
+
|
|
45
|
+
#: Molar mass of dry air :math:`[kg \ mol^{-1}]`
|
|
46
|
+
M_d: float = 28.9647e-3
|
|
47
|
+
|
|
48
|
+
#: Molar mass of water :math:`[kg \ mol^{-1}]`
|
|
49
|
+
M_v: float = 18.0153e-3
|
|
50
|
+
|
|
51
|
+
#: Ratio of heat capacities, TODO: which heat capacities?
|
|
52
|
+
gamma: float = 1.4
|
|
53
|
+
|
|
54
|
+
#: Molar gas constant :math:`[J \ mol^{-1} \ K^{-1}]`
|
|
55
|
+
R: float = 8.314462618
|
|
56
|
+
|
|
57
|
+
#: Gas constant of dry air :math:`[J \ kg^{-1} \ K^{-1}]`
|
|
58
|
+
R_d: float = 287.05
|
|
59
|
+
|
|
60
|
+
#: Gas constant of water vapour :math:`[J \ kg^{-1} \ K^{-1}]`
|
|
61
|
+
R_v: float = 461.51
|
|
62
|
+
|
|
63
|
+
#: Ratio of gas constant for dry air / gas constant for water vapor
|
|
64
|
+
epsilon: float = R_d / R_v
|
|
65
|
+
|
|
66
|
+
#: Density of ice :math:`[kg \ m^{-3}]`
|
|
67
|
+
rho_ice: float = 917.0
|
|
68
|
+
|
|
69
|
+
#: Adiabatic index air
|
|
70
|
+
kappa: float = 1.4
|
|
71
|
+
|
|
72
|
+
#: Standard atmospheric density at mean sea level (MSL) :math:`[kg \ m^{-3}]`
|
|
73
|
+
rho_msl: float = 1.225
|
|
74
|
+
|
|
75
|
+
#: Standard atmospheric temperature at mean sea level (MSL) :math:`[K]`
|
|
76
|
+
T_msl: float = 288.15
|
|
77
|
+
|
|
78
|
+
#: Speed of sound at mean sea level (MSL) in standard atmosphere :math:`[m \ s^{-1}]`
|
|
79
|
+
c_msl: float = 340.294
|
|
80
|
+
|
|
81
|
+
#: The rate at which the ISA ambient temperature falls with altitude :math:`[K \ m^{-1}]`
|
|
82
|
+
#: :cite:`wikipediacontributorsInternationalStandardAtmosphere2023`
|
|
83
|
+
T_lapse_rate: float = -0.0065
|
|
84
|
+
|
|
85
|
+
#: Average incident solar radiation, :math:`[W \ m^{-2}]`
|
|
86
|
+
#: This value can range +/- 3% as the earth orbits the sun.
|
|
87
|
+
#: From :cite:`uosolarradiationmonitoringlaboratoryUOSRMLSolar2022` citing
|
|
88
|
+
#: :cite:`paltridgeRadiativeProcessesMeteorology1976`
|
|
89
|
+
solar_constant: float = 1361.0
|
|
90
|
+
|
|
91
|
+
# ----
|
|
92
|
+
# Fuel
|
|
93
|
+
# ----
|
|
94
|
+
|
|
95
|
+
#: Isobaric heat capacity of combustion products :math:`[J \ kg^{-1} \ K^{-1}]`
|
|
96
|
+
c_p_combustion: float = 1250.0
|
|
97
|
+
|
|
98
|
+
# ------------------
|
|
99
|
+
# Optical Properties
|
|
100
|
+
# ------------------
|
|
101
|
+
|
|
102
|
+
#: Real refractive index of ice
|
|
103
|
+
mu_ice: float = 1.31
|
|
104
|
+
|
|
105
|
+
#: Wavelength of visible light (550 nm)
|
|
106
|
+
lambda_light: float = 550e-9
|
|
107
|
+
|
|
108
|
+
#: Ratio between the volume mean radius and the effective radius (Uncertainty +- 0.3)
|
|
109
|
+
c_r: float = 0.9
|
|
110
|
+
|
|
111
|
+
# ------
|
|
112
|
+
# Flight
|
|
113
|
+
# ------
|
|
114
|
+
|
|
115
|
+
#: Nominal rate of climb/descent of aircraft [:math:`m \ s^{-1}`].
|
|
116
|
+
#: Note [:math:`12.7 m \ s^{-1} = 2500 ft \ min^{-1}`].
|
|
117
|
+
nominal_rocd: float = 12.7
|