pycontrails 0.51.1__cp311-cp311-macosx_10_9_x86_64.whl → 0.51.2__cp311-cp311-macosx_10_9_x86_64.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/_version.py +2 -2
- pycontrails/core/polygon.py +1 -1
- pycontrails/core/rgi_cython.cpython-311-darwin.so +0 -0
- pycontrails/models/cocip/__init__.py +2 -0
- pycontrails/models/cocip/output_formats.py +165 -0
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/METADATA +2 -1
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/RECORD +11 -11
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/LICENSE +0 -0
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/NOTICE +0 -0
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/WHEEL +0 -0
- {pycontrails-0.51.1.dist-info → pycontrails-0.51.2.dist-info}/top_level.txt +0 -0
pycontrails/_version.py
CHANGED
pycontrails/core/polygon.py
CHANGED
|
@@ -354,7 +354,7 @@ def find_multipolygon(
|
|
|
354
354
|
return shapely.MultiPolygon()
|
|
355
355
|
|
|
356
356
|
assert len(hierarchy) == 1
|
|
357
|
-
hierarchy = hierarchy[0]
|
|
357
|
+
hierarchy = hierarchy[0] # type: ignore[index]
|
|
358
358
|
|
|
359
359
|
polygons = _contours_to_polygons(
|
|
360
360
|
contours, # type: ignore[arg-type]
|
|
Binary file
|
|
@@ -4,6 +4,7 @@ from pycontrails.models.cocip.cocip import Cocip
|
|
|
4
4
|
from pycontrails.models.cocip.cocip_params import CocipFlightParams, CocipParams
|
|
5
5
|
from pycontrails.models.cocip.cocip_uncertainty import CocipUncertaintyParams, habit_dirichlet
|
|
6
6
|
from pycontrails.models.cocip.output_formats import (
|
|
7
|
+
compare_cocip_with_goes,
|
|
7
8
|
contrail_flight_summary_statistics,
|
|
8
9
|
contrails_to_hi_res_grid,
|
|
9
10
|
flight_waypoint_summary_statistics,
|
|
@@ -24,4 +25,5 @@ __all__ = [
|
|
|
24
25
|
"longitude_latitude_grid",
|
|
25
26
|
"natural_cirrus_properties_to_hi_res_grid",
|
|
26
27
|
"time_slice_statistics",
|
|
28
|
+
"compare_cocip_with_goes",
|
|
27
29
|
]
|
|
@@ -14,13 +14,17 @@ This module includes functions to produce additional output formats, including t
|
|
|
14
14
|
(6) Increase spatial resolution of natural cirrus properties, required to estimate the
|
|
15
15
|
high-resolution contrail cirrus coverage for (5).
|
|
16
16
|
See :func:`natural_cirrus_properties_to_hi_res_grid`.
|
|
17
|
+
(7) Comparing simulated contrails from CoCiP with GOES satellite imagery.
|
|
18
|
+
See :func:`compare_cocip_with_goes`.
|
|
17
19
|
"""
|
|
18
20
|
|
|
19
21
|
from __future__ import annotations
|
|
20
22
|
|
|
23
|
+
import pathlib
|
|
21
24
|
import warnings
|
|
22
25
|
from collections.abc import Hashable
|
|
23
26
|
|
|
27
|
+
import matplotlib.pyplot as plt
|
|
24
28
|
import numpy as np
|
|
25
29
|
import numpy.typing as npt
|
|
26
30
|
import pandas as pd
|
|
@@ -28,6 +32,7 @@ import xarray as xr
|
|
|
28
32
|
|
|
29
33
|
from pycontrails.core.met import MetDataArray, MetDataset
|
|
30
34
|
from pycontrails.core.vector import GeoVectorDataset, vector_to_lon_lat_grid
|
|
35
|
+
from pycontrails.datalib.goes import GOES, extract_goes_visualization
|
|
31
36
|
from pycontrails.models.cocip.contrail_properties import contrail_edges, plume_mass_per_distance
|
|
32
37
|
from pycontrails.models.cocip.radiative_forcing import albedo
|
|
33
38
|
from pycontrails.models.humidity_scaling import HumidityScaling
|
|
@@ -2077,3 +2082,163 @@ def _repeat_rows_and_columns(
|
|
|
2077
2082
|
|
|
2078
2083
|
# Do not repeat final row and column as they are on the edge
|
|
2079
2084
|
return array_2d_rep[: -(n_reps - 1), : -(n_reps - 1)]
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
# -----------------------------------------
|
|
2088
|
+
# Compare CoCiP outputs with GOES satellite
|
|
2089
|
+
# -----------------------------------------
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
def compare_cocip_with_goes(
|
|
2093
|
+
time: np.timedelta64 | pd.Timestamp,
|
|
2094
|
+
flight: GeoVectorDataset | pd.DataFrame,
|
|
2095
|
+
contrail: GeoVectorDataset | pd.DataFrame,
|
|
2096
|
+
*,
|
|
2097
|
+
spatial_bbox: tuple[float, float, float, float] = (-160.0, -80.0, 10.0, 80.0),
|
|
2098
|
+
region: str = "F",
|
|
2099
|
+
path_write_img: pathlib.Path | None = None,
|
|
2100
|
+
) -> None | pathlib.Path:
|
|
2101
|
+
r"""
|
|
2102
|
+
Compare simulated persistent contrails from CoCiP with GOES satellite imagery.
|
|
2103
|
+
|
|
2104
|
+
Parameters
|
|
2105
|
+
----------
|
|
2106
|
+
time : np.timedelta64 | pd.Timestamp
|
|
2107
|
+
Time of GOES satellite image.
|
|
2108
|
+
flight : GeoVectorDataset | pd.DataFrame
|
|
2109
|
+
Flight waypoints.
|
|
2110
|
+
Best to use the returned output :class:`Flight` from
|
|
2111
|
+
:meth:`pycontrails.models.cocip.Cocip.eval`.
|
|
2112
|
+
contrail : GeoVectorDataset | pd.DataFrame,
|
|
2113
|
+
Contrail evolution outputs (:attr:`pycontrails.models.cocip.Cocip.contrail`)
|
|
2114
|
+
set during :meth:`pycontrails.models.cocip.Cocip.eval`.
|
|
2115
|
+
spatial_bbox : tuple[float, float, float, float]
|
|
2116
|
+
Spatial bounding box, ``(lon_min, lat_min, lon_max, lat_max)``, [:math:`\deg`]
|
|
2117
|
+
region : str
|
|
2118
|
+
'F' for full disk (image provided every 10 m), and 'C' for CONUS (image provided every 5 m)
|
|
2119
|
+
path_write_img : None | pathlib.Path
|
|
2120
|
+
File path to save the CoCiP-GOES image.
|
|
2121
|
+
|
|
2122
|
+
Returns
|
|
2123
|
+
-------
|
|
2124
|
+
None | pathlib.Path
|
|
2125
|
+
File path of saved CoCiP-GOES image if ``path_write_img`` is provided.
|
|
2126
|
+
"""
|
|
2127
|
+
|
|
2128
|
+
try:
|
|
2129
|
+
import cartopy.crs as ccrs
|
|
2130
|
+
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
|
|
2131
|
+
except ModuleNotFoundError as e:
|
|
2132
|
+
dependencies.raise_module_not_found_error(
|
|
2133
|
+
name="compare_cocip_with_goes function",
|
|
2134
|
+
package_name="cartopy",
|
|
2135
|
+
module_not_found_error=e,
|
|
2136
|
+
pycontrails_optional_package="goes",
|
|
2137
|
+
)
|
|
2138
|
+
|
|
2139
|
+
# Round `time` to nearest GOES image time slice
|
|
2140
|
+
if isinstance(time, np.timedelta64):
|
|
2141
|
+
time = pd.to_datetime(time)
|
|
2142
|
+
|
|
2143
|
+
if region == "F":
|
|
2144
|
+
time = time.round("10min")
|
|
2145
|
+
elif region == "C":
|
|
2146
|
+
time = time.round("5min")
|
|
2147
|
+
else:
|
|
2148
|
+
raise AssertionError("`region` only accepts inputs of `F` (full disk) or `C` (CONUS)")
|
|
2149
|
+
|
|
2150
|
+
_flight = GeoVectorDataset(flight)
|
|
2151
|
+
_contrail = GeoVectorDataset(contrail)
|
|
2152
|
+
|
|
2153
|
+
# Ensure the required columns are included in `flight_waypoints` and `contrails`
|
|
2154
|
+
_flight.ensure_vars(["flight_id", "waypoint"])
|
|
2155
|
+
_contrail.ensure_vars(
|
|
2156
|
+
["flight_id", "waypoint", "sin_a", "cos_a", "width", "tau_contrail", "age_hours"]
|
|
2157
|
+
)
|
|
2158
|
+
|
|
2159
|
+
# Downselect `_flight` only to spatial domain covered by GOES full disk
|
|
2160
|
+
is_in_lon = _flight.dataframe["longitude"].between(spatial_bbox[0], spatial_bbox[2])
|
|
2161
|
+
is_in_lat = _flight.dataframe["latitude"].between(spatial_bbox[1], spatial_bbox[3])
|
|
2162
|
+
is_in_lon_lat = is_in_lon & is_in_lat
|
|
2163
|
+
|
|
2164
|
+
if not np.any(is_in_lon_lat):
|
|
2165
|
+
warnings.warn(
|
|
2166
|
+
"Flight trajectory does not intersect with the defined spatial bounding box or spatial "
|
|
2167
|
+
"domain covered by GOES."
|
|
2168
|
+
)
|
|
2169
|
+
|
|
2170
|
+
_flight = _flight.filter(is_in_lon_lat)
|
|
2171
|
+
|
|
2172
|
+
# Filter `_flight` if time bounds were previously defined.
|
|
2173
|
+
is_before_time = _flight["time"] < time
|
|
2174
|
+
|
|
2175
|
+
if not np.any(is_before_time):
|
|
2176
|
+
warnings.warn("No flight waypoints were recorded before the specified `time`.")
|
|
2177
|
+
|
|
2178
|
+
_flight = _flight.filter(is_before_time)
|
|
2179
|
+
|
|
2180
|
+
# Downselect `_contrail` only to include the filtered flight waypoints
|
|
2181
|
+
is_in_domain = _contrail.dataframe["waypoint"].isin(_flight["waypoint"])
|
|
2182
|
+
|
|
2183
|
+
if not np.any(is_in_domain):
|
|
2184
|
+
warnings.warn(
|
|
2185
|
+
"No persistent contrails were formed within the defined spatial bounding box."
|
|
2186
|
+
)
|
|
2187
|
+
|
|
2188
|
+
_contrail = _contrail.filter(is_in_domain)
|
|
2189
|
+
|
|
2190
|
+
# Download GOES image at `time`
|
|
2191
|
+
goes = GOES(region=region)
|
|
2192
|
+
da = goes.get(time)
|
|
2193
|
+
rgb, transform, extent = extract_goes_visualization(da)
|
|
2194
|
+
bbox = spatial_bbox[0], spatial_bbox[2], spatial_bbox[1], spatial_bbox[3]
|
|
2195
|
+
|
|
2196
|
+
# Calculate optimal figure dimensions
|
|
2197
|
+
d_lon = spatial_bbox[2] - spatial_bbox[0]
|
|
2198
|
+
d_lat = spatial_bbox[3] - spatial_bbox[1]
|
|
2199
|
+
x_dim = 9.99
|
|
2200
|
+
y_dim = x_dim * (d_lat / d_lon)
|
|
2201
|
+
|
|
2202
|
+
# Plot data
|
|
2203
|
+
fig = plt.figure(figsize=(1.2 * x_dim, y_dim))
|
|
2204
|
+
pc = ccrs.PlateCarree()
|
|
2205
|
+
ax = fig.add_subplot(projection=pc, extent=bbox)
|
|
2206
|
+
ax.coastlines() # type: ignore[attr-defined]
|
|
2207
|
+
ax.imshow(rgb, extent=extent, transform=transform)
|
|
2208
|
+
|
|
2209
|
+
ax.set_xticks([spatial_bbox[0], spatial_bbox[2]], crs=ccrs.PlateCarree())
|
|
2210
|
+
ax.set_yticks([spatial_bbox[1], spatial_bbox[3]], crs=ccrs.PlateCarree())
|
|
2211
|
+
lon_formatter = LongitudeFormatter(zero_direction_label=True)
|
|
2212
|
+
lat_formatter = LatitudeFormatter()
|
|
2213
|
+
ax.xaxis.set_major_formatter(lon_formatter)
|
|
2214
|
+
ax.yaxis.set_major_formatter(lat_formatter)
|
|
2215
|
+
|
|
2216
|
+
# Plot flight trajectory up to `time`
|
|
2217
|
+
ax.plot(_flight["longitude"], _flight["latitude"], c="k", linewidth=2.5)
|
|
2218
|
+
plt.legend(["Flight trajectory"])
|
|
2219
|
+
|
|
2220
|
+
# Plot persistent contrails at `time`
|
|
2221
|
+
is_time = (_contrail["time"] == time) & (~np.isnan(_contrail["age_hours"]))
|
|
2222
|
+
im = ax.scatter(
|
|
2223
|
+
_contrail["longitude"][is_time],
|
|
2224
|
+
_contrail["latitude"][is_time],
|
|
2225
|
+
c=_contrail["tau_contrail"][is_time],
|
|
2226
|
+
s=4,
|
|
2227
|
+
cmap="YlOrRd_r",
|
|
2228
|
+
vmin=0,
|
|
2229
|
+
vmax=0.2,
|
|
2230
|
+
)
|
|
2231
|
+
cbar = plt.colorbar(im)
|
|
2232
|
+
cbar.set_label(r"$\tau_{\rm contrail}$")
|
|
2233
|
+
ax.set_title(f"{time}")
|
|
2234
|
+
plt.tight_layout()
|
|
2235
|
+
|
|
2236
|
+
# return output path if `path_write_img` is not None
|
|
2237
|
+
if path_write_img is not None:
|
|
2238
|
+
t_str = time.strftime("%Y%m%d_%H%M%S")
|
|
2239
|
+
file_name = f"goes_{t_str}.png"
|
|
2240
|
+
output_path = path_write_img.joinpath(file_name)
|
|
2241
|
+
plt.savefig(output_path, dpi=150, bbox_inches="tight")
|
|
2242
|
+
plt.close()
|
|
2243
|
+
|
|
2244
|
+
return output_path
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pycontrails
|
|
3
|
-
Version: 0.51.
|
|
3
|
+
Version: 0.51.2
|
|
4
4
|
Summary: Python library for modeling aviation climate impacts
|
|
5
5
|
Author-email: Breakthrough Energy <py@contrails.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -51,6 +51,7 @@ Requires-Dist: pytest >=8.2 ; extra == 'dev'
|
|
|
51
51
|
Requires-Dist: pytest-cov >=2.11 ; extra == 'dev'
|
|
52
52
|
Requires-Dist: requests >=2.25 ; extra == 'dev'
|
|
53
53
|
Requires-Dist: ruff ==0.4.1 ; extra == 'dev'
|
|
54
|
+
Requires-Dist: setuptools ; extra == 'dev'
|
|
54
55
|
Provides-Extra: docs
|
|
55
56
|
Requires-Dist: doc8 >=1.1 ; extra == 'docs'
|
|
56
57
|
Requires-Dist: furo >=2023.3 ; extra == 'docs'
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
pycontrails-0.51.
|
|
2
|
-
pycontrails-0.51.
|
|
3
|
-
pycontrails-0.51.
|
|
4
|
-
pycontrails-0.51.
|
|
5
|
-
pycontrails-0.51.
|
|
6
|
-
pycontrails-0.51.
|
|
7
|
-
pycontrails/_version.py,sha256=
|
|
1
|
+
pycontrails-0.51.2.dist-info/RECORD,,
|
|
2
|
+
pycontrails-0.51.2.dist-info/LICENSE,sha256=gJ-h7SFFD1mCfR6a7HILvEtodDT6Iig8bLXdgqR6ucA,10175
|
|
3
|
+
pycontrails-0.51.2.dist-info/WHEEL,sha256=3Ij8bI-sb8yCMxXItr4MLlNoRGZb2WoUxQe9xIFR_DQ,111
|
|
4
|
+
pycontrails-0.51.2.dist-info/NOTICE,sha256=gKI8DcN1WhiXB2SFRKDogcjONldGubTvBxiOYdC4CXU,1926
|
|
5
|
+
pycontrails-0.51.2.dist-info/top_level.txt,sha256=Z8J1R_AiBAyCVjNw6jYLdrA68PrQqTg0t3_Yek_IZ0Q,29
|
|
6
|
+
pycontrails-0.51.2.dist-info/METADATA,sha256=GrnTFo2vRstZA-G5KqvUe070DENl48rZUYrXVPjA2BM,8409
|
|
7
|
+
pycontrails/_version.py,sha256=NAimol_13XfyyQAJabjsIQxFxJiaGc5BgWOof3jZQM8,413
|
|
8
8
|
pycontrails/__init__.py,sha256=c_Vtz7CvdiVAL8ggluash9-8tGcLO_5Vvu-3_Ie47CE,1985
|
|
9
9
|
pycontrails/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
pycontrails/core/rgi_cython.cpython-311-darwin.so,sha256=
|
|
10
|
+
pycontrails/core/rgi_cython.cpython-311-darwin.so,sha256=Lzjfu3_E6X0m96F4ADQmySPB54MXT0u_1ZR78UEI9No,315896
|
|
11
11
|
pycontrails/core/vector.py,sha256=P61Rv1M040A1SRHmdWVR_RfXcWa6faM330n-9499ilI,71722
|
|
12
12
|
pycontrails/core/models.py,sha256=sipUAH_r0A1TxQ0yBjaPj8WC33Piw34ABHyrmRePfhg,39003
|
|
13
13
|
pycontrails/core/interpolation.py,sha256=FFYdUnTzGnkjoGs-FKsK3Y3nSK5lQI-mpq5HPALZ-y4,25495
|
|
14
14
|
pycontrails/core/fleet.py,sha256=84oTb8RJ3-bPVvZn3O2ljMEZLwJ9Q-E455ZzQJ4QaQU,16075
|
|
15
15
|
pycontrails/core/flight.py,sha256=jpd1bfdzUzNuuE-7pDraRC5I9kYetSwFUAMRYwMVxzw,83143
|
|
16
16
|
pycontrails/core/fuel.py,sha256=kJZ3P1lPm1L6rdPREM55XQ-VfJ_pt35cP4sO2Nnvmjs,4332
|
|
17
|
-
pycontrails/core/polygon.py,sha256=
|
|
17
|
+
pycontrails/core/polygon.py,sha256=NhoK91oVE2pse1kw2mkkhxxQpJrvBld8ofTMCwNH_h8,18016
|
|
18
18
|
pycontrails/core/datalib.py,sha256=m39gKxdhy9KSBhwWlrzEc5z-tTqPfcs7bPcqSxbU0k0,23971
|
|
19
19
|
pycontrails/core/cache.py,sha256=rCBZiRSVoFkRwf_ay7O-eba2PaYoXdlJSz1znZPuOQk,27957
|
|
20
20
|
pycontrails/core/__init__.py,sha256=4ZE7x1gMa_Q7GcgcWpPP9fQ-sTulCXWmMjsCJ0odakY,840
|
|
@@ -74,8 +74,8 @@ pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq,sha2
|
|
|
74
74
|
pycontrails/models/cocip/radiative_forcing.py,sha256=ERuFcYMo0_1iiOricnZ8D4ext23bMnTCeZwg9vd6Vzs,44944
|
|
75
75
|
pycontrails/models/cocip/wind_shear.py,sha256=p8d3iaNzxPA3MoxFEM1ZDKt0aticoD6U9cv0QmbuBzs,3860
|
|
76
76
|
pycontrails/models/cocip/cocip.py,sha256=0ILMcjbgsM00rCXAeo9UkSnUsmvq1XvORhNPI-ReNcM,97591
|
|
77
|
-
pycontrails/models/cocip/output_formats.py,sha256=
|
|
78
|
-
pycontrails/models/cocip/__init__.py,sha256=
|
|
77
|
+
pycontrails/models/cocip/output_formats.py,sha256=e3K-23EvEE2z9PuHNr2OQhwvN8_PYmNmR7Li-dsYZq8,83229
|
|
78
|
+
pycontrails/models/cocip/__init__.py,sha256=jd-9Tq20s1kwQBlxsYfZLi3hlT5MnWOY2XsPazq1fgE,962
|
|
79
79
|
pycontrails/models/cocip/cocip_params.py,sha256=R4bewge3xLgWYbBbGwd8e8r0NlaFx2IaQPZEfiqJZRI,11392
|
|
80
80
|
pycontrails/models/cocip/wake_vortex.py,sha256=i_OF193KK5BCMdVCgK0_4Aqn55f6rnL4WDWEac8um-w,14421
|
|
81
81
|
pycontrails/models/cocip/cocip_uncertainty.py,sha256=4JtlCVFpLBnPRlvyEp9QFpRfHFK9joSTnxe0NJdONG4,11784
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|