Skip to content

Commit 580d7c4

Browse files
authored
v0.1.5
## [0.1.5] - 2024-06-05 ### Fixed - Better management of cloud mask and error messages. - `groupby_date` is now performed after processing the cloudmask in order to ensure a better compatibility.
2 parents 9094172 + 06ddc2a commit 580d7c4

File tree

10 files changed

+87
-22
lines changed

10 files changed

+87
-22
lines changed

.github/workflows/pytest-dev.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ jobs:
1111
os:
1212
- ubuntu-latest
1313
python-version:
14-
- "3.10"
1514
- "3.11"
1615
- "3.12"
1716
runs-on: ${{ matrix.os }}

.github/workflows/pytest-prod.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ jobs:
1111
os:
1212
- ubuntu-latest
1313
- windows-latest
14+
- macos-latest
1415
python-version:
15-
- "3.10"
1616
- "3.11"
1717
- "3.12"
1818
runs-on: ${{ matrix.os }}

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.1.5] - 2024-06-05
8+
9+
### Fixed
10+
11+
- Better management of cloud mask and error messages.
12+
- `groupby_date` is now performed after processing the cloudmask in order to ensure a better compatibility.
13+
714
## [0.1.4] - 2024-05-23
815

916
### Fixed

earthdaily/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
# to hide warnings from rioxarray or nano seconds conversion
66
warnings.filterwarnings("ignore")
77

8-
__version__ = "0.1.4"
8+
__version__ = "0.1.5"

earthdaily/accessor/__init__.py

+26
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,29 @@ def whittaker(
117117
max_iter=max_iter,
118118
)["index"]
119119

120+
def sel_nearest_dates(
121+
self,
122+
target: (xr.Dataset, xr.DataArray),
123+
max_delta: int = 0,
124+
method: str = "nearest",
125+
return_target: bool = False,
126+
):
127+
src_time = self._obj.sel(time=target.time.dt.date, method=method).time.dt.date
128+
target_time = target.time.dt.date
129+
pos = np.abs(src_time.data - target_time.data)
130+
pos = [
131+
src_time.isel(time=i).time.values
132+
for i, j in enumerate(pos)
133+
if j.days <= max_delta
134+
]
135+
pos = np.unique(pos)
136+
if return_target:
137+
method_convert = {"bfill": "ffill", "ffill": "bfill", "nearest": "nearest"}
138+
return self._obj.sel(time=pos), target.sel(
139+
time=pos, method=method_convert[method]
140+
)
141+
return self._obj.sel(time=pos)
142+
120143

121144
@xr.register_dataset_accessor("ed")
122145
class EarthDailyAccessorDataset:
@@ -199,6 +222,9 @@ def _auto_mapper(self):
199222
"rededge1": "RE1",
200223
"rededge2": "RE2",
201224
"rededge3": "RE3",
225+
"rededge70": "RE1",
226+
"rededge74": "RE2",
227+
"rededge78": "RE3",
202228
"nir": "N",
203229
"nir08": "N2",
204230
"watervapor": "WV",

