Skip to content

Commit

Permalink
Merge branch '0.20.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-braun committed Apr 12, 2023
2 parents 18cb5f2 + 466934d commit 4bde150
Show file tree
Hide file tree
Showing 58 changed files with 855 additions and 861 deletions.
13 changes: 13 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Release History

## 0.20.0 (2023-MM-DD)

### Breaking Changes

- **BREAKING CHANGES: Switching from `resolution` to `pixel_size` to avoid confusion about the definitions (especially for SAR data)** ([#82](https://github.com/sertit/eoreader/issues/82))

### Other

- INTERNAL: Better management of logs for deprecation warnings
- INTERNAL: Refactoring `simplify_footprint` in `sertit` library
- DEPS: Pin sertit to 1.25.0

## 0.19.4 (2023-04-12)

### Bug Fixes
Expand All @@ -17,6 +29,7 @@

### Bug Fixes

- OPTIM: Don't recompute stacks if already existing on disk
- FIX: Fixing `Custom Stacks` when specifying `datetime=None` on creation
- FIX: Fix regression for multi-swath DGM CSK data (huge region) ([#78](https://github.com/sertit/eoreader/issues/78))
- FIX: Fix calibration issues with CSK HR data (using fallback GPT graph by default)
Expand Down
14 changes: 7 additions & 7 deletions CI/SCRIPTS/test_broken_s2.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@dask_env
def test_broken_s2():
"""Function testing the support of broken Sentinel-2 constellation"""
res = 10.0 * 100
pixel_size = 10.0 * 100

# ----------- Broken MTD -----------
broken_mtd = broken_s2_path().joinpath(
Expand All @@ -30,8 +30,8 @@ def test_broken_s2():
LOGGER.info(broken_mtd_prod)
LOGGER.info(broken_mtd_prod.bands)

broken_mtd_prod.load(RED, resolution=res, clean_optical="clean")
broken_mtd_prod.load(NIR, resolution=res, clean_optical="nodata")
broken_mtd_prod.load(RED, pixel_size=pixel_size, clean_optical="clean")
broken_mtd_prod.load(NIR, pixel_size=pixel_size, clean_optical="nodata")

# Invalid tests
with pytest.raises(InvalidProductError):
Expand All @@ -52,20 +52,20 @@ def test_broken_s2():
broken_detfoo_prod.footprint()

broken_detfoo_prod.load(
RED, resolution=res, clean_optical="clean"
RED, pixel_size=pixel_size, clean_optical="clean"
) # Not corrupted band

# Invalid tests
# WARNING: This doesn't fail anymore!
# with pytest.raises(InvalidProductError):
# broken_detfoo_prod.load(
# NIR, resolution=res, clean_optical="nodata"
# NIR, pixel_size=pixel_size, clean_optical="nodata"
# ) # Corrupted band

# ----------- Broken MSK -----------
broken_msk = broken_s2_path().joinpath(
"S2B_MSIL2A_20220201T104149_N0400_R008_T31UFP_20220201T122857.SAFE"
)
broken_msk_prod = READER.open(broken_msk)
broken_msk_prod.load(RED, resolution=res, clean_optical="clean")
broken_mtd_prod.load(NIR, resolution=res, clean_optical="nodata")
broken_msk_prod.load(RED, pixel_size=pixel_size, clean_optical="clean")
broken_mtd_prod.load(NIR, pixel_size=pixel_size, clean_optical="nodata")
16 changes: 8 additions & 8 deletions CI/SCRIPTS/test_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_custom_optical():
sensor_type=SensorType.OPTICAL,
constellation="WV02",
instrument="WW110",
resolution=2.0,
pixel_size=2.0,
product_type="Ortho",
band_map={BLUE: 1, GREEN: 2, RED: 3, NIR: 4, SWIR_1: 5},
)
Expand Down Expand Up @@ -118,7 +118,7 @@ def test_custom_optical():
extent_some = prod_some.extent()
footprint_some = prod_some.footprint()
crs_some = prod_some.crs()
bands = prod_some.load([HILLSHADE], resolution=200.0)
bands = prod_some.load([HILLSHADE], pixel_size=200.0)

# Check attributes
assert bands[HILLSHADE].attrs["long_name"] == "HILLSHADE"
Expand Down Expand Up @@ -160,15 +160,15 @@ def test_custom_sar():
datetime="20210827T162210",
constellation="ICEYE",
instrument="SAR X-band",
resolution=6.0,
pixel_size=6.0,
product_type="GRD",
band_map={VV: 1, VV_DSPK: 2},
)
LOGGER.info(prod_sar)
extent_sar = prod_sar.extent()
footprint_sar = prod_sar.footprint()
crs_sar = prod_sar.crs()
stack_sar = prod_sar.stack([VV, VV_DSPK], prod_sar.resolution * 10)
stack_sar = prod_sar.stack([VV, VV_DSPK], prod_sar.pixel_size * 10)

# Errors
with pytest.raises(AssertionError):
Expand All @@ -195,13 +195,13 @@ def test_custom_sar():
product_type=None,
instrument=None,
datetime=None,
resolution=6.0,
pixel_size=6.0,
)
LOGGER.info(prod_wtf)
extent_wtf = prod_wtf.extent()
footprint_wtf = prod_wtf.footprint()
crs_wtf = prod_wtf.crs()
stack_wtf = prod_wtf.stack([HH, RH], prod_wtf.resolution * 10)
stack_wtf = prod_wtf.stack([HH, RH], prod_wtf.pixel_size * 10)

ci.assert_geom_equal(extent_sar, extent_wtf)
ci.assert_geom_equal(footprint_sar, footprint_wtf)
Expand All @@ -223,7 +223,7 @@ def test_custom_wgs84():
name="SPOT6_WGS84",
datetime="20181218T090308",
constellation="SPOT6",
resolution=1.5 * 15,
pixel_size=1.5 * 15,
instrument="NAOMI",
product_type="ORT",
band_map={RED: 1, GREEN: 2, BLUE: 3, NIR: 4},
Expand All @@ -247,7 +247,7 @@ def test_custom_wgs84():
assert root.findtext("datetime") == "2018-12-18T09:03:08"
assert root.findtext("sensor_type") == "Optical"
assert root.findtext("constellation") == "Spot-6"
assert root.findtext("resolution") == str(1.5 * 15)
assert root.findtext("pixel_size") == str(1.5 * 15)
assert root.findtext("product_type") == "ORT"
assert root.findtext("band_map") == "{'BLUE': 3, 'GREEN': 2, 'RED': 1, 'NIR': 4}"
assert root.findtext("sun_azimuth") == "None"
Expand Down
17 changes: 11 additions & 6 deletions CI/SCRIPTS/test_end_to_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@
VV_DSPK,
Oa01,
)
from eoreader.env_vars import DEM_PATH, S3_DB_URL_ROOT, SAR_DEF_RES, TEST_USING_S3_DB
from eoreader.env_vars import (
DEM_PATH,
S3_DB_URL_ROOT,
SAR_DEF_PIXEL_SIZE,
TEST_USING_S3_DB,
)
from eoreader.products.product import Product, SensorType
from eoreader.reader import CheckMethod

Expand Down Expand Up @@ -174,12 +179,12 @@ def _test_core(
is_zip = "_ZIP" if prod.is_archived else ""
prod.output = os.path.join(output, f"{prod.condensed_name}{is_zip}")

# Manage S3 resolution to speed up processes
# Manage S3 pixel_size to speed up processes
if prod.sensor_type == SensorType.SAR:
res = 1000.0
os.environ[SAR_DEF_RES] = str(res)
pixel_size = 1000.0
os.environ[SAR_DEF_PIXEL_SIZE] = str(pixel_size)
else:
res = prod.resolution * 50
pixel_size = prod.pixel_size * 50

# BAND TESTS
LOGGER.info("Checking load and stack")
Expand All @@ -195,7 +200,7 @@ def _test_core(
curr_path = os.path.join(tmp_dir, f"{prod.condensed_name}_stack.tif")
stack = prod.stack(
stack_bands,
resolution=res,
pixel_size=pixel_size,
stack_path=curr_path,
clean_optical="clean",
**kwargs,
Expand Down
2 changes: 1 addition & 1 deletion CI/SCRIPTS/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def test_index():
idx_list = [
idx for idx in spyndex_list + get_eoreader_indices() if prod.has_band(idx)
]
idx = prod.load(idx_list, resolution=RES)
idx = prod.load(idx_list, pixel_size=RES)

for idx_name, idx_arr in idx.items():
LOGGER.info("Write and compare: %s", idx_name)
Expand Down
10 changes: 5 additions & 5 deletions CI/SCRIPTS/test_others.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def test_products():
stack_path = os.path.join(tmp_dir, "stack.tif")
stack = prod1.stack(
BLUE,
resolution=prod1.resolution * 100,
pixel_size=prod1.pixel_size * 100,
save_as_int=True,
stack_path=stack_path,
)
Expand Down Expand Up @@ -278,10 +278,10 @@ def test_dems_https():
# Loading same DEM from two different sources (one hosted locally and the other hosted on S3 compatible storage)
with tempenv.TemporaryEnvironment({DEM_PATH: local_path}): # Local DEM
dem_local = prod.load(
[DEM], resolution=30
[DEM], pixel_size=30
) # Loading same DEM from two different sources (one hosted locally and the other hosted on S3 compatible storage)
with tempenv.TemporaryEnvironment({DEM_PATH: remote_path}): # Remote DEM
dem_remote = prod.load([DEM], resolution=30)
dem_remote = prod.load([DEM], pixel_size=30)

xr.testing.assert_equal(dem_local[DEM], dem_remote[DEM])

Expand Down Expand Up @@ -309,10 +309,10 @@ def test_dems_S3():
# Loading same DEM from two different sources (one hosted locally and the other hosted on S3 compatible storage)
with tempenv.TemporaryEnvironment({DEM_PATH: local_path}): # Local DEM
dem_local = prod.load(
[DEM], resolution=30
[DEM], pixel_size=30
) # Loading same DEM from two different sources (one hosted locally and the other hosted on S3 compatible storage)
with tempenv.TemporaryEnvironment({DEM_PATH: s3_path}): # S3 DEM
dem_s3 = prod.load([DEM], resolution=30)
dem_s3 = prod.load([DEM], pixel_size=30)

xr.testing.assert_equal(dem_local[DEM], dem_s3[DEM])

Expand Down
20 changes: 10 additions & 10 deletions CI/SCRIPTS/test_satellites.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
CI_EOREADER_BAND_FOLDER,
DEM_PATH,
S3_DB_URL_ROOT,
SAR_DEF_RES,
SAR_DEF_PIXEL_SIZE,
TEST_USING_S3_DB,
)
from eoreader.keywords import SLSTR_RAD_ADJUST
Expand Down Expand Up @@ -200,14 +200,14 @@ def _test_core(
get_ci_data_dir().joinpath(prod.condensed_name)
)

# Manage S3 resolution to speed up processes
# Manage S3 pixel_size to speed up processes
if prod.sensor_type == SensorType.SAR:
res = 1000.0
os.environ[SAR_DEF_RES] = str(res)
pixel_size = 1000.0
os.environ[SAR_DEF_PIXEL_SIZE] = str(pixel_size)
elif prod.constellation_id in ["S2", "S2_THEIA"]:
res = 20.0 * 50 # Legacy
pixel_size = 20.0 * 50 # Legacy
else:
res = prod.resolution * 50
pixel_size = prod.pixel_size * 50

# Extent
LOGGER.info("Checking extent")
Expand Down Expand Up @@ -281,12 +281,12 @@ def _test_core(
# Check that band loaded 2 times gives the same results (disregarding float uncertainties)
assert prod.load([]) == {}
band_arr_raw = prod.load(
first_band.value, resolution=res, clean_optical="raw"
first_band.value, pixel_size=pixel_size, clean_optical="raw"
)[first_band]
band_arr1 = prod.load(
first_band, resolution=res, clean_optical="nodata"
first_band, pixel_size=pixel_size, clean_optical="nodata"
)[first_band]
band_arr2 = prod.load(first_band, resolution=res)[first_band]
band_arr2 = prod.load(first_band, pixel_size=pixel_size)[first_band]
np.testing.assert_array_almost_equal(band_arr1, band_arr2)
ci.assert_val(band_arr_raw.dtype, np.float32, "band_arr_raw dtype")
ci.assert_val(band_arr1.dtype, np.float32, "band_arr1 dtype")
Expand All @@ -302,7 +302,7 @@ def _test_core(
curr_path = os.path.join(tmp_dir, f"{prod.condensed_name}_stack.tif")
stack = prod.stack(
stack_bands,
resolution=res,
pixel_size=pixel_size,
stack_path=curr_path,
clean_optical="clean",
**kwargs,
Expand Down
2 changes: 1 addition & 1 deletion CI/SCRIPTS/test_stac.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def _test_core(
f"{CONSTELLATION} (item.properties)",
)
compare(
item.properties[GSD], prod.resolution, f"{GSD} (item.properties)"
item.properties[GSD], prod.pixel_size, f"{GSD} (item.properties)"
)
compare(
item.properties[DATETIME],
Expand Down
17 changes: 11 additions & 6 deletions CI/SCRIPTS_SNAP/test_all_sat_end_to_end_on_disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@
VV_DSPK,
Oa01,
)
from eoreader.env_vars import DEM_PATH, S3_DB_URL_ROOT, SAR_DEF_RES, TEST_USING_S3_DB
from eoreader.env_vars import (
DEM_PATH,
S3_DB_URL_ROOT,
SAR_DEF_PIXEL_SIZE,
TEST_USING_S3_DB,
)
from eoreader.keywords import SLSTR_RAD_ADJUST
from eoreader.products import S2Product, SlstrRadAdjust
from eoreader.products.product import Product, SensorType
Expand Down Expand Up @@ -200,12 +205,12 @@ def _test_core(
is_zip = "_ZIP" if prod.is_archived else ""
prod.output = os.path.join(output, f"{prod.condensed_name}{is_zip}")

# Manage S3 resolution to speed up processes
# Manage S3 pixel_size to speed up processes
if prod.sensor_type == SensorType.SAR:
res = 1000.0
os.environ[SAR_DEF_RES] = str(res)
pixel_size = 1000.0
os.environ[SAR_DEF_PIXEL_SIZE] = str(pixel_size)
else:
res = prod.resolution * 50
pixel_size = prod.pixel_size * 50

# BAND TESTS
LOGGER.info("Checking load and stack")
Expand All @@ -221,7 +226,7 @@ def _test_core(
curr_path = os.path.join(tmp_dir, f"{prod.condensed_name}_stack.tif")
stack = prod.stack(
stack_bands,
resolution=res,
pixel_size=pixel_size,
stack_path=curr_path,
clean_optical="clean",
**kwargs,
Expand Down
4 changes: 2 additions & 2 deletions docs/custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you know them, it is best to give **EOReader** all the data you know about yo
be used
- `constellation`: product constellation. If not provided, `CUSTOM` will be set. Either a string of a `Constellation` enum.
- `product_type`: product type. If not provided, `CUSTOM` will be set.
- `resolution`: product default resolution. If not provided, the stack resolution will be used.
- `pixel_size`: product default pixel size. If not provided, the stack pixel size will be used.

For optical products, two additional keyword can be set to compute the hillshade band:

Expand All @@ -60,7 +60,7 @@ custom_prod = Reader().open(
sensor_type="OPTICAL",
constellation="WV02",
product_type="Ortho",
resolution=2.0,
pixel_size=2.0,
sun_azimuth=10.0,
sun_zenith=20.0,
band_map={
Expand Down
4 changes: 4 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Sentinel-1 or other SAR constellations may fail to load KML extent files.
The cause is unknown, but a workaround based on `ogr2ogr` has been written.
Please be sure to have `ogr2ogr` (and other `GDAL` scripts available in your PATH)

For example, if you downloaded QGIS on Windows, you could simply put in your PATH:
![qgis](https://zupimages.net/up/23/13/njvv.png)
All GDAL scripts, exe, DLL, etc. are stored in the `bin` folder.

## SNAP

> ⚠ Be sure to use SNAP 8.0 or more, and please verify that your software is up-to-date.
Expand Down
8 changes: 4 additions & 4 deletions docs/main_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ ok_bands = to_str([band for band in band_list if prod.has_band(band)])
# Sentinel-2 cannot produce satellite band TIR_1 and cloud band SHADOWS

# Load bands
# if resolution is not specified -> load at default resolution (10.0 m for S2 data)
bands = prod.load(ok_bands, resolution=20.)
# if pixel_size is not specified -> load at default pixel_size (10.0 m for S2 data)
bands = prod.load(ok_bands, pixel_size=20.)
# NOTE: every array that comes out `load` are collocated, which isn't the case if you load arrays separately
# (important for DEM data as they may have different grids)
```
Expand Down Expand Up @@ -143,8 +143,8 @@ If the same band is asked several time, its order will be the one of the last de
```python
# Create a stack with the previous OK bands
stack = prod.stack(
ok_bands,
resolution=300.,
ok_bands,
pixel_size=300.,
stack_path=os.path.join(prod.output, "stack.tif")
)
```
Expand Down
6 changes: 3 additions & 3 deletions docs/notebooks/SAR.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,8 @@
}
],
"source": [
"# Load those bands as a dict of xarray.DataArray, with a 20m resolution\n",
"band_dict = prod.load(ok_bands, resolution=20.)\n",
"# Load those bands as a dict of xarray.DataArray, with a 20m pixel size\n",
"band_dict = prod.load(ok_bands, pixel_size=20.)\n",
"band_dict[HH]"
]
},
Expand All @@ -728,7 +728,7 @@
"from eoreader.keywords import SAR_INTERP_NA\n",
"band_dict = prod.load(\n",
" ok_bands, \n",
" resolution=20., \n",
" pixel_size=20.,\n",
" **{SAR_INTERP_NA: True}\n",
")\n",
"```"
Expand Down
Loading

0 comments on commit 4bde150

Please sign in to comment.