Giter Club home page Giter Club logo

sarsen's Introduction

Sarsen

Algorithms and utilities for Synthetic Aperture Radar (SAR) sensors. Enables cloud-native SAR processing via Xarray and Dask.

This Open Source project is sponsored by B-Open - https://www.bopen.eu.

Features and limitations

Sarsen is a Python library and command line tool with the following functionalities:

  • provides algorithms to terrain-correct satellite SAR data
    • geometric terrain correction (geocoding)
      • fast mode: to terrain-correct images
      • accurate mode: for interferometric processing
    • radiometric terrain correction (gamma flattening)
  • accesses SAR data via xarray-sentinel:
    • supports most Sentinel-1 data products as distributed by ESA:
      • Sentinel-1 Single Look Complex (SLC) SM/IW/EW
      • Sentinel-1 Ground Range Detected (GRD) SM/IW/EW
    • reads uncompressed and compressed SAFE data products on the local computer or on a network via fsspec - depends on rasterio>=1.3
  • accesses DEM data via rioxarray:
    • reads local and remote data in virtually any raster format via rasterio / GDAL
  • supports larger-than-memory and distributed data access and processing via Dask
    • efficient geometric terrain-correction for a full GRD
    • efficient radiometric terrain-correction for a full GRD.

Overall, the software is in the beta phase and the usual caveats apply.

Current limitations:

  • documentation needs improvement. See #6.

Non-objectives / Caveat emptor items:

  • No attempt is made to support UTC leap seconds. Observations that include a leap second may crash the code or silently return wrong results.

SAR terrain-correction

The typical side-looking SAR system acquires data with uniform sampling in azimuth and slant range, where the azimuth and range represents the time when a given target is acquired and the absolute sensor-to-target distance, respectively. Because of this, the near range appears compressed with respect to the far range. Furthermore, any deviation of the target elevation from a smooth geoid results in additional local geometric and radiometric distortions known as foreshortening, layover and shadow.

  • Radar foreshortening: Terrain surfaces sloping towards the radar appear shortened relative to those sloping away from the radar. These regions are much brighter than other places on the SAR image.
  • Radar layover: It's an extreme case of foreshortening occurring when the terrain slope is greater than the angle of the incident signal.
  • Radar shadows: They occur when ground points at the same azimuth but different slant ranges are aligned in the direction of the line-of-sight. This is usually due to a back slope with an angle steeper than the viewing angle. When this happens, the radar signal never reaches the farthest points, and thus there is no measurement, meaning that this lack of information is unrecoverable.

The geometric terrain correction (GTC) corrects the distortions due to the target elevation. The radiometric terrain correction (RTC) also compensates for the backscatter modulation generated by the topography of the scene.

Install

The easiest way to install sarsen is in a conda environment. The following commands create a new environment, activate it, install the package and its dependencies:

  conda create -n SARSEN
  conda activate SARSEN
  conda install -c conda-forge dask proj-data sarsen

Note that theΒ proj-data package is rather large (500+Mb) and it is only needed to handle input DEM whose vertical coordinate is not on a known ellipsoid, for example SRTM DEM with heigths over the EGM96 geoid.

Command line usage

The sarsen command line tool corrects SAR data based on a selected DEM and may produce geometrically terrain-corrected images (GTC) or radiometrically terrain-corrected images (RTC). Terrain-corrected images will have the same pixels as the input DEM, that should be resampled to the target projection and spacing in advance, for example using gdalwarp.

The following command performs a geometric terrain correction:

  sarsen gtc S1B_IW_GRDH_1SDV_20211217T141304_20211217T141329_030066_039705_9048.SAFE IW/VV South-of-Redmond-10m_UTM.tif

Performing geometric and radiometric terrain correction is more demanding, but it is possible to produce the RTC of a full GRD product at a 10m resolution in one go (and it takes approx 25 minutes on a 32Gb MacBook Pro):

  sarsen rtc S1B_IW_GRDH_1SDV_20211217T141304_20211217T141329_030066_039705_9048.SAFE IW/VV South-of-Redmond-10m_UTM.tif

Python API usage

The python API has entry points to the same commands and it also gives access to several lower level algorithms, but internal APIs should not be considered stable:

The following code applies the geometric terrain correction to the VV polarization of "S1B_IW_GRDH_1SDV_20211217T141304_20211217T141329_030066_039705_9048.SAFE" product:

>>> import sarsen
>>> product = sarsen.Sentinel1SarProduct(
...   "tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE",
...   measurement_group="IW/VV",
... )
>>> gtc = sarsen.terrain_correction(
...   product,
...   dem_urlpath="tests/data/Rome-30m-DEM.tif",
... )

