Skip to content

Commit

Permalink
ENH: Allow to use bands IDs, names and common name added to mapped na…
Browse files Browse the repository at this point in the history
…mes when trying to load a spectral band (#111)
  • Loading branch information
remi-braun committed Oct 30, 2023
1 parent ee35508 commit e65c717
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- **BREAKING CHANGES: Rename `utils.stack_dict` to `utils.stack` since we are stacking datasets and not dict anymore.**
- **BREAKING CHANGES: Band ID for Sentinel-3 OLCI are now int instead of band names (i.e. `7` instead of `Oa07`. The names don't change).**
- **ENH: Allow to use bands IDs, names and common name added to mapped names when trying to load a spectral band. ([#111](https://github.com/sertit/eoreader/issues/111)**
- CI: Update pre-commit hooks
- DEPS: Remove as many mention as possible to `cloudpathlib`
- GITHUB: Update bug template
Expand Down
23 changes: 23 additions & 0 deletions CI/SCRIPTS/test_bands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
""" Script testing EOReader bands """
from CI.SCRIPTS.scripts_utils import READER, opt_path
from eoreader.bands import BLUE, YELLOW


def test_bands_s3_olci():
"""Test EOReader bands for Sentinel-3 OLCI"""
prod_path = opt_path().joinpath(
"S3A_OL_1_EFR____20191215T105023_20191215T105323_20191216T153115_0179_052_322_2160_LN1_O_NT_002.SEN3.zip"
)
prod = READER.open(prod_path)

# Check all these bands are the same
assert list(set(prod.to_band(["Oa07", YELLOW, "YELLOW"]))) == [YELLOW]


def test_bands_l8():
"""Test EOReader bands for Landsat-8"""
prod_path = opt_path().joinpath("LC08_L1GT_023030_20200518_20200527_01_T2")
prod = READER.open(prod_path)

# Check all these bands are the same
assert list(set(prod.to_band(["BLUE", "Blue", 2, BLUE, "2"]))) == [BLUE]
6 changes: 6 additions & 0 deletions docs/main_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ It can load satellite bands, index, DEM bands and cloud bands according to this
:alt: load_workflow
```

Bands can be called with their name, ID or mapped name.
For example, for Sentinel-3 OLCI you can use `7`, `Oa07` or `YELLOW`. For Landsat-8, you can use `BLUE` or `2`.

```{note}
For now, EOReader **always** loads bands with projected CRS (in UTM).
Expand Down Expand Up @@ -158,6 +161,9 @@ stack = prod.stack(
)
```

Bands can be called with their name, ID or mapped name.
For example, for Sentinel-3 OLCI you can use `7`, `Oa07` or `YELLOW`. For Landsat-8, you can use `BLUE` or `2`.

Some additional arguments can be passed to this function, please see {meth}`~eoreader.keywords` for the list.
- Methods to clean optical bands are best
described [here](https://eoreader.readthedocs.io/en/latest/notebooks/optical_cleaning_methods.html),
Expand Down
5 changes: 4 additions & 1 deletion docs/notebooks/base.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@
"source": [
"## Load\n",
"\n",
"Just load easily some bands and index. The `load` function outputs a dictionary of `xarray.DataArray`."
"Just load easily some bands and index. The `load` function outputs a dictionary of `xarray.DataArray`.\n",
"\n",
"The bands can be called by their ID, name or mapped name.\n",
"For example, for Sentinel-3 OLCI you can use `7`, `Oa07` or `YELLOW`. For Landsat-8, you can use `BLUE` or `2`."
]
},
{
Expand Down
31 changes: 28 additions & 3 deletions eoreader/products/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ def load(
)

# Check if all bands are valid
bands = to_band(bands)
bands = self.to_band(bands)

for band in bands:
assert self.has_band(band), f"{self.name} has not a {to_str(band)[0]} band."
Expand Down Expand Up @@ -1196,7 +1196,7 @@ def has_band(self, band: Union[BandNames, str]) -> bool:
Returns:
bool: True if the products has the specified band
"""
band = to_band(band)[0]
band = self.to_band(band)[0]

if is_dem(band):
if self.sensor_type == SensorType.SAR and band == HILLSHADE:
Expand Down Expand Up @@ -1654,7 +1654,7 @@ def stack(
else:
os.makedirs(str(stack_path.parent), exist_ok=True)

bands = to_band(bands)
bands = self.to_band(bands)

# Create the analysis stack
band_xds = self.load(bands, pixel_size=pixel_size, size=size, **kwargs)
Expand Down Expand Up @@ -1998,3 +1998,28 @@ def get_orbit_direction(self) -> OrbitDirection:
OrbitDirection: Orbit direction (ASCENDING/DESCENDING)
"""
raise NotImplementedError

def to_band(self, raw_bands: Union[list, BandNames, str, int]) -> list:
bands = []
for raw_band in raw_bands:
try:
bands += to_band(raw_band)
except InvalidTypeError:
found = False
for band_name, band in self.bands.items():
if band is not None and str(raw_band) in [
str(band.id),
band.name,
band.common_name,
band.eoreader_name,
]:
bands.append(band_name)
found = True
break

if not found:
raise InvalidTypeError(
f"Couldn't find any band in {self.condensed_name} that corresponds to {raw_band}."
)

return bands

0 comments on commit e65c717

Please sign in to comment.