pysiral.filter ============== .. py:module:: pysiral.filter .. autoapi-nested-parse:: Created on Sat Apr 23 15:30:53 2016 @author: Stefan Hendricks Classes ------- .. autoapisummary:: pysiral.filter.L1bEnvisatBackscatterDriftCorrection pysiral.filter.L2ParameterValidRange pysiral.filter.RemoveNonOceanData pysiral.filter.ParameterSmoother pysiral.filter.MarginalIceZoneFilterData pysiral.filter.MarginalIceZoneFilterFlag pysiral.filter.SAMOSAMarginalIceZoneFilterFlag Functions --------- .. autoapisummary:: pysiral.filter.numpy_smooth pysiral.filter.scipy_smooth pysiral.filter.astropy_smooth pysiral.filter.interp1d_gap_filling pysiral.filter.lowess_smooth pysiral.filter.idl_smooth pysiral.filter.spline_smooth pysiral.filter.fill_nan pysiral.filter.smooth_2darray Module Contents --------------- .. py:class:: L1bEnvisatBackscatterDriftCorrection(*args, **kwargs) Bases: :py:obj:`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 .. py:method:: execute_procstep(l1b, l2) Apply a backscatter correction :param l1b: :param l2: :return: .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:class:: L2ParameterValidRange(*args, **kwargs) Bases: :py:obj:`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: target_variables: [] valid_minimum_point_value: valid_maximum_point_value: will lead to that all target_variables will be set to np.nan if either source_variable < min_val of source_variable > max_val .. py:method:: execute_procstep(l1b, l2) Mandatory method for Level2ProcessorStep will change l2 data object in place :param l1b: :param l2: :return: .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:class:: RemoveNonOceanData(*args, **kwargs) Bases: :py:obj:`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: [] 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. .. py:method:: execute_procstep(l1b: Level1bData, l2: Level2Data) -> numpy.ndarray .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:class:: ParameterSmoother(*args, **kwargs) Bases: :py:obj:`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: target_variable_name: target_variable_id: smoothing_method: 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 .. py:method:: execute_procstep(l1b, l2) Compute the smoother :param l1b: :param l2: :return: .. py:method:: box_filter_smoother(x, window=5) :staticmethod: .. py:method:: lowess_smoother(y, **smoother_args) :staticmethod: .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:class:: MarginalIceZoneFilterData Data class for MarginalIceZoneFilterFlag NOTE: There will be several instances of this class per trajectory if the ice edge is crossed multiple times .. py:attribute:: options :type: dict .. py:attribute:: ice_edge_idx :type: int .. py:attribute:: sea_ice_is_left :type: bool .. py:attribute:: ocean_idxs :type: numpy.ndarray .. py:attribute:: seaice_idxs :type: numpy.ndarray .. py:attribute:: leading_edge_width :type: numpy.ndarray .. py:attribute:: sea_ice_freeboard :type: numpy.ndarray .. py:attribute:: sea_ice_concentration :type: numpy.ndarray .. py:attribute:: distance_to_ocean :type: numpy.ndarray .. py:attribute:: footprint_spacing :type: float .. py:attribute:: ocean_leading_edge_width_at_ice_edge :type: float :value: None .. py:attribute:: sea_ice_freeboard_filtered :type: numpy.ndarray :value: None .. py:attribute:: sea_ice_freeboard_gradient :type: numpy.ndarray :value: None .. py:attribute:: filter_flag :type: numpy.ndarray :value: None .. py:method:: debug_plot() Create an overview plot of the filter result :return: .. py:property:: n_records :type: int .. py:property:: has_flag :type: bool .. py:class:: MarginalIceZoneFilterFlag(*args, **kwargs) Bases: :py:obj:`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: . ocean_filter_size_m: . freeboard_smoother_filter_size_m: 150000. sea_ice_freeboard_miz_gradient: 0.002 leading_edge_width_ocean_value: .. py:method:: 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 .. py:method:: 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, Union[None, List[MarginalIceZoneFilterData]]] Compute the filter flag :param leading_edge_width: :param leading_edge_width_rolling_mean: :param pulse_peakiness_rolling_sdev: :param sea_ice_freeboard: :param sea_ice_concentration: :param distance_to_ocean: :param distance_to_low_ice_concentration: :param footprint_spacing: :return: .. py:method:: get_miz_filter_flag_ice_edge_transition(leading_edge_width, sea_ice_concentration, sea_ice_freeboard, distance_to_ocean, footprint_spacing) -> Tuple[numpy.ndarray, Union[None, List[MarginalIceZoneFilterData]]] Get the filter flag for ice edge crossings :param leading_edge_width: :param sea_ice_concentration: :param sea_ice_freeboard: :param distance_to_ocean: :param footprint_spacing: :return: .. py:method:: get_marginal_ice_zone_segments(sea_ice_concentration: numpy.ndarray, distance_to_ocean: numpy.ndarray, footprint_spacing: float) -> Union[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). .. py:method:: 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) .. py:method:: 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] :staticmethod: 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: .. py:method:: 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 :staticmethod: 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. :param sea_ice_freeboard_filtered: :param sea_ice_freeboard_gradient: :param ice_edge_idx: :param sea_ice_is_left: :return: Indices Array (potentially empty) .. py:method:: 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) -> Union[numpy.ndarray, None] Compute the MIZ Flag based on a set of thresholds only. Conditions :param distance_to_low_ice_concentration: :param sea_ice_concentration: :param leading_edge_width_rolling_mean: :param pulse_peakiness_rolling_sdev: :return: .. py:method:: get_default_filter_flag(n_records: int, boolean_flag_values: bool) -> numpy.ndarray :staticmethod: .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:class:: SAMOSAMarginalIceZoneFilterFlag(*args, **kwargs) Bases: :py:obj:`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: min_significant_waveheight: .. py:method:: 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 .. py:property:: l2_input_vars .. py:property:: l2_output_vars .. py:property:: error_bit .. py:function:: numpy_smooth(x, window) .. py:function:: scipy_smooth(x, window) Numpy implementation of the IDL SMOOTH function .. py:function:: astropy_smooth(x, window, **kwargs) .. py:function:: 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: .. py:function:: lowess_smooth(x: numpy.ndarray, y: numpy.ndarray, window: int) -> numpy.ndarray Simple lowess smoother :param x: :param y: :param window: :return: .. py:function:: idl_smooth(x: numpy.ndarray, window: int) -> numpy.ndarray Implementation of the IDL smooth(x, window, /EDGE_TRUNCATE, /NAN) .. py:function:: spline_smooth(y, window) .. py:function:: fill_nan(y) .. py:function:: smooth_2darray(array, filter_width=5, preserve_gaps=True) A simple smoothing filter