Skip to content

Commit

Permalink
fix a problem for fully nan feature vectors, this is now handled but …
Browse files Browse the repository at this point in the history
…not properly tested in calibration_smoothing.py
  • Loading branch information
leoschwarz committed Jun 7, 2024
1 parent 769b19f commit 25beb57
Showing 1 changed file with 39 additions and 10 deletions.
49 changes: 39 additions & 10 deletions src/depiction/calibration/spectrum/calibration_smoothing.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,52 @@
from __future__ import annotations

from typing import Callable

import numpy as np
import xarray
from xarray import DataArray

from depiction.image.spatial_smoothing_sparse_aware import SpatialSmoothingSparseAware


# TODO should be refactored later
def _apply_on_spatial_view(array: DataArray, fn: Callable[[DataArray], DataArray]) -> DataArray:
# adjust indexing for the rest of the function
array_flat = array.drop("i").set_xindex(["x", "y"])

# perform the computation on 2d view
array_2d = array_flat.unstack("i").transpose("y", "x", "c")
array_2d = fn(array_2d)

def smooth_image_features(all_features: DataArray, kernel_size: int, kernel_std: float) -> DataArray:
features_flat = all_features.drop("i").set_xindex(["x", "y"])
features_2d = features_flat.unstack("i").transpose("y", "x", "c")
smoother = SpatialSmoothingSparseAware(
kernel_size=kernel_size,
kernel_std=kernel_std,
# trick: concatenate an additional channel that will indicate everything that was present before, including
# fully nan elements because they should not disappear like an actual background
# this almost works but is broken:
is_nan_before = (
array_flat.isnull().all("c").astype(array_2d.dtype).expand_dims("c").unstack("i").transpose("y", "x", "c")
)
result = smoother.smooth(features_2d, bg_value=np.nan)
# TODO a bit ugly...
result = result.stack(i=("x", "y")).dropna("i", how="all")
array_2d = xarray.concat([array_2d, is_nan_before], dim="c")

# stack back the 2d view
result = array_2d.stack(i=("x", "y")).dropna("i", how="all")

# remove the additional channel
result = result.isel(c=slice(0, -1))

# revert the indexing
x, y = result.x.values, result.y.values
return result.drop_vars(["i", "x", "y"]).assign_coords(x=("i", x), y=("i", y), i=np.arange(len(result.i)))


# TODO should be refactored later

# TODO test this case : a spectrum is all nan before, but present in the flat repr, it should not disappear like an actual background


def smooth_image_features(all_features: DataArray, kernel_size: int, kernel_std: float) -> DataArray:
def fn(array_2d: DataArray) -> DataArray:
smoother = SpatialSmoothingSparseAware(
kernel_size=kernel_size,
kernel_std=kernel_std,
)
return smoother.smooth(array_2d, bg_value=np.nan)

return _apply_on_spatial_view(all_features, fn)

0 comments on commit 25beb57

Please sign in to comment.