The radiometric correction can be activated using the key correct_radiometry:

>>> rtc = sarsen.terrain_correction(
...   product,
...   dem_urlpath="tests/data/Rome-30m-DEM.tif",
...   correct_radiometry="gamma_nearest"
... )

Reference documentation

This is the list of the reference documents:

Project resources

on-push codecov

Contributing

The main repository is hosted on GitHub. Testing, bug reports and contributions are highly welcomed and appreciated:

https://github.com/bopen/sarsen

Lead developer:

Main contributors:

See also the list of contributors who participated in this project.

Sponsoring

B-Open commits to maintain the project long term and we are happy to accept sponsorships to develop new features.

We wish to express our gratitude to the project sponsors:

  • Microsoft has sponsored the support for GRD products and the gamma flattening algorithm.

License

Copyright 2016-2022 B-Open Solutions srl

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

sarsen's People

Contributors

alexamici avatar aurghs avatar dependabot[bot] avatar malmans2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sarsen's Issues

Make processing dask-friendly to allow larger-than-memory and parallel processing

Almost all operations can be chunked via the DEM chunks (not the image ones).

This includes:

  • allow controlling the DEM chunks
  • use dask-friendly xarray-sentinel helpers
  • make internal functions (that need it) dask-friendly via xarray.map_blocks
  • add borders to the gamma flattening processing to avoid "seeing" the borders of the blocks

The main source of dask-unfriendliness is the wide spread use of DataArray.interp with the target values on the DEM coordinates. All operations (except the gamma flattening) can be performed on ("x", "y") blocks exactly.

Use gamma-0 backscatter convention for RTC output

Hi all,
I was wondering why you chose to stick to the beta-0 backscatter convention instead of gamma-0 for the RTC output?
Isn't the entire point of applying David Small's RTC algorithm [1] to get a terrain-flattened, gamma-0 normalized backscatter product? Furthermore, you might have heard of the CEOS CARD4L Normalised Radar Backscatter specification [2], which also endorses the gamma-0 backscatter convention.

Great software and I'm looking forward to hearing from you!

[1] https://doi.org/10.1109/tgrs.2011.2120616
[2] https://ceos.org/ard/files/PFS/NRB/v5.5/CARD4L-PFS_NRB_v5.5.pdf

SARSEN Error

