LIDAR signal filtering#
This page documents SignalCreation.Lidar.Lidar.filtering(), and details the available
filter kernels, the ways to set the number of coefficients over altitude, and the
NDACC-compliant resolution methodologies implemented in SignalCreation.Lidar.Filter.Filter.
Overview#
Selects input variables by prefix (default:
preprocess) and bySignal_Type(default:[100,119]).Builds a
Filterobject with the requested filter name.Computes the number of coefficients per altitude via one of several strategies (fixed, DIAL polynomial, linear).
Applies the filter to value and uncertainty (optional PR2 and/or log-space transform).
Computes resolution using NDACC transfer function (DF) and/or impulse response (IR) methods, and also the originator method.
Saves filtered data, uncertainties, number-of-points, and resolution arrays to the dataset.
Function signature#
def filtering(
self,
list_data_name: list | None = None,
error_suffix: None | str = None,
input_prefix: str | None = None,
prefix_output: str | None = None,
filter_output: str | None = None,
resolution_output_origin: str | None = None,
resolution_output_ndacc_df: str | None = None,
resolution_output_ndacc_ir: str | None = None,
resolution_methodology: str | list | None = None,
list_signal_type: list | np.ndarray | None = None,
name_param_tag: str = "Filtering",
use_pr2: bool = False,
use_log: bool = False,
) -> None
Configuring the filter#
### Available filter names
These map to static methods in Filter and determine the kernel shape.
Filter name (string) |
Type |
Notes |
|---|---|---|
|
Low-pass |
|
|
Derivative |
Antisymmetric coefficients (1st derivative) |
|
Low-pass |
Flat window / moving average |
|
Low-pass |
Hann window (normalized) |
|
Low-pass |
Hamming window (normalized) |
|
Low-pass |
Blackman window (normalized) |
|
Low-pass (needs fcut) |
Ideal sinc truncation with cutoff |
|
Low-pass (needs fcut) |
Windowed-sinc, Hann |
|
Low-pass (needs fcut) |
Windowed-sinc, Hamming |
|
Low-pass (needs fcut) |
Windowed-sinc, Blackman |
|
Low-pass |
Normalized binomial coefficients |
Notes
- Type: filters are detected as low-pass (symmetric kernel) or derivative (antisymmetric kernel).
- Filters marked needs fcut accept a cutoff parameter fcut via the parameter dict used when computing coefficients.
- Some implementations accept a generic atten key, but the current kernels use mainly fcut.
- For derivative filters, an extra division by \(\Delta z\) (altitude sampling) is applied after convolution to yield the correct derivative units.
Setting the number of coefficients over altitude#
The number of coefficients \(N(z)\) can vary with altitude. The following strategies are available
via Filter.calculate_nb_coef_over_altitude(method, parameters)():
Fixed number of points (
"fixed number points"/ constant window)Parameters:
value(int, default 50).Resulting window length is forced to odd internally (for symmetry).
DIAL polynomial (
"dial poly")Parameters:
ican1,ican2,ncan1,ncan2,ncanmin,ncanmax(defaults: 400, 1200, 50, 400, 1, 200).Window evolves quadratically between indices
ican1andican2, bounded byncanmin/ncanmax.Final length is odd: \(N(z)=2\cdot \lfloor \mathrm{something}\rfloor + 1\).
Linear (
"linear")Parameters:
alt_min,alt_max,n_min,n_max(defaults: 0 m, 50 km, 1, 400).Linearly interpolates the window length between altitude bounds, then rounds to the nearest odd integer.
After computing \(N(z)\), Filter.calculate_coefficients() pre-computes unique kernels
used during the convolution.
Applying the filter#
Inputs: value and uncertainty are fetched with
tf.xr_get_data_and_unc().Optional transforms: -
use_pr2=True→ apply to \(P r^2\) (and its uncertainty). -use_log=True→ apply to \(\log(\cdot)\); uncertainty handled viatf.xr_log().Convolution: altitude-dependent kernel is applied per-altitude; if any NaN exists in the window, the corresponding output altitude is set to NaN.
Units: if the input has pint units, they are preserved; derivative filters divide by \(\Delta z\) automatically.
Resolution methodologies#
Three resolution definitions are provided and may be saved:
NDACC — transfer function (DF) Uses
transfer_function(). The magnitude of the transfer function \(H(f)\) is computed from the kernel, the cutoff frequency \(f_c\) is defined by \(H(f_c)=0.5\), and the resolution is\[\mathrm{Resolution}_{\mathrm{DF}} = \frac{1}{2 f_c} \times \Delta z\]where \(\Delta z\) is the vertical sampling (pint-aware). The method also supports returning the full transfer function matrix for diagnostics. Files can be cached to NetCDF when enabled.
NDACC — impulse response (IR) Uses
impulse_response(). The impulse response \(h\) is normalized to 1 at peak, and the resolution is computed from the FWHM via linear interpolation around 0.5; equivalently\[\mathrm{Resolution}_{\mathrm{IR}} = \mathrm{FWHM}(h) \times \Delta z.\]Originator method
Filter.get_resol_init_matlab_software()implements the legacy (MATLAB) formula:\[\mathrm{Resolution}_{\mathrm{orig}} = \frac{\Delta z}{\left(\frac{N/2}{a}\right)^{1/b}},\quad a=0.664,\; b=-1.046,\]where \(N\) is the odd window length at each altitude.
Outputs and shapes
- output="resolution" → 1D profile over altitude with units of altitude.
- output="matrix" → 2D matrix:
DF: dims
['altitude','frequency']with frequency coordinate (scaled by \(\Delta z\)).IR: dims
['altitude','nf']with the impulse-response vector.
Caching and performance
- If use_ndacc_resol_file=True, DF/IR results can be read/written to NetCDF files
(filenames configurable via filenames_ndacc_resol = {'df': ..., 'ir': ...}) to speed up repeated runs.
- Multiprocessing is used for DF calculations when enabled (use_multiprocessing=True).
Processing steps (updated)#
Discover inputs (by prefix and
Signal_Type) iflist_data_namenot provided.Instantiate Filter(filter_name) from XML
Filtering/filter_name(default:"Savitzky-Golay").Compute N(z) via
Filter.calculate_nb_coef_over_altitude()using XMLFiltering/mode_number_pointsand its child parameters; write back final parameters to XML.Apply filter to value and uncertainty (with PR2/log options if requested).
Compute resolution according to
Filtering/resolution_methodology(one or more ofdf, ir, origin) and save each under the dedicated prefixes (resolution_ndacc_df,resolution_ndacc_ir,resolution_origin).Write outputs: filtered signal under
prefix_output, number-of-points underfilter_output, and attach attributes includingSignal_Type,ancillary_variables, andResolutionlist.
Example (XML)#
<Filtering>
<filter_name>Savitzky-Golay</filter_name>
<mode_number_points>dial poly</mode_number_points>
<mode_number_points>
<ican1>400</ican1>
<ican2>1200</ican2>
<ncan1>50</ncan1>
<ncan2>400</ncan2>
<ncanmin>1</ncanmin>
<ncanmax>200</ncanmax>
</mode_number_points>
<resolution_methodology options="df,ir,origin" multiple_options="True">df,ir</resolution_methodology>
</Filtering>