pysiral.filter

Created on Sat Apr 23 15:30:53 2016

@author: Stefan Hendricks

Classes

L1bEnvisatBackscatterDriftCorrection

Very specific filter to correct backscatter drift. The filter

L2ParameterValidRange

Filters L2 variables that are outside a valid range.

RemoveNonOceanData

Ensure that data over non-ocean surfaces is set to NaN.

ParameterSmoother

Creates a filtered/smoothed copy of a given parameter.

MarginalIceZoneFilterData

Data class for MarginalIceZoneFilterFlag

MarginalIceZoneFilterFlag

Create a flag value that can be used to filter freeboard/thickness values

SAMOSAMarginalIceZoneFilterFlag

Create a flag value that can be used to filter freeboard/thickness values

Functions

numpy_smooth(x, window)

scipy_smooth(x, window)

Numpy implementation of the IDL SMOOTH function

astropy_smooth(x, window, **kwargs)

interp1d_gap_filling(→ numpy.ndarray)

Fill not-finite gaps by linear interpolation using `scipy.interp1d`with bounds_error

lowess_smooth(→ numpy.ndarray)

Simple lowess smoother

idl_smooth(→ numpy.ndarray)

Implementation of the IDL smooth(x, window, /EDGE_TRUNCATE, /NAN)

spline_smooth(y, window)

fill_nan(y)

smooth_2darray(array[, filter_width, preserve_gaps])

A simple smoothing filter

Module Contents

