pycontrails 0.40.1__cp311-cp311-macosx_11_0_arm64.whl → 0.42.0__cp311-cp311-macosx_11_0_arm64.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/airports.py +228 -0
- pycontrails/core/datalib.py +8 -4
- pycontrails/core/fleet.py +13 -13
- pycontrails/core/flight.py +311 -86
- pycontrails/core/met.py +78 -78
- pycontrails/core/polygon.py +329 -339
- pycontrails/core/rgi_cython.cpython-311-darwin.so +0 -0
- pycontrails/core/vector.py +63 -51
- pycontrails/datalib/__init__.py +1 -1
- pycontrails/datalib/spire/__init__.py +19 -0
- pycontrails/datalib/spire/spire.py +739 -0
- pycontrails/models/cocip/wind_shear.py +2 -2
- pycontrails/models/emissions/emissions.py +1 -1
- pycontrails/models/humidity_scaling.py +1 -1
- pycontrails/models/issr.py +1 -1
- pycontrails/models/pcr.py +1 -1
- pycontrails/models/sac.py +5 -5
- pycontrails/physics/geo.py +3 -2
- pycontrails/physics/jet.py +66 -113
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/METADATA +2 -1
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/RECORD +26 -23
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/LICENSE +0 -0
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/NOTICE +0 -0
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/WHEEL +0 -0
- {pycontrails-0.40.1.dist-info → pycontrails-0.42.0.dist-info}/top_level.txt +0 -0
pycontrails/core/met.py
CHANGED
|
@@ -1683,12 +1683,12 @@ class MetDataArray(MetBase):
|
|
|
1683
1683
|
fill_value: float = 0.0,
|
|
1684
1684
|
iso_value: float | None = None,
|
|
1685
1685
|
min_area: float = 0.0,
|
|
1686
|
-
min_area_to_iterate: float = 0.0,
|
|
1687
1686
|
epsilon: float = 0.0,
|
|
1688
1687
|
precision: int | None = None,
|
|
1689
|
-
|
|
1688
|
+
interiors: bool = True,
|
|
1690
1689
|
convex_hull: bool = False,
|
|
1691
1690
|
include_altitude: bool = False,
|
|
1691
|
+
properties: dict[str, Any] | None = None,
|
|
1692
1692
|
) -> dict[str, Any]:
|
|
1693
1693
|
"""Create GeoJSON Feature artifact from spatial array on a single level and time slice.
|
|
1694
1694
|
|
|
@@ -1696,7 +1696,7 @@ class MetDataArray(MetBase):
|
|
|
1696
1696
|
`GeoJSON Polygon specification <https://www.rfc-editor.org/rfc/rfc7946.html#section-3.1.6>`.
|
|
1697
1697
|
Polygons may also contain interior linear rings (holes). This method does not support
|
|
1698
1698
|
nesting beyond the GeoJSON specification. See the :mod:`pycontrails.core.polygon`
|
|
1699
|
-
for additional polygon support
|
|
1699
|
+
for additional polygon support.
|
|
1700
1700
|
|
|
1701
1701
|
.. versionchanged:: 0.25.12
|
|
1702
1702
|
|
|
@@ -1717,6 +1717,12 @@ class MetDataArray(MetBase):
|
|
|
1717
1717
|
|
|
1718
1718
|
Change default value of ``epsilon`` from 0.15 to 0.
|
|
1719
1719
|
|
|
1720
|
+
.. versionchanged:: 0.41.0
|
|
1721
|
+
|
|
1722
|
+
Convert continuous fields to binary fields before computing polygons.
|
|
1723
|
+
The parameters ``max_area`` and ``epsilon`` are now expressed in terms of
|
|
1724
|
+
longitude/latitude units instead of pixels.
|
|
1725
|
+
|
|
1720
1726
|
Parameters
|
|
1721
1727
|
----------
|
|
1722
1728
|
level : float, optional
|
|
@@ -1733,28 +1739,20 @@ class MetDataArray(MetBase):
|
|
|
1733
1739
|
iso_value : float, optional
|
|
1734
1740
|
Value in field to create iso-surface.
|
|
1735
1741
|
Defaults to the average of the min and max value of the array. (This is the
|
|
1736
|
-
same convention as used by ``skimage``.)
|
|
1737
|
-
in :func:`skimage.measure.find_contours`.
|
|
1742
|
+
same convention as used by ``skimage``.)
|
|
1738
1743
|
min_area : float, optional
|
|
1739
1744
|
Minimum area of each polygon. Polygons with area less than ``min_area`` are
|
|
1740
|
-
not included in the output. The unit of this parameter is
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
min_area_to_iterate : float, optional
|
|
1744
|
-
Minimum area of exterior polygon to search for interior rings. Polygons with
|
|
1745
|
-
area less than ``min_area_to_iterate`` are not searched for interior rings.
|
|
1746
|
-
The same unit convention as ``min_area`` applies. Set to 0 to omit any polygon
|
|
1747
|
-
filtering based on a minimal area conditional. By default, 0.0.
|
|
1748
|
-
A reasonable value for this parameter is 10x the ``min_area`` parameter.
|
|
1745
|
+
not included in the output. The unit of this parameter is in longitude/latitude
|
|
1746
|
+
degrees squared. Set to 0 to omit any polygon filtering based on a minimal area
|
|
1747
|
+
conditional. By default, 0.0.
|
|
1749
1748
|
epsilon : float, optional
|
|
1750
1749
|
Control the extent to which the polygon is simplified. A value of 0 does not alter
|
|
1751
|
-
the geometry of the polygon.
|
|
1750
|
+
the geometry of the polygon. The unit of this parameter is in longitude/latitude
|
|
1751
|
+
degrees. By default, 0.0.
|
|
1752
1752
|
precision : int, optional
|
|
1753
1753
|
Number of decimal places to round coordinates to. If None, no rounding is performed.
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
the exterior and interior rings are both included. Set to 1 to include only the
|
|
1757
|
-
exterior ring. Must be 1 or 2.
|
|
1754
|
+
interiors : bool, optional
|
|
1755
|
+
If True, include interior linear rings (holes) in the output. True by default.
|
|
1758
1756
|
convex_hull : bool, optional
|
|
1759
1757
|
EXPERIMENTAL. If True, compute the convex hull of each polygon. Only implemented
|
|
1760
1758
|
for depth=1. False by default. A warning is issued if the underlying algorithm
|
|
@@ -1763,6 +1761,8 @@ class MetDataArray(MetBase):
|
|
|
1763
1761
|
If True, include the array altitude [:math:`m`] as a z-coordinate in the
|
|
1764
1762
|
`GeoJSON output <https://www.rfc-editor.org/rfc/rfc7946#section-3.1.1>`.
|
|
1765
1763
|
False by default.
|
|
1764
|
+
properties : dict, optional
|
|
1765
|
+
Additional properties to include in the GeoJSON output. By default, None.
|
|
1766
1766
|
|
|
1767
1767
|
Returns
|
|
1768
1768
|
-------
|
|
@@ -1772,8 +1772,7 @@ class MetDataArray(MetBase):
|
|
|
1772
1772
|
See Also
|
|
1773
1773
|
--------
|
|
1774
1774
|
:meth:`to_polyhedra`
|
|
1775
|
-
:func:`
|
|
1776
|
-
:func:`pycontrails.core.polygons.find_contours_to_depth`
|
|
1775
|
+
:func:`pycontrails.core.polygons.find_multipolygons`
|
|
1777
1776
|
|
|
1778
1777
|
Examples
|
|
1779
1778
|
--------
|
|
@@ -1784,34 +1783,24 @@ class MetDataArray(MetBase):
|
|
|
1784
1783
|
>>> mda.shape
|
|
1785
1784
|
(1440, 721, 1, 1)
|
|
1786
1785
|
|
|
1787
|
-
>>> pprint(mda.to_polygon_feature(iso_value=239.5, precision=2, epsilon=0.
|
|
1788
|
-
{'geometry': {'coordinates': [[[[
|
|
1789
|
-
[
|
|
1790
|
-
[
|
|
1791
|
-
[
|
|
1792
|
-
[
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
[
|
|
1796
|
-
[
|
|
1797
|
-
[
|
|
1786
|
+
>>> pprint(mda.to_polygon_feature(iso_value=239.5, precision=2, epsilon=0.1))
|
|
1787
|
+
{'geometry': {'coordinates': [[[[167.88, -22.5],
|
|
1788
|
+
[167.75, -22.38],
|
|
1789
|
+
[167.62, -22.5],
|
|
1790
|
+
[167.75, -22.62],
|
|
1791
|
+
[167.88, -22.5]]],
|
|
1792
|
+
[[[43.38, -33.5],
|
|
1793
|
+
[43.5, -34.12],
|
|
1794
|
+
[43.62, -33.5],
|
|
1795
|
+
[43.5, -33.38],
|
|
1796
|
+
[43.38, -33.5]]]],
|
|
1798
1797
|
'type': 'MultiPolygon'},
|
|
1799
1798
|
'properties': {},
|
|
1800
1799
|
'type': 'Feature'}
|
|
1801
1800
|
|
|
1802
1801
|
"""
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
warnings.warn(
|
|
1806
|
-
f"The fill_value {fill_value} expected to be less than the iso_value {iso_value}"
|
|
1807
|
-
)
|
|
1808
|
-
|
|
1809
|
-
if depth not in (1, 2):
|
|
1810
|
-
raise ValueError(
|
|
1811
|
-
f"Invalid depth value {depth}. Must be 1 or 2. See docstring for details."
|
|
1812
|
-
)
|
|
1813
|
-
if convex_hull and depth != 1:
|
|
1814
|
-
raise ValueError(f"Set depth=1 to use the 'convex_hull' parameter. Found depth={depth}")
|
|
1802
|
+
if convex_hull and interiors:
|
|
1803
|
+
raise ValueError("Set 'interiors=False' to use the 'convex_hull' parameter.")
|
|
1815
1804
|
|
|
1816
1805
|
arr, altitude = _extract_2d_arr_and_altitude(self, level, time)
|
|
1817
1806
|
if not include_altitude:
|
|
@@ -1825,52 +1814,48 @@ class MetDataArray(MetBase):
|
|
|
1825
1814
|
|
|
1826
1815
|
np.nan_to_num(arr, copy=False, nan=fill_value)
|
|
1827
1816
|
|
|
1828
|
-
# Pad along axes to ensure polygons are closed
|
|
1829
|
-
arr = np.pad(arr, pad_width=1, constant_values=fill_value)
|
|
1830
|
-
|
|
1831
1817
|
# default iso_value
|
|
1832
1818
|
if iso_value is None:
|
|
1833
|
-
iso_value = (np.
|
|
1819
|
+
iso_value = (np.max(arr) + np.min(arr)) / 2
|
|
1834
1820
|
warnings.warn(f"The 'iso_value' parameter was not specified. Using value: {iso_value}")
|
|
1835
1821
|
|
|
1836
1822
|
# We'll get a nice error message if dependencies are not installed
|
|
1837
1823
|
import pycontrails.core.polygon as polygon
|
|
1838
1824
|
|
|
1839
|
-
|
|
1825
|
+
# Convert to nested lists of coordinates for GeoJSON representation
|
|
1826
|
+
longitude: npt.NDArray[np.float_] = self.variables["longitude"].values
|
|
1827
|
+
latitude: npt.NDArray[np.float_] = self.variables["latitude"].values
|
|
1828
|
+
|
|
1829
|
+
mp = polygon.find_multipolygon(
|
|
1840
1830
|
arr,
|
|
1841
1831
|
threshold=iso_value,
|
|
1842
1832
|
min_area=min_area,
|
|
1843
|
-
min_area_to_iterate=min_area_to_iterate,
|
|
1844
1833
|
epsilon=epsilon,
|
|
1845
|
-
|
|
1834
|
+
interiors=interiors,
|
|
1846
1835
|
convex_hull=convex_hull,
|
|
1836
|
+
longitude=longitude,
|
|
1837
|
+
latitude=latitude,
|
|
1838
|
+
precision=precision,
|
|
1847
1839
|
)
|
|
1848
1840
|
|
|
1849
|
-
|
|
1850
|
-
longitude = self.variables["longitude"].values
|
|
1851
|
-
latitude = self.variables["latitude"].values
|
|
1852
|
-
|
|
1853
|
-
multipolygons: list[list[list[list[float]]]] = []
|
|
1854
|
-
for exterior_poly in nc:
|
|
1855
|
-
poly = [
|
|
1856
|
-
polygon.contour_to_lon_lat(p.contour, longitude, latitude, altitude, precision)
|
|
1857
|
-
for p in [exterior_poly, *exterior_poly]
|
|
1858
|
-
]
|
|
1859
|
-
multipolygons.append(poly)
|
|
1860
|
-
|
|
1861
|
-
return {
|
|
1862
|
-
"type": "Feature",
|
|
1863
|
-
"properties": {},
|
|
1864
|
-
"geometry": {"type": "MultiPolygon", "coordinates": multipolygons},
|
|
1865
|
-
}
|
|
1841
|
+
return polygon.multipolygon_to_geojson(mp, altitude, properties)
|
|
1866
1842
|
|
|
1867
|
-
def to_polygon_feature_collection(
|
|
1843
|
+
def to_polygon_feature_collection(
|
|
1844
|
+
self,
|
|
1845
|
+
time: np.datetime64 | datetime | None = None,
|
|
1846
|
+
fill_value: float = 0.0,
|
|
1847
|
+
iso_value: float | None = None,
|
|
1848
|
+
min_area: float = 0.0,
|
|
1849
|
+
epsilon: float = 0.0,
|
|
1850
|
+
precision: int | None = None,
|
|
1851
|
+
interiors: bool = True,
|
|
1852
|
+
convex_hull: bool = False,
|
|
1853
|
+
include_altitude: bool = False,
|
|
1854
|
+
properties: dict[str, Any] | None = None,
|
|
1855
|
+
) -> dict[str, Any]:
|
|
1868
1856
|
"""Create GeoJSON FeatureCollection artifact from spatial array at time slice.
|
|
1869
1857
|
|
|
1870
|
-
|
|
1871
|
-
----------
|
|
1872
|
-
**kwargs : Any
|
|
1873
|
-
Passed into :meth:`to_polygon_feature`.
|
|
1858
|
+
See the :meth:`to_polygon_feature` method for a description of the parameters.
|
|
1874
1859
|
|
|
1875
1860
|
Returns
|
|
1876
1861
|
-------
|
|
@@ -1878,13 +1863,26 @@ class MetDataArray(MetBase):
|
|
|
1878
1863
|
Python representation of GeoJSON FeatureCollection. This dictionary is
|
|
1879
1864
|
comprised of individual GeoJON Features, one per :attr:`self.data["level"]`.
|
|
1880
1865
|
"""
|
|
1866
|
+
base_properties = properties or {}
|
|
1881
1867
|
features = []
|
|
1882
1868
|
for level in self.data["level"]:
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
feature
|
|
1869
|
+
properties = base_properties.copy()
|
|
1870
|
+
properties.update(level=level.item())
|
|
1871
|
+
properties.update({f"level_{k}": v for k, v in self.data["level"].attrs.items()})
|
|
1872
|
+
|
|
1873
|
+
feature = self.to_polygon_feature(
|
|
1874
|
+
level=level,
|
|
1875
|
+
time=time,
|
|
1876
|
+
fill_value=fill_value,
|
|
1877
|
+
iso_value=iso_value,
|
|
1878
|
+
min_area=min_area,
|
|
1879
|
+
epsilon=epsilon,
|
|
1880
|
+
precision=precision,
|
|
1881
|
+
interiors=interiors,
|
|
1882
|
+
convex_hull=convex_hull,
|
|
1883
|
+
include_altitude=include_altitude,
|
|
1884
|
+
properties=properties,
|
|
1885
|
+
)
|
|
1888
1886
|
features.append(feature)
|
|
1889
1887
|
|
|
1890
1888
|
return {
|
|
@@ -2317,6 +2315,8 @@ def _extract_2d_arr_and_altitude(
|
|
|
2317
2315
|
altitude = da["altitude"].values.item() # item not implemented on dask arrays
|
|
2318
2316
|
except KeyError:
|
|
2319
2317
|
altitude = None
|
|
2318
|
+
else:
|
|
2319
|
+
altitude = round(altitude)
|
|
2320
2320
|
|
|
2321
2321
|
return arr, altitude
|
|
2322
2322
|
|