Skip to content

Commit d4b95d3

Browse files
committed
INTERNAL: Rationalize band paths and filename functions (still early work) #31
1 parent c796b77 commit d4b95d3

16 files changed

+259
-267
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
- FIX: Fix toa radiance to toa reflectance computation for VHR data
3535
- FIX: Save Cosmo quicklooks as PNG instead of GeoTiffs as they are not georeferenced
3636
- FIX: Fix `to_str` function with `as_list=False`
37+
- INTERNAL: Rationalize band paths and filename functions (still early work) ([#31](https://github.com/sertit/eoreader/issues/31))
3738
- DOC: Add documentation on how EOReader can improve your data handling ([#108](https://github.com/sertit/eoreader/issues/108))
3839
- DEPS: Add `ephem` for computing earth-sun distance (according to Maxar's method from docs)
3940

ci/weekly/test_satellites.py

+27-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import numpy as np
1010
import pytest
11+
import tempenv
1112
import xarray as xr
1213
from lxml import etree
1314
from rasterio.windows import Window
@@ -43,7 +44,7 @@
4344
VV,
4445
VV_DSPK,
4546
)
46-
from eoreader.env_vars import CI_EOREADER_BAND_FOLDER
47+
from eoreader.env_vars import CI_EOREADER_BAND_FOLDER, SAR_DEF_PIXEL_SIZE
4748
from eoreader.keywords import SLSTR_RAD_ADJUST
4849
from eoreader.products import Product, S2Product, SensorType, SlstrRadAdjust
4950
from eoreader.products.product import OrbitDirection
@@ -139,33 +140,35 @@ def check_load(prod: Product, first_band) -> None:
139140
# Check loading 0 bands
140141
assert len(prod.load([])) == 0
141142

142-
# Load with the raw process
143-
band_arr_raw = prod.load(
144-
first_band.value,
145-
window=Window(col_off=0, row_off=0, width=100, height=100),
146-
clean_optical="raw",
147-
)[first_band]
143+
# Don't orthorectify with a window to 1000 m
144+
with tempenv.TemporaryEnvironment({SAR_DEF_PIXEL_SIZE: "0"}):
145+
# Load with the raw process
146+
band_arr_raw = prod.load(
147+
first_band.value,
148+
window=Window(col_off=0, row_off=0, width=100, height=100),
149+
clean_optical="raw",
150+
)[first_band]
148151

149-
# Check that band loaded 2 times gives the same results (disregarding float uncertainties)
150-
band_arr1 = prod.load(
151-
first_band,
152-
window=Window(col_off=0, row_off=0, width=100, height=100),
153-
clean_optical="nodata",
154-
)[first_band]
155-
band_arr2 = prod.load(
156-
first_band,
157-
window=Window(col_off=0, row_off=0, width=100, height=100),
158-
)[first_band]
152+
# Check that band loaded 2 times gives the same results (disregarding float uncertainties)
153+
band_arr1 = prod.load(
154+
first_band,
155+
window=Window(col_off=0, row_off=0, width=100, height=100),
156+
clean_optical="nodata",
157+
)[first_band]
158+
band_arr2 = prod.load(
159+
first_band,
160+
window=Window(col_off=0, row_off=0, width=100, height=100),
161+
)[first_band]
159162

160-
np.testing.assert_array_almost_equal(band_arr1, band_arr2)
163+
np.testing.assert_array_almost_equal(band_arr1, band_arr2)
161164

162-
# Check dtypes
163-
ci.assert_val(band_arr_raw.dtype, np.float32, "band_arr_raw dtype")
164-
ci.assert_val(band_arr1.dtype, np.float32, "band_arr1 dtype")
165-
ci.assert_val(band_arr2.dtype, np.float32, "band_arr2 dtype")
165+
# Check dtypes
166+
ci.assert_val(band_arr_raw.dtype, np.float32, "band_arr_raw dtype")
167+
ci.assert_val(band_arr1.dtype, np.float32, "band_arr1 dtype")
168+
ci.assert_val(band_arr2.dtype, np.float32, "band_arr2 dtype")
166169

167-
# Check shapes between raw and no data cleaning
168-
ci.assert_val(band_arr_raw.shape, band_arr1.shape, "band_arr1 shape")
170+
# Check shapes between raw and no data cleaning
171+
ci.assert_val(band_arr_raw.shape, band_arr1.shape, "band_arr1 shape")
169172

170173

171174
def check_attrs(prod: Product, array: xr.DataArray, long_name) -> None:

eoreader/products/optical/hls_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,7 @@ def get_band_paths(
714714
band_id = self.bands[band].id
715715

716716
# Get clean band path
717-
clean_band = self._get_clean_band_path(
718-
band, pixel_size=pixel_size, **kwargs
719-
)
717+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
720718
if clean_band.is_file():
721719
band_paths[band] = clean_band
722720
else:

eoreader/products/optical/landsat_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -979,9 +979,7 @@ def get_band_paths(
979979
band_id = self.bands[band].id
980980

981981
# Get clean band path
982-
clean_band = self._get_clean_band_path(
983-
band, pixel_size=pixel_size, **kwargs
984-
)
982+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
985983
if clean_band.is_file():
986984
band_paths[band] = clean_band
987985
else:

eoreader/products/optical/optical_product.py

+22-34
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,10 @@ def _open_bands(
317317

318318
if not pixel_size:
319319
pixel_size = band_arr.rio.resolution()[0]
320-
clean_band_path = self._get_clean_band_path(
320+
clean_band_path = self.get_band_path(
321321
band, pixel_size=pixel_size, writable=True, **kwargs
322322
)
323-
# If raw data, clean it !
323+
# If raw data, clean it!
324324
if AnyPath(band_path).name != clean_band_path.name:
325325
# Clean pixels
326326
cleaning_method = CleanMethod.from_value(
@@ -596,7 +596,7 @@ def _load_clouds(
596596
# First, try to open the cloud band written on disk
597597
bands_to_load = []
598598
for band in bands:
599-
cloud_path = self._construct_band_path(
599+
cloud_path = self.get_band_path(
600600
band, pixel_size, size, writable=False, **kwargs
601601
)
602602
if cloud_path.is_file():
@@ -609,7 +609,7 @@ def _load_clouds(
609609

610610
# Write them on disk
611611
for band_id, band_arr in loaded_bands.items():
612-
cloud_path = self._construct_band_path(
612+
cloud_path = self.get_band_path(
613613
band_id, pixel_size, size, writable=True, **kwargs
614614
)
615615
band_arr = utils.write_path_in_attrs(band_arr, cloud_path)
@@ -664,7 +664,7 @@ def _load_masks(
664664
# First, try to open the cloud band written on disk
665665
bands_to_load = []
666666
for band in bands:
667-
mask_path = self._construct_band_path(
667+
mask_path = self.get_band_path(
668668
band, pixel_size, size, writable=False, **kwargs
669669
)
670670
if mask_path.is_file():
@@ -677,7 +677,7 @@ def _load_masks(
677677

678678
# Write them on disk
679679
for band_id, band_arr in loaded_bands.items():
680-
mask_path = self._construct_band_path(
680+
mask_path = self.get_band_path(
681681
band_id, pixel_size, size, writable=True, **kwargs
682682
)
683683
band_arr = utils.write_path_in_attrs(band_arr, mask_path)
@@ -719,44 +719,32 @@ def _create_mask(
719719

720720
return mask
721721

722-
def _get_clean_band_path(
723-
self,
724-
band: BandNames,
725-
pixel_size: float = None,
726-
writable: bool = False,
727-
**kwargs,
728-
) -> AnyPathType:
722+
def _get_band_file_name_sensor_specific_suffix(
723+
self, band: BandNames, **kwargs
724+
) -> str:
729725
"""
730-
Get clean band path.
731-
732-
The clean band is the opened band where invalid pixels have been managed.
726+
Get the sensor-specific suffix of a band filename.
733727
734728
Args:
735729
band (BandNames): Wanted band
736-
pixel_size (float): Band pixel size in meters
737-
writable (bool): True if we want the band folder to be writeable
738-
kwargs: Additional arguments
730+
**kwargs: Other args
739731
740732
Returns:
741-
AnyPathType: Clean band path
733+
str: Band filename sensor-specific suffix
742734
"""
743-
cleaning_method = CleanMethod.from_value(
744-
kwargs.get(CLEAN_OPTICAL, DEF_CLEAN_METHOD)
745-
)
746-
747-
res_str = self._pixel_size_to_str(pixel_size)
735+
if is_spectral_band(band):
736+
cleaning_method = CleanMethod.from_value(
737+
kwargs.get(CLEAN_OPTICAL, DEF_CLEAN_METHOD)
738+
)
748739

749-
# Radiometric processing
750-
rad_proc = "" if kwargs.get(TO_REFLECTANCE, True) else "_as_is"
740+
# Radiometric processing
741+
rad_proc = "" if kwargs.get(TO_REFLECTANCE, True) else "_as_is"
751742

752-
# Window name
753-
win_suffix = utils.get_window_suffix(kwargs.get("window"))
754-
if win_suffix:
755-
win_suffix += "_"
743+
suffix = f"_{cleaning_method.value}{rad_proc}"
744+
else:
745+
suffix = ""
756746

757-
return self._get_band_folder(writable).joinpath(
758-
f"{self.condensed_name}_{band.name}_{res_str.replace('.', '-')}_{win_suffix}{cleaning_method.value}{rad_proc}.tif",
759-
)
747+
return suffix
760748

761749
@cache
762750
def _sun_earth_distance(self) -> float:

eoreader/products/optical/planet_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,7 @@ def get_band_paths(
428428
band_path = self._get_stack_path(as_list=False)
429429
for band in band_list:
430430
# Get clean band path
431-
clean_band = self._get_clean_band_path(
432-
band, pixel_size=pixel_size, **kwargs
433-
)
431+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
434432
if clean_band.is_file():
435433
band_paths[band] = clean_band
436434
else:

eoreader/products/optical/s2_e84_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,7 @@ def get_band_paths(
514514
band_id = self.bands[band].id
515515

516516
# Get clean band path
517-
clean_band = self._get_clean_band_path(
518-
band, pixel_size=pixel_size, **kwargs
519-
)
517+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
520518
if clean_band.is_file():
521519
band_paths[band] = clean_band
522520
else:

eoreader/products/optical/s2_product.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,7 @@ def get_band_paths(
668668
band_paths = {}
669669
for band in band_list:
670670
# Get clean band path
671-
clean_band = self._get_clean_band_path(
672-
band, pixel_size=pixel_size, **kwargs
673-
)
671+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
674672
if clean_band.is_file():
675673
band_paths[band] = clean_band
676674
else:
@@ -980,7 +978,7 @@ def _load_masks(
980978
for band in bands:
981979
for associated_band in associated_bands[band]:
982980
key = self._get_band_key(band, associated_band, **kwargs)
983-
mask_path = self._construct_band_path(
981+
mask_path = self.get_band_path(
984982
key,
985983
pixel_size,
986984
size,
@@ -1003,7 +1001,7 @@ def _load_masks(
10031001

10041002
# Write them on disk
10051003
for band_id, band_arr in loaded_bands.items():
1006-
mask_path = self._construct_band_path(
1004+
mask_path = self.get_band_path(
10071005
band_id, pixel_size, size, writable=True, **kwargs
10081006
)
10091007
band_arr = utils.write_path_in_attrs(band_arr, mask_path)
@@ -1595,7 +1593,7 @@ def _load_s2_l2a_bands(
15951593
# First, try to open the cloud band written on disk
15961594
bands_to_load = []
15971595
for band in bands:
1598-
s2_l2a_path = self._construct_band_path(
1596+
s2_l2a_path = self.get_band_path(
15991597
band, pixel_size, size, writable=False, **kwargs
16001598
)
16011599
if s2_l2a_path.is_file():
@@ -1654,7 +1652,7 @@ def _load_s2_l2a_bands(
16541652

16551653
# Write them on disk
16561654
for band_id, band_arr in loaded_bands.items():
1657-
s2_l2a_path = self._construct_band_path(
1655+
s2_l2a_path = self.get_band_path(
16581656
band_id, pixel_size, size, writable=True, **kwargs
16591657
)
16601658
band_arr = utils.write_path_in_attrs(band_arr, s2_l2a_path)
@@ -2407,9 +2405,7 @@ def get_band_paths(
24072405
band_paths = {}
24082406
for band in band_list:
24092407
# Get clean band path
2410-
clean_band = self._get_clean_band_path(
2411-
band, pixel_size=pixel_size, **kwargs
2412-
)
2408+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
24132409
if clean_band.is_file():
24142410
band_paths[band] = clean_band
24152411
else:

eoreader/products/optical/s2_theia_product.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,7 @@ def get_band_paths(
327327
"""
328328
band_paths = {}
329329
for band in band_list: # Get clean band path
330-
clean_band = self._get_clean_band_path(
331-
band, pixel_size=pixel_size, **kwargs
332-
)
330+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
333331
if clean_band.is_file():
334332
band_paths[band] = clean_band
335333
else:
@@ -656,7 +654,7 @@ def _load_masks(
656654
for band in bands:
657655
for associated_band in associated_bands[band]:
658656
key = self._get_band_key(band, associated_band, **kwargs)
659-
mask_path = self._construct_band_path(
657+
mask_path = self.get_band_path(
660658
key,
661659
pixel_size,
662660
size,
@@ -679,7 +677,7 @@ def _load_masks(
679677

680678
# Write them on disk
681679
for band_id, band_arr in loaded_bands.items():
682-
mask_path = self._construct_band_path(
680+
mask_path = self.get_band_path(
683681
band_id, pixel_size, size, writable=True, **kwargs
684682
)
685683
band_arr = utils.write_path_in_attrs(band_arr, mask_path)

eoreader/products/optical/s3_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,7 @@ def get_band_paths(
423423
band_paths = {}
424424
for band in band_list:
425425
# Get clean band path
426-
clean_band = self._get_clean_band_path(
427-
band, pixel_size=pixel_size, **kwargs
428-
)
426+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
429427
if clean_band.is_file():
430428
band_paths[band] = clean_band
431429
else:

eoreader/products/optical/s3_slstr_product.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ def get_mean_sun_angles(self, view: SlstrView = SlstrView.NADIR) -> (float, floa
11321132

11331133
return float(sun_az.mean().data) % 360, float(sun_ze.mean().data)
11341134

1135-
def _get_clean_band_path(
1135+
def get_band_path(
11361136
self,
11371137
band: BandNames,
11381138
pixel_size: float = None,
@@ -1153,7 +1153,7 @@ def _get_clean_band_path(
11531153
AnyPathType: Clean band path
11541154
"""
11551155

1156-
clean_band_path = super()._get_clean_band_path(
1156+
clean_band_path = super().get_band_path(
11571157
band=band,
11581158
pixel_size=pixel_size,
11591159
writable=writable,

eoreader/products/optical/sv1_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,7 @@ def get_band_paths(
594594
band_paths = {}
595595
for band in band_list:
596596
# Get clean band path
597-
clean_band = self._get_clean_band_path(
598-
band, pixel_size=pixel_size, **kwargs
599-
)
597+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
600598
if clean_band.is_file():
601599
band_paths[band] = clean_band
602600
else:

eoreader/products/optical/vhr_product.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ def get_band_paths(
206206
band_paths = {}
207207
for band in band_list:
208208
# Get clean band path
209-
clean_band = self._get_clean_band_path(
210-
band, pixel_size=pixel_size, **kwargs
211-
)
209+
clean_band = self.get_band_path(band, pixel_size=pixel_size, **kwargs)
212210
if clean_band.is_file():
213211
band_paths[band] = clean_band
214212
else:

0 commit comments

Comments
 (0)