class pysiral.filter.L1bEnvisatBackscatterDriftCorrection(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Very specific filter to correct backscatter drift. The filter applies a monthly linear correction based on the drift factor and base period.

Notes:

  1. This class is very specifically designed for correcting the sigma0 value of the degrading Envisat RA-2 antenna

execute_procstep(l1b, l2)

Apply a backscatter correction :param l1b: :param l2: :return:

property l2_input_vars
property l2_output_vars
property error_bit
class pysiral.filter.L2ParameterValidRange(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Filters L2 variables that are outside a valid range.

Usage in Level-2 processor definition files:

  • module: filter pyclass: L2ParameterValidRange options:

    source_variable: <source_variable> target_variables: [<target_variables>] valid_minimum_point_value: <min_val> valid_maximum_point_value: <max_val>

will lead to that all target_variables will be set to np.nan if either

source_variable < min_val of source_variable > max_val

execute_procstep(l1b, l2)

Mandatory method for Level2ProcessorStep will change l2 data object in place :param l1b: :param l2: :return:

property l2_input_vars
property l2_output_vars
property error_bit
class pysiral.filter.RemoveNonOceanData(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Ensure that data over non-ocean surfaces is set to NaN.

Usage in Level-2 processor definition files:

  • module: filter pyclass: RemoveNonOceanData options:

    target_variables: [<target_variables>]

will lead to that all finite values of the target variables are set to NaN if the surface type is either land (6) or land ice (7). Any occurrence are logged.

execute_procstep(l1b: Level1bData, l2: Level2Data) numpy.ndarray
property l2_input_vars
property l2_output_vars
property error_bit
class pysiral.filter.ParameterSmoother(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Creates a filtered/smoothed copy of a given parameter.

Usage in Level-2 processor definition files:

  • module: filter pyclass: ParameterSmoother options:

    source_variable: <source_variable> target_variable_name: <output variable auxiliary data name> target_variable_id: <output variable auxiliary data id> smoothing_method: <the method for the smoothing: box_filter|gaussian_process> smoother_args: dict retain_nan_mask: bool

will register a new auxiliary variable output_variable_name|output_variable_id to the Level-2 data object

execute_procstep(l1b, l2)

Compute the smoother :param l1b: :param l2: :return:

static box_filter_smoother(x, window=5)
static lowess_smoother(y, **smoother_args)
property l2_input_vars
property l2_output_vars
property error_bit
class pysiral.filter.MarginalIceZoneFilterData

Data class for MarginalIceZoneFilterFlag NOTE: There will be several instances of this class per trajectory

if the ice edge is crossed multiple times

options: dict
ice_edge_idx: int
sea_ice_is_left: bool
ocean_idxs: numpy.ndarray
seaice_idxs: numpy.ndarray
leading_edge_width: numpy.ndarray
sea_ice_freeboard: numpy.ndarray
sea_ice_concentration: numpy.ndarray
distance_to_ocean: numpy.ndarray
footprint_spacing: float
ocean_leading_edge_width_at_ice_edge: float = None
sea_ice_freeboard_filtered: numpy.ndarray = None
sea_ice_freeboard_gradient: numpy.ndarray = None
filter_flag: numpy.ndarray = None
debug_plot()

Create an overview plot of the filter result :return:

property n_records: int
property has_flag: bool
class pysiral.filter.MarginalIceZoneFilterFlag(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Create a flag value that can be used to filter freeboard/thickness values that are affected by surface waves penetrating the marginal ice zone. The filter flag is not applied to any geophysical variables, but added to the l2 data container.

The flag can take the following values:

0: not in marginal ice zone 1: in marginal ice zone: light to none wave influence detected 2: in marginal ice zone: wave influence detected

The flag values depend on:

  • leading edge with of ocean waveforms at the ice edge

  • sea ice freeboard gradient as a function of distance to the ice edge

Thresholds to determine the flag values need to be specified in the options of the Level2 processor definition file:

  • module: filter pyclass: MarginalIceZoneFilterFlag options:

    sea_ice_filter_size_m: <freeboard smoothing filter size>. ocean_filter_size_m: <ocean>. freeboard_smoother_filter_size_m: 150000. sea_ice_freeboard_miz_gradient: 0.002 leading_edge_width_ocean_value: <threshold for ocean leading width>

execute_procstep(l1b: Level1bData, l2: Level2Data) numpy.ndarray

API method for Level2ProcessorStep subclasses. Computes and add the filter flag to the l2 data object :param l1b: :param l2: :return: Error flag array

get_miz_filter_flag(leading_edge_width: numpy.ndarray, leading_edge_width_rolling_mean: numpy.ndarray, pulse_peakiness_rolling_sdev: numpy.ndarray, sea_ice_freeboard: numpy.ndarray, sea_ice_concentration: numpy.ndarray, distance_to_ocean: numpy.ndarray, distance_to_low_ice_concentration: numpy.ndarray, footprint_spacing: float) Tuple[numpy.ndarray, None | List[MarginalIceZoneFilterData]]

Compute the filter flag

Parameters:
  • leading_edge_width

  • leading_edge_width_rolling_mean

  • pulse_peakiness_rolling_sdev

  • sea_ice_freeboard

  • sea_ice_concentration

  • distance_to_ocean

  • distance_to_low_ice_concentration

  • footprint_spacing

Returns:

get_miz_filter_flag_ice_edge_transition(leading_edge_width, sea_ice_concentration, sea_ice_freeboard, distance_to_ocean, footprint_spacing) Tuple[numpy.ndarray, None | List[MarginalIceZoneFilterData]]

Get the filter flag for ice edge crossings

Parameters:
  • leading_edge_width

  • sea_ice_concentration

  • sea_ice_freeboard

  • distance_to_ocean

  • footprint_spacing

Returns:

get_marginal_ice_zone_segments(sea_ice_concentration: numpy.ndarray, distance_to_ocean: numpy.ndarray, footprint_spacing: float) List | None

Find any transitions between sea ice / open water areas determined by sea ice concentration crossing the 15% threshold. :param sea_ice_concentration: :param distance_to_ocean: :param footprint_spacing: :return: List of indices marking the ice edge (e.g. first ice waveform).

compute_marginal_ice_zone_filter_flag(data: MarginalIceZoneFilterData) None

Compute the data properties in the marginal ice zone for the filter classification :param data: :return: None (miz prop is changed in-place)

static get_filtered_value_and_gradient(x: numpy.ndarray, y: numpy.ndarray, filter_size: int, gradient_scale_factor: float = 1.0) Tuple[numpy.ndarray, numpy.ndarray]

Compute a filtered version and its gradient of a noisy and gappy variable (In this case likely freeboard) :param x: :param y: :param filter_size: :param gradient_scale_factor: :return:

static get_impacted_range(sea_ice_freeboard_filtered: numpy.ndarray, sea_ice_freeboard_gradient: numpy.ndarray, ice_edge_idx: int, sea_ice_is_left: bool) numpy.ndarray

Compute the impacted area which is defined as the range between the nearest point to the ice edge to the point where the sea ice freeboard gradient show the first zero crossing (-> reversal of freeboard trend). This method should only be called, when it is quite certain that the freeboard is impacted by wave.

Parameters:
  • sea_ice_freeboard_filtered

  • sea_ice_freeboard_gradient

  • ice_edge_idx

  • sea_ice_is_left

Returns:

Indices Array (potentially empty)

get_miz_filter_flag_proximity_based(distance_to_low_ice_concentration: numpy.ndarray, sea_ice_concentration: numpy.ndarray, leading_edge_width_rolling_mean: numpy.ndarray, pulse_peakiness_rolling_sdev: numpy.ndarray) numpy.ndarray | None

Compute the MIZ Flag based on a set of thresholds only. Conditions

Parameters:
  • distance_to_low_ice_concentration

  • sea_ice_concentration

  • leading_edge_width_rolling_mean

  • pulse_peakiness_rolling_sdev

Returns:

static get_default_filter_flag(n_records: int, boolean_flag_values: bool) numpy.ndarray
property l2_input_vars
property l2_output_vars
property error_bit
class pysiral.filter.SAMOSAMarginalIceZoneFilterFlag(*args, **kwargs)

Bases: pysiral.l2proc.procsteps.Level2ProcessorStep

Create a flag value that can be used to filter freeboard/thickness values that are affected by surface waves penetrating the marginal ice zone based on output from the SAMOSA+ algorithm.

The flag can take the following values:

0: not in marginal ice zone 1: in marginal ice zone: light to none wave influence detected 2: in marginal ice zone: wave influence detected

The flag values depend on:

  • leading edge with of ocean waveforms at the ice edge

  • sea ice freeboard gradient as a function of distance to the ice edge

Thresholds to determine the flag values need to be specified in the options of the Level2 processor definition file:

  • module: filter pyclass: SAMOSAMarginalIceZoneFilterFlag options:

    max_ocean_proximity: <maximum distance to ocean in meter> min_significant_waveheight: <minimum significant wave height in meter>

execute_procstep(l1b: Level1bData, l2: Level2Data) numpy.ndarray

API method for Level2ProcessorStep subclasses. Computes and add the filter flag to the l2 data object

Parameters:
  • l1b

  • l2

Returns:

Error flag array

property l2_input_vars
property l2_output_vars
property error_bit
pysiral.filter.numpy_smooth(x, window)
pysiral.filter.scipy_smooth(x, window)

Numpy implementation of the IDL SMOOTH function

pysiral.filter.astropy_smooth(x, window, **kwargs)
pysiral.filter.interp1d_gap_filling(y: numpy.ndarray, **interp_kwargs) numpy.ndarray

Fill not-finite gaps by linear interpolation using `scipy.interp1d`with bounds_error turned off by default. Keywords to this function are passed to interp1d. :param y: :return:

pysiral.filter.lowess_smooth(x: numpy.ndarray, y: numpy.ndarray, window: int) numpy.ndarray

Simple lowess smoother :param x: :param y: :param window: :return:

pysiral.filter.idl_smooth(x: numpy.ndarray, window: int) numpy.ndarray

Implementation of the IDL smooth(x, window, /EDGE_TRUNCATE, /NAN)

pysiral.filter.spline_smooth(y, window)
pysiral.filter.fill_nan(y)
pysiral.filter.smooth_2darray(array, filter_width=5, preserve_gaps=True)

A simple smoothing filter