Skip to content

Commit

Permalink
Merge pull request #2827 from BENR0/fix_to_xr_dataset_merge_error
Browse files Browse the repository at this point in the history
  • Loading branch information
djhoese authored Jan 21, 2025
2 parents d96b46f + 43f8ce9 commit 9a40616
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
8 changes: 6 additions & 2 deletions satpy/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -1079,12 +1079,16 @@ def to_hvplot(self, datasets=None, *args, **kwargs):



def to_xarray_dataset(self, datasets=None):
def to_xarray_dataset(self, datasets=None, compat="minimal"):
"""Merge all xr.DataArrays of a scene to a xr.DataSet.
Parameters:
datasets (list):
List of products to include in the :class:`xarray.Dataset`
compat (str):
How to compare variables with the same name for conflicts.
See :func:`xarray.merge` for possible options. Defaults to
"minimal" which drops conflicting variables.
Returns: :class:`xarray.Dataset`
Expand All @@ -1100,7 +1104,7 @@ def to_xarray_dataset(self, datasets=None):
mdata = combine_metadata(*tuple(i.attrs for i in dataarrays))
if mdata.get("area") is None or not isinstance(mdata["area"], SwathDefinition):
# either don't know what the area is or we have an AreaDefinition
ds = xr.merge(ds_dict.values())
ds = xr.merge(ds_dict.values(), compat=compat)
else:
# we have a swath definition and should use lon/lat values
lons, lats = mdata["area"].get_lonlats()
Expand Down
47 changes: 39 additions & 8 deletions satpy/tests/scene_tests/test_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"""Unit tests for Scene conversion functionality."""

import datetime as dt
from datetime import datetime

import numpy as np
import pytest
import xarray as xr
from dask import array as da
Expand Down Expand Up @@ -51,14 +53,6 @@ def test_serialization_with_readers_and_data_arr(self):
class TestSceneConversions:
"""Test Scene conversion to geoviews, xarray, etc."""

def test_to_xarray_dataset_with_empty_scene(self):
"""Test converting empty Scene to xarray dataset."""
scn = Scene()
xrds = scn.to_xarray_dataset()
assert isinstance(xrds, xr.Dataset)
assert len(xrds.variables) == 0
assert len(xrds.coords) == 0

def test_geoviews_basic_with_area(self):
"""Test converting a Scene to geoviews with an AreaDefinition."""
from pyresample.geometry import AreaDefinition
Expand Down Expand Up @@ -164,6 +158,43 @@ def single_area_scn(self):
scn["var1"] = data_array
return scn

def test_to_xarray_dataset_with_conflicting_variables(self):
"""Test converting Scene with DataArrays with conflicting variables.
E.g. "acq_time" in the seviri_l1b_nc reader
"""
from pyresample.geometry import AreaDefinition
area = AreaDefinition("test", "test", "test",
{"proj": "geos", "lon_0": -95.5, "h": 35786023.0},
2, 2, [-200, -200, 200, 200])
scn = Scene()

acq_time_1 = ("y", [np.datetime64("1958-01-02 00:00:01"),
np.datetime64("1958-01-02 00:00:02")])
ds = xr.DataArray(da.zeros((2, 2), chunks=-1), dims=("y", "x"),
attrs={"start_time": datetime(2018, 1, 1), "area": area})
ds["acq_time"] = acq_time_1

scn["ds1"] = ds

acq_time_2 = ("y", [np.datetime64("1958-02-02 00:00:01"),
np.datetime64("1958-02-02 00:00:02")])
ds2 = ds.copy()
ds2["acq_time"] = acq_time_2

scn["ds2"] = ds2

# drop case (compat="minimal")
xrds = scn.to_xarray_dataset()
assert isinstance(xrds, xr.Dataset)
assert "acq_time" not in xrds.coords

# override: pick variable from first dataset
xrds = scn.to_xarray_dataset(datasets=["ds1", "ds2"], compat="override")
assert isinstance(xrds, xr.Dataset)
assert "acq_time" in xrds.coords
xr.testing.assert_equal(xrds["acq_time"], ds["acq_time"])

@pytest.fixture
def multi_area_scn(self):
"""Define Scene with multiple area."""
Expand Down

0 comments on commit 9a40616

Please sign in to comment.