I have tested on both CentOS 7 and Windows 10. We are unable to use SARSEN because of this error:
sarsen gtc S1A_IW_GRDH_1SDV_20210519T094926_20210519T094951_037955_047ACD_7336.zip "IW/VV" GLO20_WGS84_clipped.tif
Traceback (most recent call last):
File "/opt/anaconda3/envs/SARSEN/bin/sarsen", line 8, in
sys.exit(app())
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/typer/main.py", line 214, in call
return get_command(self)(*args, **kwargs)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/click/core.py", line 1128, in call
return self.main(*args, **kwargs)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/typer/main.py", line 500, in wrapper
return callback(**use_params) # type: ignore
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/sarsen/main.py", line 17, in gtc
apps.backward_geocode_sentinel1(
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/sarsen/apps.py", line 84, in backward_geocode_sentinel1
measurement_ds = xr.open_dataset(
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/xarray/backends/api.py", line 495, in open_dataset
backend_ds = backend.open_dataset(
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/xarray_sentinel/xarray_backends.py", line 18, in open_dataset
ds = sentinel1.open_sentinel1_dataset(
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/xarray_sentinel/sentinel1.py", line 715, in open_sentinel1_dataset
product_attrs, product_files = esa_safe.parse_manifest_sentinel1(file)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/site-packages/xarray_sentinel/esa_safe.py", line 111, in parse_manifest_sentinel1
manifest = ElementTree.parse(manifest_path)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/xml/etree/ElementTree.py", line 1229, in parse
tree.parse(source, parser)
File "/opt/anaconda3/envs/SARSEN/lib/python3.10/xml/etree/ElementTree.py", line 580, in parse
self._root = parser._parse_whole(source)
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 1, column 2

Documentation is lacking

At the minimum we need:

  • doctrings for public entry points
  • README with working examples
  • [requires more effort] set up a read the docs site

DEM format requirements / Reproducible example

Hi all,
I'm running into issues processing an SLC scene. Both GTC and RTC results are not really usable. I suspect my DEM is the problem and I'm wondering why, because I'm using the same DEM to successfully create an RTC product with SNAP. Here is the gdalinfo output if you're interested.

Can you provide some guidelines on format requirements for the DEM? Or at least a reproducible example in the notebook section. download_data.sh could, for example, be extended by a section that downloads DEM tiles from an open source (e.g., here) and prepares it with GDAL in the way sarsen expects.

Cheers, Marco

QST: How to use sarsen functions on other SAR constellations than S1

Hello,

I would like to use sarsen to avoid using ESA SNAP in eoreader, but since this library lacks an API documentation, I have some questions πŸ˜„

I already have my own way to load agnostically these SAR constellations:

Constellations
COSMO-SkyMed 1st Generation
COSMO-SkyMed 2nd Generation
ICEYE
RADARSAT Constellation Mission
RADARSAT-2
Sentinel-1
SAOCOM-1
TerraSAR-X, TanDEM-X, PAZ SAR

I would like to use your calibration, terrain correction (and so on) methods in order to avoid calling GPT.
Is this already possible? (are they fundamentally sensor agnostic ?)
Is this a good way to use of your library ?
It seems your algorithms are based on xarray-sentinel, but is there a workaround to your functions that would allow anyone to give bands and metadata, allowing the user to easily use your library with other constellations ?

Incompatibility with xarray 2023.08

The current main have several unittest failures with xarray v2023.08:

$ python3 -m pytest
================================================================== test session starts ==================================================================
platform linux -- Python 3.11.4, pytest-7.4.0, pluggy-1.3.0
rootdir: /home/antonio/projects/forks/sarsen
collected 30 items                                                                                                                                      

tests/test_10_chunking.py ...                                                                                                                     [ 10%]
tests/test_10_datamodel.py .                                                                                                                      [ 13%]
tests/test_10_orbit.py ..                                                                                                                         [ 20%]
tests/test_10_scene.py .FF                                                                                                                        [ 30%]
tests/test_20_geocoding.py ...                                                                                                                    [ 40%]
tests/test_20_sentinel1.py ...                                                                                                                    [ 50%]
tests/test_30_radiometry.py F                                                                                                                     [ 53%]
tests/test_50_apps.py ..FFFF..FFFF                                                                                                                [ 93%]
tests/test_60_main.py .                                                                                                                           [ 96%]
tests/test_90_sarsen.py .                                                                                                                         [100%]

======================================================================= FAILURES ========================================================================
_________________________________________________________________ test_transform_dem_3d _________________________________________________________________

dem_raster = <xarray.DataArray 'dem' (y: 360, x: 360)>
[129600 values with dtype=float32]
Coordinates:
  * x            (x) float64....05
    spatial_ref  int64 ...
Attributes:
    AREA_OR_POINT:  Area
    units:          m
    long_name:      elevation

    def test_transform_dem_3d(dem_raster: xr.DataArray) -> None:
        dem_3d = scene.convert_to_dem_3d(dem_raster)
    
        # from height over the geoid to height over the ellipsoid
        res = scene.transform_dem_3d(dem_3d, dem_3d.rio.crs, "EPSG:4979")
    
        assert res.dims == ("axis", "y", "x")
        # this assert fails if proj-data is not properly installed on the system
>       assert abs(res.sel(x=12.5, y=42, method="nearest")[2] - 65.613) < 0.001
E       AssertionError: assert <xarray.DataArray 'dem_3d' ()>\narray(48.613)\nCoordinates:\n    x            float64 12.5\n    spatial_ref  int64 0\n    y            float64 42.0\n    axis         int64 2 < 0.001
E        +  where <xarray.DataArray 'dem_3d' ()>\narray(48.613)\nCoordinates:\n    x            float64 12.5\n    spatial_ref  int64 0\n    y            float64 42.0\n    axis         int64 2 = abs((<xarray.DataArray 'dem_3d' ()>\narray(17.)\nCoordinates:\n    x            float64 12.5\n    spatial_ref  int64 0\n    y            float64 42.0\n    axis         int64 2 - 65.613))

tests/test_10_scene.py:23: AssertionError
____________________________________________________________ test_compute_dem_oriented_area _____________________________________________________________

dem_raster = <xarray.DataArray 'dem' (y: 360, x: 360)>
[129600 values with dtype=float32]
Coordinates:
  * x            (x) float64....05
    spatial_ref  int64 ...
Attributes:
    AREA_OR_POINT:  Area
    units:          m
    long_name:      elevation

    def test_compute_dem_oriented_area(dem_raster: xr.DataArray) -> None:
        dem_3d = scene.convert_to_dem_3d(dem_raster)
    
>       res = scene.compute_dem_oriented_area(dem_3d)

tests/test_10_scene.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb1d69650>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
________________________________________________________________ test_compute_gamma_area ________________________________________________________________

dem_ecef = <xarray.DataArray 'dem_3d' (axis: 3, y: 360, x: 360)>
array([[[4639035.90736075, 4639029.48935904, 4639021.61878218, .... 0
  * y            (y) float64 41.95 41.95 41.95 41.95 ... 42.05 42.05 42.05 42.05
  * axis         (axis) int64 0 1 2

    def test_compute_gamma_area(dem_ecef: xr.DataArray) -> None:
        dem_direction = xr.DataArray()
>       res = radiometry.compute_gamma_area(dem_ecef, dem_direction)

tests/test_30_radiometry.py:8: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb0b84750>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
__________________________________________________ test_terrain_correction_fast_rtc[data_path0-IW/VV] ___________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_fast_r0')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE')
group = 'IW/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_fast_rtc(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_nearest",
            output_urlpath=out,
        )

tests/test_50_apps.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0b8bca5690>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
__________________________________________________ test_terrain_correction_fast_rtc[data_path1-IW1/VV] __________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_fast_r1')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1A_IW_SLC__1SDV_20220104T170557_20220104T170624_041314_04E951_F1F1.SAFE')
group = 'IW1/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_fast_rtc(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_nearest",
            output_urlpath=out,
        )

tests/test_50_apps.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb05f1fd0>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
_____________________________________________________ test_terrain_correction_rtc[data_path0-IW/VV] _____________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_rtc_da0')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE')
group = 'IW/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_rtc(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_bilinear",
            output_urlpath=out,
        )

tests/test_50_apps.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb0b057d0>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
____________________________________________________ test_terrain_correction_rtc[data_path1-IW1/VV] _____________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_rtc_da1')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1A_IW_SLC__1SDV_20220104T170557_20220104T170624_041314_04E951_F1F1.SAFE')
group = 'IW1/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_rtc(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_bilinear",
            output_urlpath=out,
        )