earthdaily/earthdatastore/__init__.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,8 @@ def datacube(
641641

642642
if mask_with:
643643
if mask_with not in mask._available_masks:
644-
logging.log(
645-
level=logging.INFO,
646-
msg=f"Specified mask '{mask_with}' is not available. Currently available masks provider are : {mask._available_masks}",
644+
raise NotImplementedError(
645+
f"Specified mask '{mask_with}' is not available. Available masks providers are : {mask._available_masks}"
647646
)
648647

649648
elif mask_with == "ag_cloud_mask":
@@ -686,6 +685,10 @@ def datacube(
686685
"No cross calibration coefficient available for the specified collections."
687686
)
688687

688+
groupby_date_sensor_cube = groupby_date
689+
if mask_with and groupby_date:
690+
groupby_date_sensor_cube = None
691+
689692
xr_datacube = datacube(
690693
items,
691694
intersects=intersects,
@@ -694,11 +697,10 @@ def datacube(
694697
common_band_names=common_band_names,
695698
cross_calibration_items=xcal_items,
696699
properties=properties,
697-
groupby_date=groupby_date,
700+
groupby_date=groupby_date_sensor_cube,
698701
**kwargs,
699702
)
700703
if mask_with:
701-
groupby_date_mask = "max" if isinstance(groupby_date, str) else None
702704
if clear_cover and mask_statistics is False:
703705
mask_statistics = True
704706
mask_kwargs = dict(mask_statistics=mask_statistics)
@@ -708,7 +710,7 @@ def datacube(
708710
acm_items,
709711
intersects=intersects,
710712
bbox=bbox,
711-
groupby_date=groupby_date_mask,
713+
groupby_date=None,
712714
geobox=xr_datacube.odc.geobox
713715
if hasattr(xr_datacube, "odc")
714716
else None,
@@ -728,7 +730,7 @@ def datacube(
728730

729731
clouds_datacube = datacube(
730732
items,
731-
groupby_date=groupby_date_mask,
733+
groupby_date=None,
732734
intersects=intersects,
733735
bbox=bbox,
734736
assets=[mask_assets],
@@ -750,6 +752,29 @@ def datacube(
750752

751753
if clear_cover:
752754
xr_datacube = mask.filter_clear_cover(xr_datacube, clear_cover)
755+
if groupby_date and mask_with:
756+
grouped_coords = []
757+
# for coords using only time dimensions like clear_pixels, keeping the max
758+
for coord in xr_datacube.coords:
759+
if coord in ("x", "y", "time"):
760+
continue
761+
if (
762+
len(xr_datacube[coord].dims) == 1
763+
and xr_datacube[coord].dims[0] == "time"
764+
):
765+
grouped_coords.append(
766+
xr_datacube[coord]
767+
.groupby("time.date", squeeze=True)
768+
.max()
769+
.rename(dict(date="time"))
770+
)
771+
772+
xr_datacube = xr_datacube.groupby("time.date", restore_coord_dims=True)
773+
xr_datacube = getattr(xr_datacube, groupby_date)().rename(dict(date="time"))
774+
for grouped_coord in grouped_coords:
775+
xr_datacube = xr_datacube.assign_coords(
776+
{grouped_coord.name: grouped_coord}
777+
)
753778
return xr_datacube
754779

755780
def _update_search_for_assets(self, assets):

earthdaily/earthdatastore/cube_utils/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ def _impl(self, *args, **kwargs):
2323
mask_with = kwargs.get("mask_with", None)
2424
if isinstance(mask_with, list):
2525
kwargs.pop("mask_with")
26-
for mask in mask_with:
26+
for idx, mask in enumerate(mask_with):
2727
try:
2828
datacube = method(self, mask_with=mask, *args, **kwargs)
2929
break
30-
except Warning:
30+
except Warning as E:
3131
# if warning about no items for ag_cloud_mask for example
32-
continue
32+
if idx + 1 == len(mask_with):
33+
raise E
3334
else:
3435
datacube = method(self, *args, **kwargs)
3536
return datacube

earthdaily/earthdatastore/cube_utils/geometry_manager.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,21 @@ def _unknow_geometry_to_geodataframe(self, geometry):
5151
return gpd.read_file(geometry, driver="GeoJson", crs="EPSG:4326")
5252
except:
5353
try:
54-
return gpd.GeoDataFrame.from_features(geometry, crs="EPSG:4326")
54+
return gpd.read_file(
55+
json.dumps(geometry), driver="GeoJson", crs="EPSG:4326"
56+
)
5557
except:
56-
if "type" in geometry:
57-
geom = shapely.__dict__[geometry["type"]](
58-
[geometry["coordinates"][0]]
59-
)
60-
return gpd.GeoDataFrame(geometry=[geom], crs="EPSG:4326")
58+
pass
59+
60+
try:
61+
return gpd.GeoDataFrame.from_features(geometry, crs="EPSG:4326")
62+
except:
63+
if "type" in geometry:
64+
geom = shapely.__dict__[geometry["type"]](
65+
[geometry["coordinates"][0]]
66+
)
67+
return gpd.GeoDataFrame(geometry=[geom], crs="EPSG:4326")
68+
6169
elif isinstance(geometry, gpd.GeoSeries):
6270
self.input_type = "GeoSeries"
6371

earthdaily/earthdatastore/mask/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ def compute_clear_coverage(
162162
)
163163
}
164164
)
165-
# self._obj = self._obj.reset_coords(names=['clear_pixels','clear_percent'])
166165

167166
return self._obj
168167

examples/field_evolution.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
pivot_cube = eds.datacube(
3333
"sentinel-2-l2a",
3434
intersects=pivot,
35-
datetime=["2022-07-01", "2022-08-31"],
35+
datetime=["2023-07-01","2023-07-10"],
3636
assets=["red", "green", "blue"],
37-
mask_with="ag_cloud_mask",
37+
mask_with="native",
3838
clear_cover=50,
3939
)
4040

0 commit comments

Comments
 (0)