tests/test_50_apps.py:80: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb02a3bd0>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
________________________________________________ test_terrain_correction_fast_rtc_dask[data_path0-IW/VV] ________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_fast_r2')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE')
group = 'IW/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_fast_rtc_dask(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_nearest",
            output_urlpath=out,
            chunks=1024,
        )

tests/test_50_apps.py:124: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0b8bc5d7d0>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
_______________________________________________ test_terrain_correction_fast_rtc_dask[data_path1-IW1/VV] ________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_fast_r3')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1A_IW_SLC__1SDV_20220104T170557_20220104T170624_041314_04E951_F1F1.SAFE')
group = 'IW1/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_fast_rtc_dask(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_nearest",
            output_urlpath=out,
            chunks=1024,
        )

tests/test_50_apps.py:124: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0bb0889ad0>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
__________________________________________________ test_terrain_correction_rtc_dask[data_path0-IW/VV] ___________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_rtc_da2')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE')
group = 'IW/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_rtc_dask(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_bilinear",
            output_urlpath=out,
            chunks=1024,
        )

tests/test_50_apps.py:147: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0b8bfae750>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
__________________________________________________ test_terrain_correction_rtc_dask[data_path1-IW1/VV] __________________________________________________

tmpdir = local('/tmp/pytest-of-antonio/pytest-3/test_terrain_correction_rtc_da3')
data_path = PosixPath('/home/antonio/projects/forks/sarsen/tests/data/S1A_IW_SLC__1SDV_20220104T170557_20220104T170624_041314_04E951_F1F1.SAFE')
group = 'IW1/VV'

    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    @pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == "true", reason="too much memory")
    def test_terrain_correction_rtc_dask(
        tmpdir: py.path.local, data_path: pathlib.Path, group: str
    ) -> None:
        out = str(tmpdir.join("RTC.tif"))
        product = sentinel1.Sentinel1SarProduct(
            str(data_path),
            group,
        )
    
>       res = apps.terrain_correction(
            product,
            str(DEM_RASTER),
            correct_radiometry="gamma_bilinear",
            output_urlpath=out,
            chunks=1024,
        )

tests/test_50_apps.py:147: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sarsen/apps.py:166: in terrain_correction
    acquisition = acquisition.persist()
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1029: in persist
    return new._persist_inplace(**kwargs)
venv/lib/python3.11/site-packages/xarray/core/dataset.py:1003: in _persist_inplace
    evaluated_data = dask.persist(*lazy_data.values(), **kwargs)
venv/lib/python3.11/site-packages/dask/base.py:967: in persist
    results = schedule(dsk, keys, **kwargs)
venv/lib/python3.11/site-packages/dask/threaded.py:89: in get
    results = get_async(
venv/lib/python3.11/site-packages/dask/local.py:511: in get_async
    raise_exception(exc, tb)
venv/lib/python3.11/site-packages/dask/local.py:319: in reraise
    raise exc
venv/lib/python3.11/site-packages/dask/local.py:224: in execute_task
    result = _execute_task(task, data)
venv/lib/python3.11/site-packages/dask/core.py:121: in _execute_task
    return func(*(_execute_task(a, cache) for a in args))
venv/lib/python3.11/site-packages/xarray/core/parallel.py:268: in _wrapper
    result = func(*converted_args, **kwargs)
sarsen/apps.py:36: in simulate_acquisition
    gamma_area = radiometry.compute_gamma_area(
sarsen/radiometry.py:56: in compute_gamma_area
    dem_oriented_area = scene.compute_dem_oriented_area(dem_ecef)
sarsen/scene.py:110: in compute_dem_oriented_area
    cross_2 = xr.cross(dx2, dy2, dim="axis") / 2
venv/lib/python3.11/site-packages/xarray/core/computation.py:1609: in cross
    c = apply_ufunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:1197: in apply_ufunc
    return apply_dataarray_vfunc(
venv/lib/python3.11/site-packages/xarray/core/computation.py:288: in apply_dataarray_vfunc
    args = deep_align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:847: in deep_align
    aligned = align(
venv/lib/python3.11/site-packages/xarray/core/alignment.py:783: in align
    aligner.align()
venv/lib/python3.11/site-packages/xarray/core/alignment.py:568: in align
    self.align_indexes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <xarray.core.alignment.Aligner object at 0x7f0b8bec2d90>

    def align_indexes(self) -> None:
        """Compute all aligned indexes and their corresponding coordinate variables."""
    
        aligned_indexes = {}
        aligned_index_vars = {}
        reindex = {}
        new_indexes = {}
        new_index_vars = {}
    
        for key, matching_indexes in self.all_indexes.items():
            matching_index_vars = self.all_index_vars[key]
            dims = {d for coord in matching_index_vars[0].values() for d in coord.dims}
            index_cls = key[1]
    
            if self.join == "override":
                joined_index = matching_indexes[0]
                joined_index_vars = matching_index_vars[0]
                need_reindex = False
            elif key in self.indexes:
                joined_index = self.indexes[key]
                joined_index_vars = self.index_vars[key]
                cmp_indexes = list(
                    zip(
                        [joined_index] + matching_indexes,
                        [joined_index_vars] + matching_index_vars,
                    )
                )
                need_reindex = self._need_reindex(dims, cmp_indexes)
            else:
                if len(matching_indexes) > 1:
                    need_reindex = self._need_reindex(
                        dims,
                        list(zip(matching_indexes, matching_index_vars)),
                    )
                else:
                    need_reindex = False
                if need_reindex:
                    if self.join == "exact":
>                       raise ValueError(
                            "cannot align objects with join='exact' where "
                            "index/labels/sizes are not equal along "
                            "these coordinates (dimensions): "
                            + ", ".join(f"{name!r} {dims!r}" for name, dims in key[0])
                        )
E                       ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)

venv/lib/python3.11/site-packages/xarray/core/alignment.py:415: ValueError
=================================================================== warnings summary ====================================================================
tests/test_20_geocoding.py::test_secant_method
  /home/antonio/projects/forks/sarsen/sarsen/geocoding.py:44: RuntimeWarning: invalid value encountered in divide
    t_prev, t_curr = t_curr, t_curr - np.where(q != 0, p / q, 0)  # type: ignore

tests/test_20_sentinel1.py: 26 warnings
tests/test_50_apps.py: 52 warnings
  /home/antonio/projects/forks/sarsen/sarsen/sentinel1.py:30: UserWarning: Converting non-nanosecond precision datetime values to nanosecond precision. This behavior can eventually be relaxed in xarray, as it is an artifact from pandas which is now beginning to support non-nanosecond precision values. This warning is caused by passing non-nanosecond np.datetime64 or np.timedelta64 values to the DataArray or Variable constructor; it can be silenced by converting the values to nanosecond precision ahead of time.
    ds = xr.open_dataset(product_urlpath, group=group, chunks=chunks, **kwargs)

tests/test_20_sentinel1.py: 7 warnings
tests/test_50_apps.py: 18 warnings
  /home/antonio/projects/forks/sarsen/venv/lib/python3.11/site-packages/rioxarray/_io.py:1132: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
    warnings.warn(str(rio_warning.message), type(rio_warning.message))  # type: ignore

tests/test_20_sentinel1.py: 7 warnings
tests/test_50_apps.py: 14 warnings
  /home/antonio/projects/forks/sarsen/venv/lib/python3.11/site-packages/xarray/core/dataset.py:269: UserWarning: The specified chunks separate the stored chunks along dimension "line" starting at index 2048. This could degrade performance. Instead, consider rechunking after loading.
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================================================ short test summary info ================================================================
FAILED tests/test_10_scene.py::test_transform_dem_3d - AssertionError: assert <xarray.DataArray 'dem_3d' ()>\narray(48.613)\nCoordinates:\n    x            float64 12.5\n    spatial_ref  int64 0\n    y  ...
FAILED tests/test_10_scene.py::test_compute_dem_oriented_area - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_30_radiometry.py::test_compute_gamma_area - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_fast_rtc[data_path0-IW/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_fast_rtc[data_path1-IW1/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_rtc[data_path0-IW/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_rtc[data_path1-IW1/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_fast_rtc_dask[data_path0-IW/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_fast_rtc_dask[data_path1-IW1/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_rtc_dask[data_path0-IW/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
FAILED tests/test_50_apps.py::test_terrain_correction_rtc_dask[data_path1-IW1/VV] - ValueError: cannot align objects with join='exact' where index/labels/sizes are not equal along these coordinates (dimensions): 'x' ('x',)
================================================ 11 failed, 19 passed, 125 warnings in 124.60s (0:02:04) ================================================

Any idea about how to fix / workaround this issue?

Local incidence angle images

Hi,
I recently discovered sarsen. This is a great tool that fills an important gap in the python geo/rs stack! Thanks!

I have started to poke around to generate local incidence angle images for GRD products on a target CRS (the one of the DEM), the goal being to have a corrected (geometry and radiometry) SAR image + the local incidence angle (LIA) as a single stack with 3 channels (VV, VH, LIA).

Actually, I would only need the incidence angle array extracted with xarray-sentinel1 (your other lib) orthorectified on the DEM and then I could use the DEM slope and aspect to compute the local angle.

Could you give me some guidance in how to generate the incidence angle grid on the DEM geometry? I can't wrap my head around how to use the sarsen API once I get the incidence angles from the gcp subgroup from xarray-sentinel1.

Thank you.

Test error on i386

Two tests of the test suite seems to fail on i386 architectures (see the salsa CI log).
The problem has been spotted on one of the Debian CI systems.
Both issues seems to be linked to the size of the image and the limited resources of the VM used in CI (I do not know details but the amount of memory seems to be quite limited).

Does it make sense to try reduce the size of the image used for the test? ... is it something that can be done easily?
I could try to prepare a patch in the case ...

============================ test session starts ==============================
platform linux -- Python 3.11.1, pytest-7.2.0, pluggy-1.0.0+repack
rootdir: /builds/debian-gis-team/sarsen/debian/output/source_dir/.pybuild/cpython3_3.11/build
collected 30 items
tests/test_10_chunking.py ...                                            [ 10%]
tests/test_10_datamodel.py .                                             [ 13%]
tests/test_10_orbit.py ..                                                [ 20%]
tests/test_10_scene.py ...                                               [ 30%]
tests/test_20_geocoding.py ...                                           [ 40%]
tests/test_20_sentinel1.py FF.                                           [ 50%]
tests/test_30_radiometry.py .                                            [ 53%]
tests/test_50_apps.py ssssssssssss                                       [ 93%]
tests/test_60_main.py .                                                  [ 96%]
tests/test_90_sarsen.py .                                                [100%]
=================================== FAILURES ===================================
__________________ test_Sentinel1SarProduct[data_path0-IW/VV] __________________
data_path = PosixPath('/builds/debian-gis-team/sarsen/debian/output/source_dir/.pybuild/cpython3_3.11/build/tests/data/S1B_IW_GRDH_1SDV_20211223T051122_20211223T051147_030148_039993_5371.SAFE')
group = 'IW/VV'
    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    def test_Sentinel1SarProduct(data_path: str, group: str) -> None:
        res = sentinel1.Sentinel1SarProduct(data_path, group)
    
        assert isinstance(res.measurement, xr.Dataset)
        assert isinstance(res.orbit, xr.Dataset)
        assert isinstance(res.calibration, xr.Dataset)
    
        if res.product_type == "GRD":
            assert isinstance(res.coordinate_conversion, xr.Dataset)
            assert res.azimuth_fm_rate is None
            assert res.dc_estimate is None
        else:
            assert res.coordinate_conversion is None
            assert isinstance(res.azimuth_fm_rate, xr.Dataset)
            assert isinstance(res.dc_estimate, xr.Dataset)
    
        assert res.product_type in {"SLC", "GRD"}
>       assert isinstance(res.beta_nought(), xr.DataArray)
tests/test_20_sentinel1.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
sarsen/sentinel1.py:156: in beta_nought
    return calibrate_measurement(measurement, self.calibration.betaNought)
sarsen/sentinel1.py:44: in calibrate_measurement
    beta_nought = xarray_sentinel.calibrate_intensity(measurement, beta_nought_lut)
/usr/lib/python3/dist-packages/xarray_sentinel/sentinel1.py:842: in calibrate_intensity
    amplitude = calibrate_amplitude(digital_number, calibration_lut, **kwargs)
/usr/lib/python3/dist-packages/xarray_sentinel/sentinel1.py:816: in calibrate_amplitude
    amplitude = digital_number / calibration
/usr/lib/python3/dist-packages/xarray/core/_typed_ops.py:218: in __truediv__
    return self._binary_op(other, operator.truediv)
/usr/lib/python3/dist-packages/xarray/core/dataarray.py:4358: in _binary_op
    f(self.variable, other_variable)
/usr/lib/python3/dist-packages/xarray/core/_typed_ops.py:408: in __truediv__
    return self._binary_op(other, operator.truediv)
/usr/lib/python3/dist-packages/xarray/core/variable.py:2634: in _binary_op
    self_data, other_data, dims = _broadcast_compat_data(self, other)
/usr/lib/python3/dist-packages/xarray/core/variable.py:3123: in _broadcast_compat_data
    self_data = new_self.data
/usr/lib/python3/dist-packages/xarray/core/variable.py:435: in data
    return self.values
/usr/lib/python3/dist-packages/xarray/core/variable.py:608: in values
    return _as_array_or_item(self._data)
/usr/lib/python3/dist-packages/xarray/core/variable.py:314: in _as_array_or_item
    data = np.asarray(data)
/usr/lib/python3/dist-packages/xarray/core/indexing.py:653: in __array__
    self._ensure_cached()
/usr/lib/python3/dist-packages/xarray/core/indexing.py:650: in _ensure_cached
    self.array = NumpyIndexingAdapter(np.asarray(self.array))
/usr/lib/python3/dist-packages/xarray/core/indexing.py:623: in __array__
    return np.asarray(self.array, dtype=dtype)
/usr/lib/python3/dist-packages/xarray/core/indexing.py:653: in __array__
    self._ensure_cached()
/usr/lib/python3/dist-packages/xarray/core/indexing.py:650: in _ensure_cached
    self.array = NumpyIndexingAdapter(np.asarray(self.array))
/usr/lib/python3/dist-packages/xarray/core/indexing.py:623: in __array__
    return np.asarray(self.array, dtype=dtype)
/usr/lib/python3/dist-packages/xarray/core/indexing.py:653: in __array__
    self._ensure_cached()
/usr/lib/python3/dist-packages/xarray/core/indexing.py:650: in _ensure_cached
    self.array = NumpyIndexingAdapter(np.asarray(self.array))
/usr/lib/python3/dist-packages/xarray/core/indexing.py:623: in __array__
    return np.asarray(self.array, dtype=dtype)
/usr/lib/python3/dist-packages/xarray/core/indexing.py:524: in __array__
    return np.asarray(array[self.key], dtype=None)
/usr/lib/python3/dist-packages/rioxarray/_io.py:423: in __getitem__
    return indexing.explicit_indexing_adapter(
/usr/lib/python3/dist-packages/xarray/core/indexing.py:815: in explicit_indexing_adapter
    result = raw_indexing_method(raw_key.tuple)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <rioxarray._io.RasterioArrayWrapper object at 0xe665e230>
key = (0, slice(None, None, None), slice(None, None, None))
    def _getitem(self, key):
        band_key, window, squeeze_axis, np_inds = self._get_indexer(key)
        if not band_key or any(start == stop for (start, stop) in window):
            # no need to do IO
            shape = (len(band_key),) + tuple(stop - start for (start, stop) in window)
            out = np.zeros(shape, dtype=self.dtype)
        else:
            with self.lock:
                riods = self.manager.acquire(needs_lock=False)
                if self.vrt_params is not None:
                    riods = WarpedVRT(riods, **self.vrt_params)
                out = riods.read(band_key, window=window, masked=self.masked)
                if self._unsigned_dtype is not None:
                    out = out.astype(self._unsigned_dtype)
                if self.masked:
>                   out = np.ma.filled(out.astype(self.dtype), self.fill_value)
E                   numpy.core._exceptions._ArrayMemoryError: Unable to allocate 1.62 GiB for an array with shape (16705, 26102) and data type float32
/usr/lib/python3/dist-packages/rioxarray/_io.py:404: MemoryError
_________________ test_Sentinel1SarProduct[data_path1-IW1/VV] __________________
data_path = PosixPath('/builds/debian-gis-team/sarsen/debian/output/source_dir/.pybuild/cpython3_3.11/build/tests/data/S1A_IW_SLC__1SDV_20220104T170557_20220104T170624_041314_04E951_F1F1.SAFE')
group = 'IW1/VV'
    @pytest.mark.parametrize("data_path,group", zip(DATA_PATHS, GROUPS))
    def test_Sentinel1SarProduct(data_path: str, group: str) -> None:
        res = sentinel1.Sentinel1SarProduct(data_path, group)
    
        assert isinstance(res.measurement, xr.Dataset)
        assert isinstance(res.orbit, xr.Dataset)
        assert isinstance(res.calibration, xr.Dataset)
    
        if res.product_type == "GRD":
            assert isinstance(res.coordinate_conversion, xr.Dataset)
            assert res.azimuth_fm_rate is None
            assert res.dc_estimate is None
        else:
            assert res.coordinate_conversion is None
            assert isinstance(res.azimuth_fm_rate, xr.Dataset)
            assert isinstance(res.dc_estimate, xr.Dataset)
    
        assert res.product_type in {"SLC", "GRD"}
>       assert isinstance(res.beta_nought(), xr.DataArray)
tests/test_20_sentinel1.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
sarsen/sentinel1.py:156: in beta_nought
    return calibrate_measurement(measurement, self.calibration.betaNought)
sarsen/sentinel1.py:42: in calibrate_measurement
    measurement = xarray_sentinel.mosaic_slc_iw(measurement)
/usr/lib/python3/dist-packages/xarray_sentinel/sentinel1.py:791: in mosaic_slc_iw
    return xr.concat(bursts, dim="azimuth_time")
/usr/lib/python3/dist-packages/xarray/core/concat.py:231: in concat
    return _dataarray_concat(
/usr/lib/python3/dist-packages/xarray/core/concat.py:657: in _dataarray_concat
    ds = _dataset_concat(
/usr/lib/python3/dist-packages/xarray/core/concat.py:584: in _dataset_concat
    combined_var = concat_vars(
/usr/lib/python3/dist-packages/xarray/core/variable.py:3186: in concat
    return Variable.concat(variables, dim, positions, shortcut, combine_attrs)
/usr/lib/python3/dist-packages/xarray/core/variable.py:2047: in concat
    data = duck_array_ops.concatenate(arrays, axis=axis)
/usr/lib/python3/dist-packages/xarray/core/duck_array_ops.py:314: in concatenate
    return _concatenate(as_shared_dtype(arrays), axis=axis)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
args = ([array([[0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0... 0.+0.j, 0.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0.+0.j]],
      dtype=complex64), ...],)
kwargs = {'axis': 0}
relevant_args = [array([[0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0....., 0.+0.j, 0.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j, 0.+0.j, ..., 0.+0.j, 0.+0.j, 0.+0.j]],
      dtype=complex64), ...]
>   ???
E   ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.
<__array_function__ internals>:180: ValueError
=============================== warnings summary ===============================
tests/test_20_geocoding.py::test_secant_method
  /builds/debian-gis-team/sarsen/debian/output/source_dir/.pybuild/cpython3_3.11/build/sarsen/geocoding.py:46: RuntimeWarning: invalid value encountered in divide
    t_prev, t_curr = t_curr, t_curr - np.where(q != 0, p / q, 0)  # type: ignore
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV]
  /usr/lib/python3/dist-packages/rioxarray/_io.py:1111: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned.
    warnings.warn(str(rio_warning.message), type(rio_warning.message))  # type: ignore
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path0-IW/VV] - numpy.core._exceptions._ArrayMemoryError: Unable to allocate 1.62 GiB for an array with shape (16705, 26102) and data type float32
FAILED tests/test_20_sentinel1.py::test_Sentinel1SarProduct[data_path1-IW1/VV] - ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.
============ 2 failed, 16 passed, 12 skipped, 8 warnings in 29.65s =============

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.