marine_qc.helpers package

Marine Quality Control helpers package.

class marine_qc.helpers.Climatology(data, time_axis=None, lat_axis=None, lon_axis=None, source_units=None, target_units=None, valid_ntime=None)[source]

Bases: object

Class for dealing with climatologies, reading, extracting values etc.

Automatically detects if this is a single field, pentad or daily climatology.

Parameters:
  • data (xarray.DataArray) – Climatology data.

  • time_axis (str, optional) – Name of time axis. Set if time axis in data is not CF compatible.

  • lat_axis (str, optional) – Name of latitude axis. Set if latitude axis in data is not CF compatible.

  • lon_axis (str, optional) – Name of longitude axis. Set if longitude axis in data is not CF compatible.

  • source_units (str, optional) – Name of units in data. Set if units are not defined in data.

  • target_units (str, optional) – Name of target units to which units must conform.

  • valid_ntime (int or list, default: [1, 73, 365]) – Number of valid time steps: - 1: single field climatology - 73: pentad climatology - 365: daily climatology

convert_units_to(target_units, source_units=None)[source]

Convert units to user-specific units.

Parameters:
  • target_units (str) – Target units to which units must conform.

  • source_units (str, optional) – Source units if not specified in Climatology.

Return type:

None

Notes

For more information see: xclim.core.units.convert_units_to()

static get_t_index(month, day, ntime)[source]

Convert arrays of months and days to an array of indices for the grid.

Parameters:
  • month (numpy.ndarray) – Array of months.

  • day (numpy.ndarray) – Array of days.

  • ntime (int) – Number of time points in the grid, valid values are 1, 73 (pentad resolution) and 365 (daily resolution).

Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

get_tindex(month, day)[source]

Get the time index of the input month and day.

Parameters:
  • month (int) – Month for which the time index is required.

  • day (int) – Day for which the time index is required.

Return type:

int

Returns:

int – Time index for specified month and day.

get_value(lat, lon, date=None, month=None, day=None)[source]

Get the value from a climatology at the give position and time.

Parameters:
Return type:

ndarray | Series

Returns:

ndarray or pandas.Series – Climatology value at specified location and time.

Notes

Use only exact matches for selecting time and nearest valid index value for selecting location.

get_value_fast(lat, lon, date=None, month=None, day=None)[source]

Get the value from a climatology at the give position and time.

Parameters:
Return type:

ndarray | Series

Returns:

numpy.ndarray or pandas.Series – Climatology value at specified location and time.

Notes

Assumes that the grid is a regular latitude longitude grid. The alternative method get_value works with non-regular grids.

static get_x_index(lon_arr, lon_axis)[source]

Convert an array of longitudes to an array of indices for the grid.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

static get_y_index(lat_arr, lat_axis)[source]

Convert an array of latitudes to an array of indices for the grid.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

classmethod open_netcdf_file(file_name, clim_name, **kwargs)[source]

Open a NetCDF climatology file and construct a Climatology instance.

Parameters:
  • file_name (str or path-like) – Path to the NetCDF file to open.

  • clim_name (str) – Name of the climatology variable within the NetCDF file.

  • **kwargs (dict) – Additional keyword arguments passed to the Climatology constructor.

Return type:

Climatology

Returns:

Climatology – A Climatology instance constructed from the specified variable in the NetCDF file. If the file cannot be opened, an empty climatology object is returned.

class marine_qc.helpers.Flags[source]

Bases: object

Constants used to annotate quality control (QC) and duplicate-check results.

best = 1
duplicate = 2
failed = 1
passed = 0
unique = 0
untestable = 2
untested = 3
worst = 3
marine_qc.helpers.open_xrdataset(files, use_cftime=True, decode_cf=False, decode_times=False, parallel=False, data_vars='minimal', chunks='default', coords='minimal', compat='override', combine='by_coords', **kwargs)[source]

Optimized function for opening large CF-compliant datasets with xarray.

This implementation follows guidance from: https://github.com/pydata/xarray/issues/1385#issuecomment-561920115

decode_timedelta=False is added to leave variables and coordinates with time units in {“days”, “hours”, “minutes”, “seconds”, “milliseconds”, “microseconds”} encoded as numbers.

Parameters:
Return type:

Dataset

Returns:

xarray.Dataset – Opened xarray Dataset, optimized for large CF datasets.

Submodules

marine_qc.helpers.astronomical_geometry module

Some generally helpful astronomical geometry functions for base QC.

marine_qc.helpers.astronomical_geometry.azimuth_elevation(lat, declination, hour_angle)[source]

Get both azimuth and geometric elevation of sun.

Parameters:
  • lat (float) – Latitude value in degrees.

  • declination (float) – Declination.

  • hour_angle (float) – Hour angle.

Return type:

tuple[float, float]

Returns:

tuple of float – A tuple of two floats representing azimuth and geometric elevation of sun.

marine_qc.helpers.astronomical_geometry.calculate_azimuth(declination, hour_angle, elevation, phi)[source]

Calculate azimuth.

Parameters:
  • declination (float) – Declination.

  • hour_angle (float) – Hour angle.

  • elevation (float) – Elevation.

  • phi (float) – Latitude value in rad.

Return type:

float

Returns:

float – Azimuth.

marine_qc.helpers.astronomical_geometry.calculate_sun_parameters(time)[source]

Calculate both right ascension and declination of sun.

Parameters:

time (float) – Time value.

Return type:

tuple[float, float]

Returns:

tuple of float – A tuple of two floats representing right ascension and declination of sun.

marine_qc.helpers.astronomical_geometry.convert_degrees(deg)[source]

Convert degrees.

Parameters:

deg (float) – Value in degrees.

Return type:

float

Returns:

float – Degree (from 0 to 360).

marine_qc.helpers.astronomical_geometry.elliptic_angle(time)[source]

Get angle plane of elliptic to plane of celestial equator.

Parameters:

time (float) – Time value.

Return type:

float

Returns:

float – Angle plane of elliptic to plane of celestial equator.

marine_qc.helpers.astronomical_geometry.mean_earth_anomaly(time, theta)[source]

Calculate mean anomaly of earth (g).

Parameters:
  • time (float) – Time value.

  • theta (float) – Position of the sun.

Return type:

float

Returns:

float – Mean anomaly of the earth (g).

marine_qc.helpers.astronomical_geometry.sin_of_elevation(phi, declination, hour_angle)[source]

Get sinus of geometric elevation.

Parameters:
  • phi (float) – Latitude value in rad.

  • declination (float) – Declination.

  • hour_angle (float) – Hour angle.

Return type:

float

Returns:

float – Sinus of geometric elevation.

marine_qc.helpers.astronomical_geometry.sun_ascension(long_of_sun, sin_long_of_sun, angle_of_elliptic)[source]

Calculate right ascension.

Parameters:
  • long_of_sun (float) – Longitude of the sun.

  • sin_long_of_sun (float) – Sinus of the longitude of the sun.

  • angle_of_elliptic (float) – Angle of elliptic.

Return type:

float

Returns:

float – Right ascension.

marine_qc.helpers.astronomical_geometry.sun_azimuth(phi, declination)[source]

Get azimuth.

Parameters:
  • phi (float) – Latitude value in rad.

  • declination (float) – Declination.

Return type:

float

Returns:

float – Azimuth.

marine_qc.helpers.astronomical_geometry.sun_declination(sin_long_of_sun, angle_of_elliptic)[source]

Calculate declination of sun.

Parameters:
  • sin_long_of_sun (float) – Sinus of the longitude of the sun.

  • angle_of_elliptic (float) – Angle of elliptic.

Return type:

float

Returns:

float – Declination of sun.

marine_qc.helpers.astronomical_geometry.sun_hour_angle(local_siderial_time, right_ascension)[source]

Get hour angle.

Parameters:
  • local_siderial_time (float) – Local siderial time value.

  • right_ascension (float) – Right ascension.

Return type:

float

Returns:

float – Hour angle.

marine_qc.helpers.astronomical_geometry.sun_longitude(time)[source]

Get longitude of sun.

Parameters:

time (float) – Time value.

Return type:

float

Returns:

float – Longitude of the sun.

marine_qc.helpers.astronomical_geometry.sun_position(time)[source]

Find position of sun in celestial sphere, assuming circular orbit (radians).

Parameters:

time (float) – Time value.

Return type:

float

Returns:

float – Position of the sun.

marine_qc.helpers.astronomical_geometry.sunangle(year, day, hour, minute, sec, zone, dasvtm, lat, lon)[source]

Calculate the local azimuth and elevation of the sun at a specified location and time.

Parameters:
  • year (int) – Year.

  • day (int) – Day number of year starting with 1 for Jan 1st and running up to 365/6.

  • hour (int) – Hour.

  • minute (int) – Minute.

  • sec (int) – Second.

  • zone (int) – The local international time zone, counted westward from Greenwich.

  • dasvtm (int) – 1 if daylight saving time is in effect, otherwise 0.

  • lat (float) – Latitude in degrees, north is positive.

  • lon (float) – Longitude in degrees, east is positive.

Return type:

tuple[float, float, float, float, float, float]

Returns:

tuple of float – A tuple of six floats representing Azimuth angle of the sun (degrees east of north), Elevation of sun (degrees), Right ascension of sun (degrees), Hour angle of sun (degrees), Hour angle of local siderial time (degrees) and Declination of sun (degrees).

Notes

Copied from Rob Hackett’s area 28 Apr 1998 by J.Arnott. Add protection for ASIN near +/- 90 degrees 07 Jan 2002 by J.Arnott. Pythonised 25/09/2015 by J.J. Kennedy

The Python version gets within a fraction of a degree of the original Fortran code from which it was ported for a range of values. The differences are larger if single precision values are used suggesting that this is not the most numerically robust scheme.

marine_qc.helpers.astronomical_geometry.to_local_siderial_time(time, time_in_hours, delyear, lon)[source]

Convert to local siderial time.

Parameters:
  • time (float) – Time value.

  • time_in_hours (float) – Time value in hours.

  • delyear (int) – Relative year number.

  • lon (float) – Longitude value in degrees.

Return type:

float

Returns:

float – Local siderial time.

marine_qc.helpers.astronomical_geometry.to_siderial_time(time, delyear)[source]

Convert to siderial time.

Parameters:
  • time (float) – Time value.

  • delyear (int) – Relative year number.

Return type:

float

Returns:

float – Siderial time.

marine_qc.helpers.auxiliary module

Auxiliary functions for QC.

marine_qc.helpers.auxiliary.args_from_data(*params)[source]

Decorator that extracts positional arguments from a pandas.DataFrame.

If the decorated function is called with a data keyword argument, the specified columns are extracted from the pandas.DataFrame and passed to the function as positional arguments. This provides an alternative calling convention where required positional arguments can be supplied via a pandas.DataFrame instead.

The decorated function must be called using either positional arguments or the data keyword argument, but not both.

Parameters:

*params (str) – Name(s) of the pandas.DataFrame columns that correspond to the required positional arguments of the decorated function.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that wraps a function and allows its positional arguments to be obtained from a pandas.DataFrame passed via the data keyword argument.

Raises:

ValueError – If both positional arguments and data are provided.

marine_qc.helpers.auxiliary.convert_to(value, source_units, target_units)[source]

Convert a float or sequence from source units to target units.

Parameters:
  • value (SequenceNumberType) – A single float value, None, or a sequence (e.g., list, tuple, array-like) containing floats and/or None values. None values are passed through unchanged.

  • source_units (str) – The unit(s) of the input value(s), e.g., ‘degC’, ‘km/h’.

  • target_units (str) – The unit(s) to convert to, e.g., ‘K’, ‘m/s’. If set to “unknown”, the value(s) will be converted to the base SI units of the source_units, e.g., ‘degC’ to ‘kelvin’, ‘km/h’ to ‘meter/s’.

Return type:

SequenceNumberType

Returns:

SequenceNumberType – The converted value(s), preserving the input structure (scalar, list, tuple, array). None values remain unchanged.

Examples

>>> convert_to(100, "degC", "K")
373.15
>>> convert_to([0, 100], "degC", "K")
[273.15, 373.15]
>>> convert_to([None, 100], "degC", "K")
[None, 373.15]
>>> convert_to(5, "km", "unknown")  # Converts to base unit 'meter'
5000.0
marine_qc.helpers.auxiliary.convert_units(**units_by_name)[source]

Decorator to automatically convert specified function arguments to target units.

This decorator allows a function to accept inputs in various units and automatically converts them to desired target units before the function executes. It is especially useful for scientific or engineering functions where users may provide inputs in different unit systems.

Parameters:

**units_by_name (str) – Keyword arguments mapping function argument names to their target units. Special case: if a target unit is “unknown”, it will be converted to the base SI unit for the given source unit (e.g., “degC” ? “K”, “km/h” ? “m/s”).

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that converts specified parameters to the target units prior to executing the decorated function.

Notes

  • The decorated function must be called with a units keyword argument, which can be:
    • A dictionary mapping argument names to their source units, or

    • A single string unit applied to all arguments.

  • Parameters not listed in units_by_name are not converted.

  • Parameters with None values are skipped.

  • If a target unit is “unknown”, the value is converted to the base SI unit.

Examples

>>> @convert_units(temperature="K")
... def func_single(temperature):
...     print(f"Temperature: {temperature:.2f} K")
>>> func_single(25.0, units={"temperature": "degC"})
Temperature: 298.15 K
>>> @convert_units(speed="m/s", altitude="m")
... def func_multiple(speed, altitude):
...     print(f"Speed: {speed:.1f} m/s, Altitude: {altitude:.0f} m")
>>> func_multiple(72.0, 0.5, units={"speed": "km/h", "altitude": "km"})
Speed: 20.0 m/s, Altitude: 500 m
>>> @convert_units(distance="unknown")
... def func_base(distance):
...     print(f"Distance in SI units: {distance} m")
>>> func_base(1.2, units={"distance": "km"})
Distance in SI units: 1200.0 m
marine_qc.helpers.auxiliary.ensure_arrays(**values)[source]

Ensure that all input values are NumPy arrays.

Parameters:

**values (Mapping[str, Any]) – Mapping of names to values expected to be NumPy arrays.

Return type:

tuple[ndarray[tuple[Any, ...], dtype[Any]], ...]

Returns:

tuple of numpy.ndarray – A tuple containing the NumPy arrays corresponding to the input values, in the same order as provided.

Raises:

TypeError – If any input value is not a NumPy array.

marine_qc.helpers.auxiliary.format_return_type(result_array, *input_values, dtype=<class 'int'>, keep_index=False)[source]

Convert the result numpy array(s) to the same type as the input value.

If result_array is a tuple of arrays, format each element recursively, preserving the container type.

Parameters:
  • result_array (numpy.ndarray or tuple of numpy.ndarray) – The numpy array(s) of results.

  • *input_values (Any) – One or more original input values to infer the desired return type from.

  • dtype (type, optional, default: int) – Desired data type of the result.

  • keep_index (bool, default: True) – If True keep indexes from result_array, otherwise take indexes from input_values.

Return type:

Any

Returns:

Same type as input(s) – The result formatted to match the type of the first valid input value.

marine_qc.helpers.auxiliary.generic_decorator(pre_handler=None, post_handler=None)[source]

Create a decorator that binds function arguments and applies pre- and post-processing handlers.

This decorator factory allows you to inspect, modify, or validate function arguments before and after the original function is called. Reserved keyword arguments can be passed to the handlers via _decorator_kwargs and removed from the call to the original function.

Parameters:
  • pre_handler (Callable[[dict], None]) – A function that takes the bound arguments dictionary (bound_args.arguments) and optionally additional keyword arguments, to inspect or modify arguments before the decorated function executes. Signature: handler(arguments: dict, **meta_kwargs) -> None.

  • post_handler (Callable[[dict], None]) – A function that takes the bound arguments dictionary (bound_args.arguments) and optionally additional keyword arguments, to inspect or modify arguments after the decorated function executes. Signature: handler(arguments: dict, **meta_kwargs) -> None.

Return type:

Callable[..., Any]

Returns:

Callable – A decorator that wraps any function. When applied, the function’s arguments are bound and passed to the handlers before execution.

Notes

  • Handlers can define a _decorator_kwargs attribute (a set of reserved keyword argument names). These reserved kwargs will be extracted from the decorated function’s call kwargs, passed to the handler, and removed before calling the original function.

  • The original function is called with the possibly modified bound arguments after handler processing.

marine_qc.helpers.auxiliary.inspect_arrays(*params, sortby=None)[source]

Decorator to convert and validate specified function input parameters as 1D NumPy arrays.

This decorator ensures that specified input arguments are sequence-like, converts them to 1D NumPy arrays, validates that they are one-dimensional, and checks that all arrays have the same length. Optionally, the arrays can be sorted by another parameter and later restored to the original order.

Parameters:
  • *params (str) – Names of parameters to inspect in the decorated function. Each specified parameter will be converted to a 1D NumPy array and validated.

  • sortby (str, optional) – Name of a parameter to sort the arrays by, if desired. The result will be returned in the original order of this parameter.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that, when applied, converts the specified parameters to 1D NumPy arrays, validates them, optionally sorts them, and passes them to the decorated function.

Raises:

ValueError – If a specified parameter is missing from the function arguments. If any specified parameter is not one-dimensional. If the lengths of the specified arrays do not all match.

Notes

  • If sortby is specified, the result of the function is reordered to match the original order of sortby after the function executes.

Examples

>>> @inspect_arrays("a", "b")
... def add_arrays(a, b):
...     return a + b
>>> add_arrays([1, 2, 3], [4, 5, 6])
array([5, 7, 9])
>>> add_arrays([1, 2], [3, 4, 5])
Traceback (most recent call last):
    ...
ValueError: Input ['a', 'b'] must all have the same length.
marine_qc.helpers.auxiliary.is_scalar_like(x)[source]

Return True if the input is scalar-like.

A value is considered scalar-like if it is one of the following:

  • Built-in Python scalars: int, float, bool, None

  • Strings and bytes

  • NumPy scalars (subclasses of numpy.generic), e.g. numpy.int32, numpy.float64, numpy.datetime64

  • Zero-dimensional NumPy arrays (e.g. numpy.array(5))

  • Pandas scalar types:
    • pandas.Timestamp

    • pandas.Timedelta

    • pandas.NA

    • pandas.NaT

  • Python datetime types:
    • datetime.date

    • datetime.datetime

    • datetime.time

Container types such as lists, tuples, sets, dicts, pandas Series, pandas DataFrame, and NumPy arrays with one or more dimensions are not considered scalar-like.

Parameters:

x (Any) – The value to check.

Return type:

bool

Returns:

bool – True if x is scalar-like, False otherwise.

marine_qc.helpers.auxiliary.isvalid(inval)[source]

Check if a value(s) are numerically valid (not None or NaN).

Parameters:

inval (ValueNumberType) – Input value(s) to be tested.

Return type:

bool | ndarray[tuple[Any, ...], dtype[bool]]

Returns:

bool or numpy.ndarray of bool – Returns False where the input is None or NaN, True otherwise. Returns a boolean scalar if input is scalar, else a boolean array.

marine_qc.helpers.auxiliary.post_format_return_type(*params, dtype=<class 'int'>, multiple=False, keep_index=False)[source]

Decorator to format a function’s return value to match the type of its original input(s).

This decorator ensures that the output of the decorated function is converted back to the same structure/type as the original input(s) specified by params. It uses a context object (_ctx) if available to retrieve the original inputs before any preprocessing was applied. If no context is found, it falls back to the current bound arguments.

Parameters:
  • *params (str) – List of parameter names whose original input types should be used to format the return value.

  • dtype (type or list of type, optional, default: int) – Desired data type of the result. If multiple is True dtype can be a list of types.

  • multiple (bool, optional) – If True, assumes the function returns a sequence of results (e.g., a tuple), and applies format_return_type to each element individually. If False (default), applies format_return_type once on the entire result.

  • keep_index (bool, default: True) – If True keep indexes from result, otherwise take indexes from input.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that modifies the decorated function’s output to match the input types.

Notes

  • Assumes a TypeContext object may be passed via _ctx keyword argument, storing original input values for accurate type formatting.

  • Falls back gracefully if no context is available, using current arguments.

  • Useful when function inputs are preprocessed (e.g., converted to arrays), and the output should match the original input types.

marine_qc.helpers.calculate_humidity module

The CalcHums module contains a set of functions for calculating humidity variables.

At present, it can only cope with scalars, not arrays.

There are routines for: specific humidity from dew point temperature and temperature and pressure vapour pressure from dew point temperature and temperature and pressure relative humidity from dew point temperature and temperature and pressure wet bulb temperature from dew point temperature and temperature and pressure dew point depression from dew point temperature and temperature

There are also routines for: vapour pressure from specific humidity and pressure and temperature dew point temperature from vapour pressure and temperature and pressure relative humidity from vapour pressure and temperature and pressure wet bulb temperature from vapour pressure and dew point temperature and temperature (and pressure?)

Where vapour pressure is used as part of the equation a pseudo wet bulb temperature is calculated. If this is at or below 0 deg C then the ice bulb equation is used.

ALL NUMBERS ARE RETURNED TO ONE SIGNIFICANT DECIMAL FIGURE.

THIS ROUTINE CANNOT COPE WITH MISSING DATA

THIS ROUTINE HAS a roundit=True/False. The default is True - round to one decimal place. Otherwise - set roundit=False

Written by Kate Willett 7th Feb 2016

marine_qc.helpers.calculate_humidity.dpd(td, t, roundit=True)[source]

Calculate dew point depression from dew point temperature and dry bulb temperature.

Parameters:
  • td (float) – Dew point temperature in degrees C (array or scalar).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Dew point depression in degrees C (array or scalar).

Notes

Ref:

TESTED! dpd = dpd(10..,15.) dpd = 5.0

marine_qc.helpers.calculate_humidity.rh(td, t, p, roundit=True)[source]

Calculate relative humidity from dew point temperature, dry bulb temperature and pressure.

It calculates the saturated vapour pressure from t. It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even if vapour pressure is an array (CHECK). To test whether to apply the ice or water calculation a dewpoint and dry bulb temperature are needed. We can assume that the dry bulb t is the same as the wet bulb t at saturation. This allows calculation of a pseudo-wet bulb temperature (imprecise) first. If the wet bulb temperature is at or below 0 deg C then the ice calculation is used.

Parameters:
  • td (float) – Dew point temperature in degrees C (array or scalar).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Relative humidity in %rh (array or scalar).

Notes

Ref:

TESTED! rh = rh(10.,15.,1013.) rh = 72.0

marine_qc.helpers.calculate_humidity.sh(td, t, p, roundit=True)[source]

Calculate specific humidity dew point temperature, dry bulb temperature and pressure.

It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even if vapour pressure is an array (CHECK).

Parameters:
  • td (float) – Dew point temperature in degrees C (array or scalar).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Specific humidity in g/kg (array or scalar).

Notes

Peixoto & Oort, 1996, Ross & Elliott, 1996 Peixoto, J. P. and Oort, A. H.: The climatology of relative humidity in the atmosphere, J. Climate, 9, 3443?3463, 1996.

TESTED! sh = sh(10.,15.,1013.) sh = 7.6

marine_qc.helpers.calculate_humidity.sh_from_vap(e, p, roundit=True)[source]

Calculate specific humidity from vapour pressure and pressure.

It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even if vapour pressure is an array (CHECK).

Parameters:
  • e (float) – Vapour pressure in hPa (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Specific humidity in g/kg (array or scalar).

Notes

Peixoto & Oort, 1996, Ross & Elliott, 1996 Peixoto, J. P. and Oort, A. H.: The climatology of relative humidity in the atmosphere, J. Climate, 9, 3443?3463, 1996.

TESTED! sh = sh(10.,15.,1013.) sh = 7.6

marine_qc.helpers.calculate_humidity.td_from_vap(e, p, t, roundit=True)[source]

Calculate dew point depression from vapour pressure, pressure and dry bulb temperature.

It also requires temperature to check whether the wet bulb temperature is <= 0.0 - if so the ice bulb calculation is used.

Parameters:
  • e (float) – Vapour pressure in hPa (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Dew point depression in degrees C (array or scalar).

Notes

Buck 1981 Buck, A. L.: New equations for computing vapor pressure and enhancement factor, J. Appl. Meteorol., 20, 1527?1532, 1981. Jenson et al. 1990 Jensen, M. E., Burman, R. D., and Allen, R. G. (Eds.): Evapotranspiration and Irrigation Water Requirements: ASCE Manuals and Reports on Engineering Practices No. 70, American Society of Civil Engineers, New York, 360 pp., 1990.

TESTED! td = td_from_vap(12.3,1013.,15.) td = 10.0

marine_qc.helpers.calculate_humidity.vap(td, t, p, roundit=True)[source]

Calculate vapour pressure from dew point temperature, dry bulb temperature and pressure.

It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even if dewpoint temperature is an array (CHECK). To test whether to apply the ice or water calculation a dry bulb temperature is needed. This allows calculation of a pseudo-wet bulb temperature (imprecise) first. If the wet bulb temperature is at or below 0 deg C then the ice calculation is used.

Parameters:
  • td (float) – Dew point temperature in degrees C (array or scalar).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Vapour pressure in hPa (array or scalar).

Notes

Buck 1981 Buck, A. L.: New equations for computing vapor pressure and enhancement factor, J. Appl. Meteorol., 20, 1527?1532, 1981. Jenson et al. 1990 Jensen, M. E., Burman, R. D., and Allen, R. G. (Eds.): Evapotranspiration and Irrigation Water Requirements: ASCE Manuals and Reports on Engineering Practices No. 70, American Society of Civil Engineers, New York, 360 pp., 1990.

TESTED! e = vap(10.,15.,1013.) e = 12.3

marine_qc.helpers.calculate_humidity.vap_from_sh(sh, p, roundit=True)[source]

Calculate vapour pressure from specific humidity and pressure.

It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even if specific humidity is an array (CHECK).

Parameters:
  • sh (float) – Specific humidity in g/kg (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Vapour pressure in hPa (array or scalar).

Notes

Peixoto & Oort, 1996, Ross & Elliott, 1996 Peixoto, J. P. and Oort, A. H.: The climatology of relative humidity in the atmosphere, J. Climate, 9, 3443?3463, 1996.

TESTED! e = vap_from_sh(7.6,1013.) e = 12.3

marine_qc.helpers.calculate_humidity.wb(td, t, p, roundit=True)[source]

Calculate wet bulb temperature from dew point temperature, dry bulb temperature and pressure.

It requires a sea (station actually but sea level ok for marine data) level pressure value. This can be a scalar or an array, even ifvapour pressure is an array (CHECK). To test whether to apply the ice or water calculation a dewpoint and dry bulb temperature are needed. This allows calculation of a pseudo-wet bulb temperature (imprecise) first. If the wet bulb temperature is at or below 0 deg C then the ice calculation is used.

Parameters:
  • td (float) – Dew point temperature in degrees C (array or scalar).

  • t (float) – Dry bulb temperature in degrees C (array or scalar).

  • p (float) – Pressure at observation level in hPa (array or scalar - can be scalar even if others are arrays).

  • roundit (bool) – Flag to tell function to round to one decimal place, default TRUE.

Return type:

float

Returns:

float – Wet bulb temperature in degrees C (array or scalar).

Notes

Ref: Jenson et al. 1990 Jensen, M. E., Burman, R. D., and Allen, R. G. (Eds.): Evapotranspiration and Irrigation Water Requirements: ASCE Manuals and Reports on Engineering Practices No. 70, American Society of Civil Engineers, New York, 360 pp., 1990.

TESTED! wb = wb(10.,15.,1013) wb = 12.2

marine_qc.helpers.external_clim module

Module to read external climatology files.

class marine_qc.helpers.external_clim.Climatology(data, time_axis=None, lat_axis=None, lon_axis=None, source_units=None, target_units=None, valid_ntime=None)[source]

Bases: object

Class for dealing with climatologies, reading, extracting values etc.

Automatically detects if this is a single field, pentad or daily climatology.

Parameters:
  • data (xarray.DataArray) – Climatology data.

  • time_axis (str, optional) – Name of time axis. Set if time axis in data is not CF compatible.

  • lat_axis (str, optional) – Name of latitude axis. Set if latitude axis in data is not CF compatible.

  • lon_axis (str, optional) – Name of longitude axis. Set if longitude axis in data is not CF compatible.

  • source_units (str, optional) – Name of units in data. Set if units are not defined in data.

  • target_units (str, optional) – Name of target units to which units must conform.

  • valid_ntime (int or list, default: [1, 73, 365]) – Number of valid time steps: - 1: single field climatology - 73: pentad climatology - 365: daily climatology

convert_units_to(target_units, source_units=None)[source]

Convert units to user-specific units.

Parameters:
  • target_units (str) – Target units to which units must conform.

  • source_units (str, optional) – Source units if not specified in Climatology.

Return type:

None

Notes

For more information see: xclim.core.units.convert_units_to()

static get_t_index(month, day, ntime)[source]

Convert arrays of months and days to an array of indices for the grid.

Parameters:
  • month (numpy.ndarray) – Array of months.

  • day (numpy.ndarray) – Array of days.

  • ntime (int) – Number of time points in the grid, valid values are 1, 73 (pentad resolution) and 365 (daily resolution).

Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

get_tindex(month, day)[source]

Get the time index of the input month and day.

Parameters:
  • month (int) – Month for which the time index is required.

  • day (int) – Day for which the time index is required.

Return type:

int

Returns:

int – Time index for specified month and day.

get_value(lat, lon, date=None, month=None, day=None)[source]

Get the value from a climatology at the give position and time.

Parameters:
Return type:

ndarray | Series

Returns:

ndarray or pandas.Series – Climatology value at specified location and time.

Notes

Use only exact matches for selecting time and nearest valid index value for selecting location.

get_value_fast(lat, lon, date=None, month=None, day=None)[source]

Get the value from a climatology at the give position and time.

Parameters:
Return type:

ndarray | Series

Returns:

numpy.ndarray or pandas.Series – Climatology value at specified location and time.

Notes

Assumes that the grid is a regular latitude longitude grid. The alternative method get_value works with non-regular grids.

static get_x_index(lon_arr, lon_axis)[source]

Convert an array of longitudes to an array of indices for the grid.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

static get_y_index(lat_arr, lat_axis)[source]

Convert an array of latitudes to an array of indices for the grid.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Array of indices.

classmethod open_netcdf_file(file_name, clim_name, **kwargs)[source]

Open a NetCDF climatology file and construct a Climatology instance.

Parameters:
  • file_name (str or path-like) – Path to the NetCDF file to open.

  • clim_name (str) – Name of the climatology variable within the NetCDF file.

  • **kwargs (dict) – Additional keyword arguments passed to the Climatology constructor.

Return type:

Climatology

Returns:

Climatology – A Climatology instance constructed from the specified variable in the NetCDF file. If the file cannot be opened, an empty climatology object is returned.

marine_qc.helpers.external_clim.get_climatological_value(climatology, **kwargs)[source]

Get the value from a climatology.

Parameters:
  • climatology (Climatology) – Climatology class.

  • **kwargs (dict) – Pass keyword-arguments to :py:func:~Climatology.get_value`.

Return type:

ndarray

Returns:

ndarray – Climatology value at specified location and time.

marine_qc.helpers.external_clim.inspect_climatology(*climatology_keys, optional=None)[source]

A decorator factory to preprocess function arguments that may be Climatology objects.

This decorator inspects the specified function arguments and normalizes them to concrete numerical values before the decorated function is executed. Supported input types include raw numeric values, xarray objects, file paths, and Climatology instances.

Parameters:
  • *climatology_keys (str) – Names of required function arguments to be inspected. These should be arguments that may be:

    • a numeric value

    • a xarray.DataArray

    • a xarray.Dataset

    • a string or path-like object pointing to a valid NetCDF file on disk

    • a Climatology instance

    If a Climatology object (or an object convertible to one) is detected, it will be resolved to a concrete value using its .get_value_fast(**kwargs) method.

  • optional (str or sequence of str, optional) – Argument names that should be treated as optional. If they are explicitly passed when the decorated function is called, they will be treated the same way as climatology_keys.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that wraps the target function, processing specified arguments before the function is called.

Raises:
  • TypeError – If a required climatology argument is missing from the decorated function call

  • ValueError – If an xarray.Dataset is provided without specifying clim_name, or if a string/Path input does not point to a valid file on disk.

Warns:

UserWarning – Issued if required keyword arguments for get_value_fast() are missing. This warning does not stop execution; missing values are replaced with numpy.nan.

Notes

  • xarray.Dataset inputs require the keyword argument clim_name to select the relevant data variable.

  • xarray.DataArray inputs are automatically wrapped in a Climatology object.

  • String or path-like inputs must point to an existing file and are opened via open_netcdf_file().

  • If a Climatology object is processed, it is resolved using .get_value_fast(**kwargs).

  • If required keyword arguments for .get_value_fast() are missing, a warning is issued.

  • If resolution fails due to TypeError or ValueError, the value is replaced with numpy.nan.

marine_qc.helpers.external_clim.open_xrdataset(files, use_cftime=True, decode_cf=False, decode_times=False, parallel=False, data_vars='minimal', chunks='default', coords='minimal', compat='override', combine='by_coords', **kwargs)[source]

Optimized function for opening large CF-compliant datasets with xarray.

This implementation follows guidance from: https://github.com/pydata/xarray/issues/1385#issuecomment-561920115

decode_timedelta=False is added to leave variables and coordinates with time units in {“days”, “hours”, “minutes”, “seconds”, “milliseconds”, “microseconds”} encoded as numbers.

Parameters:
Return type:

Dataset

Returns:

xarray.Dataset – Opened xarray Dataset, optimized for large CF datasets.

marine_qc.helpers.location_control module

Some generally helpful location control functions for base QC.

marine_qc.helpers.location_control.fill_missing_vals(q11, q12, q21, q22)[source]

Fill missing values.

For a group of four neighbouring grid boxes which form a square, with values q11, q12, q21, q22, fill gaps using means of neighbours.

Parameters:
  • q11 (float) – Value of first gridbox.

  • q12 (float) – Value of second gridbox.

  • q21 (float) – Value of third gridbox.

  • q22 (float) – Value of fourth gridbox.

Return type:

tuple[float | None, float | None, float | None, float | None]

Returns:

tuple of float – A tuple of four floats representing neighbour means.

marine_qc.helpers.location_control.filler(value_to_fill, neighbour1, neighbour2, opposite)[source]

Fill invalid values.

If the value_to_fill is invalid it is replaced with the mean of the neighbours and if it is still invalid then it is replaced with the value from the opposite member.

Parameters:
  • value_to_fill (float) – The value to fill.

  • neighbour1 (float) – The first neighbour.

  • neighbour2 (float) – The second neighbour.

  • opposite (float) – The opposite member.

Return type:

float | None

Returns:

float – Filled invalid input values.

marine_qc.helpers.location_control.get_four_surrounding_points(lat, lon, res, max90=True)[source]

Get the four surrounding points of a specified latitude and longitude point.

Parameters:
  • lat (float) – Latitude of point.

  • lon (float) – Longitude of point.

  • res (int) – Resolution of the grid in degrees.

  • max90 (bool, default: True) – If True then cap latitude at 90.0, otherwise don’t cap latitude.

Return type:

tuple[float, float, float, float]

Returns:

tuple of floats – A tuple of floats representing the longitudes of the leftmost and rightmost pairs of points, and the latitudes of the topmost and bottommost pairs of points.

marine_qc.helpers.location_control.lat_to_yindex(lat, res)[source]

For a given latitude return the y index in a 1x1x5-day global grid.

Parameters:
  • lat (float) – Latitude of the point.

  • res (float) – Resolution of grid in degrees.

Return type:

int

Returns:

int – Grid box index.

Notes

The routine assumes that the structure of the SST array is a grid that is 360 x 180 x 73 i.e. one year of 1degree lat x 1degree lon data split up into pentads. The west-most box is at 180degrees with index 0 and the northernmost box also has index zero. Inputs on the border between grid cells are pushed south.

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.lon_to_xindex(lon, res)[source]

For a given longitude return the x index in a 1x1x5-day global grid.

Parameters:
  • lon (float) – Longitude of the point.

  • res (float) – Resolution of grid in degrees.

Return type:

int

Returns:

int – Grid box index.

Notes

The routine assumes that the structure of the SST array is a grid that is 360 x 180 x 73 i.e. one year of 1degree lat x 1degree lon data split up into pentads. The west-most box is at 180degrees W with index 0 and the northernmost box also has index zero. Inputs on the border between grid cells are pushed east.

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.mds_lat_to_yindex(lat, res)[source]

For a given latitude return the y-index as it was in MDS2/3 in a 1x1 global grid.

Parameters:
  • lat (float) – Latitude of the point.

  • res (float) – Resolution of grid in degrees.

Return type:

int

Returns:

int – Grid box index.

Notes

In the northern hemisphere, borderline latitudes which fall on grid boundaries are pushed north, except 90 which goes south. In the southern hemisphere, they are pushed south, except -90 which goes north. At 0 degrees they are pushed south.

Expects that latitudes run from 90N to 90S

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.mds_lat_to_yindex_fast(lat, res)[source]

For a given latitude return the y-index as it was in MDS2/3 in a 1x1 global grid.

Parameters:
  • lat (numpy.ndarray) – Latitude(s) of observation in degrees.

  • res (float) – Resolution of grid in degrees.

Return type:

ndarray

Returns:

numpy.ndarray – Grid box indexes.

Notes

In the northern hemisphere, borderline latitudes which fall on grid boundaries are pushed north, except 90 which goes south. In the southern hemisphere, they are pushed south, except -90 which goes north. At 0 degrees they are pushed south.

Expects that latitudes run from 90N to 90S

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.mds_lon_to_xindex(lon, res)[source]

For a given longitude return the x-index as it was in MDS2/3 in a 1x1 global grid.

Parameters:
  • lon (float) – Longitude of the point.

  • res (float) – Resolution of grid in degrees.

Return type:

int

Returns:

int – Grid box index.

Notes

In the western hemisphere, borderline longitudes which fall on grid boundaries are pushed west, except -180 which goes east. In the eastern hemisphere, they are pushed east, except 180 which goes west. At 0 degrees they are pushed west.

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.mds_lon_to_xindex_fast(lon, res)[source]

For a given longitude return the x-index as it was in MDS2/3 in a 1x1 global grid.

Parameters:
  • lon (numpy.ndarray) – Longitude(s) of observation in degrees.

  • res (float) – Resolution of grid in degrees.

Return type:

ndarray

Returns:

numpy.ndarray – Grid box indexes.

Notes

In the western hemisphere, borderline longitudes which fall on grid boundaries are pushed west, except -180 which goes east. In the eastern hemisphere, they are pushed east, except 180 which goes west. At 0 degrees they are pushed west.

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.xindex_to_lon(xindex, res)[source]

Convert xindex to longitude.

Parameters:
  • xindex (int) – Index of the longitude.

  • res (float) – Resolution of grid in degrees.

Return type:

float

Returns:

float – Longitude (degrees).

Notes

In previous versions, res had the default value 1.0.

marine_qc.helpers.location_control.yindex_to_lat(yindex, res)[source]

Convert yindex to latitude.

Parameters:
  • yindex (int) – Index of the latitude.

  • res (float) – Resolution of grid in degrees.

Return type:

float

Returns:

float – Latitude (degrees).

Notes

In previous versions, res had the default value 1.0.

marine_qc.helpers.spherical_geometry module

Quality control suite spherical geometry module.

The spherical geometry module is a simple collection of calculations on a sphere Sourced from https://edwilliams.org/avform147.htm formerly williams.best.vwh.net/avform.htm

marine_qc.helpers.spherical_geometry.angular_distance(lat1, lon1, lat2, lon2)[source]

Calculate the great-circle angular distance between two points on a sphere.

Input latitudes and longitudes should be in degrees. Output distance is returned in radians.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Angular great-circle distance between the two points in radians. NaN is returned for any invalid input values.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.spherical_geometry.course_between_points(lat1, lon1, lat2, lon2)[source]

Given two points find the initial true course at point1 inputs are in degrees and output is in degrees.

Parameters:
Return type:

SequenceFloatType

Returns:

SequenceFloatType – Initial true course in degrees at point one along the great circle between point one and point two.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.spherical_geometry.intermediate_point(lat1, lon1, lat2, lon2, f)[source]

Compute the intermediate point along the great-circle path between two points.

Given two lat,lon points find the latitude and longitude that are a fraction f of the great circle distance between them https://edwilliams.org/avform147.htm formerly williams.best.vwh.net/avform.htm#Intermediate

Parameters:
Return type:

tuple[ndarray, ndarray]

Returns:

tuple of (numpy.ndarray, numpy.ndarray) – A tuple containing: - Latitude(s) of the intermediate point(s) in degrees. - Longitude(s) of the intermediate point(s) in degrees. The outputs have the same shape as the broadcasted inputs.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.spherical_geometry.lat_lon_from_course_and_distance(lat1, lon1, tc, d)[source]

Calculate latitude and longitude given a starting point, true course and distance.

Uses spherical trigonometry formulas from https://edwilliams.org/avform147.htm to compute the endpoint given a starting latitude and longitude, a true coure (bearing), and a distance traveled along a great-circle path.

Parameters:
  • lat1 (SequenceNumberType) – Latitude of the first point in degrees.

  • lon1 (SequenceNumberType) – Longitude of the first point in degrees.

  • tc (float) – True course measured clockwise from north in degrees.

  • d (float) – Distance travelled in kilometres.

Return type:

tuple[ndarray, ndarray]

Returns:

tuple of (SequenceFloatType, SequenceFloatType) – A tuple containing: - Latitude(s) of the intermediate point(s) in degrees. - Longitude(s) of the intermediate point(s) in degrees. The outputs have the same shape as the broadcasted inputs.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.spherical_geometry.sphere_distance(lat1, lon1, lat2, lon2)[source]

Calculate the great circle angular distance between two points on a sphere.

Input latitudes and longitudes should be in degrees. Output distance is returned in radians.

The great circle distance is the shortest distance between any two points on the Earths surface. The calculation is done by first calculating the angular distance between the points and then multiplying that by the radius of the Earth. The angular distance calculation is handled by another function.

Parameters:
Return type:

ndarray

Returns:

numpy.ndarray – Angular great-circle distance between the two points in kilometres.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.statistics module

Some generally helpful statistical functions for base QC.

marine_qc.helpers.statistics.missing_mean(inarr)[source]

Return mean of input array.

Parameters:

inarr (list of float) – List of values for which mean is required. Missing values represented by None in list.

Return type:

float | None

Returns:

float or None – Mean of non-missing values or None.

marine_qc.helpers.statistics.p_data_given_good(x, q, r_hi, r_lo, mu, sigma)[source]

Probability of an observed value assuming it comes from a “good” measurement.

Calculate the probability of an observed value x given a normal distribution with mean mu standard deviation of sigma, where x is constrained to fall between R_hi and R_lo and is known only to an integer multiple of Q, the quantization level.

Parameters:
  • x (float) – Observed value for which probability is required.

  • q (float) – Quantization of x, i.e. x is an integer multiple of Q.

  • r_hi (float) – The upper limit on x imposed by previous QC choices.

  • r_lo (float) – The lower limit on x imposed by previous QC choices.

  • mu (float) – The mean of the distribution.

  • sigma (float) – The standard deviation of the distribution.

Return type:

float

Returns:

float – Probability of the observed value given the specified distribution.

Raises:

ValueError – When inputs are incorrectly specified: q<=0, sigma<=0, r_lo > r_hi, x < r_lo or x > r_hi.

marine_qc.helpers.statistics.p_data_given_gross(q, r_hi, r_lo)[source]

Probability of an observed value assuming it is a gross error.

Calculate the probability of the data given a gross error assuming gross errors are uniformly distributed between R_low and R_high and that the quantization, rounding level is Q

Parameters:
  • q (float) – Quantization of x, i.e. x is an integer multiple of Q.

  • r_hi (float) – The upper limit on x imposed by previous QC choices.

  • r_lo (float) – The lower limit on x imposed by previous QC choices.

Return type:

float

Returns:

float – Probability of the observed value given that it is a gross error.

Raises:

ValueError – When limits are not ascending or q<=0.

marine_qc.helpers.statistics.p_gross(p0, q, r_hi, r_lo, x, mu, sigma)[source]

Posterior probability that an observation is a gross error.

Calculate the posterior probability of a gross error given the prior probability p0, the quantization level of the observed value, Q, previous limits on the observed value, R_hi and R_lo, the observed value, x, and the mean (mu) and standard deviation (sigma) of the distribution of good observations assuming they are normally distributed. Gross errors are assumed to be uniformly distributed between R_lo and R_hi.

Parameters:
  • p0 (float) – Prior probability of gross error.

  • q (float) – Quantization of x, i.e. x is an integer multiple of Q.

  • r_hi (float) – The upper limit on x imposed by previous QC choices.

  • r_lo (float) – The lower limit on x imposed by previous QC choices.

  • x (float) – Observed value for which probability is required.

  • mu (float) – The mean of the distribution of good obs.

  • sigma (float) – The standard deviation of the distribution of good obs.

Return type:

float

Returns:

float – Probability of gross error given an observed value.

Raises:

ValueError – When inputs are incorrectly specified: p0 < 0, p0 > 1, q <= 0, r_hi < r_lo, x < r_lo, x > r_hi, sigma <= 0.

marine_qc.helpers.statistics.trim_mean(inarr, trim)[source]

Calculate a resistant (aka robust) mean of an input array given a trimming criteria.

Parameters:
  • inarr (array-like of float, shape (n,)) – 1-dimensional value array.

  • trim (int) – Trimming criteria. A value of 10 trims one tenth of the values off each end of the sorted array before calculating the mean.

Return type:

float

Returns:

float – Trimmed mean.

marine_qc.helpers.statistics.trim_std(inarr, trim)[source]

Calculate a resistant (aka robust) standard deviation of an input array given a trimming criteria.

Parameters:
  • inarr (array-like of float, shape (n,)) – 1-dimensional value array.

  • trim (int) – Trimming criteria. A value of 10 trims one tenth of the values off each end of the sorted array before calculating the standard deviation.

Return type:

float

Returns:

float – Trimmed standard deviation.

marine_qc.helpers.statistics.winsorised_mean(inarr)[source]

Compute the 25% winsorised mean of the input array.

The winsorised mean is a resistant way of calculating an average.

Parameters:

inarr (list of float) – Input array to be averaged.

Return type:

float

Returns:

float – The winsorised mean of the input array with a 25% trimming.

Raises:

ValueError – if length of inarr is equal to 0.

Notes

The winsorised mean is that which you get if you set the first quarter of the sorted input array to the 1st quartile value and the last quarter to the 3rd quartile and then take the mean. This is quite a heavy trimming of the distribution. It makes it very resistant - about half the obs can be egregiously bad without affecting the mean strongly - but it will be less accurate if there are lots of observations, or the quality of the obs is higher.

marine_qc.helpers.time_control module

Some generally helpful time control functions for base QC.

marine_qc.helpers.time_control.convert_date(*params)[source]

Decorator to extract date components and inject them as function parameters.

This decorator intercepts the ‘date’ argument from the function call, splits it into its components (e.g., year, month, day), and assigns those components to specified parameters in the wrapped function. It supports scalar or sequence inputs for ‘date’.

Parameters:

*params (str) – List of parameter names corresponding to date components to be extracted and passed to the decorated function.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that wraps a function, extracting date components before calling it.

Notes

  • The decorator expects the wrapped function to accept the parameters listed in params. If a parameter is missing, it raises a ValueError.

  • If the ‘date’ argument is None, the original function is called without modification.

  • Supports scalar-like ‘date’ values as well as iterable sequences.

  • Assumes a helper function split_date exists that splits a date into components and returns a dictionary mapping parameter names to their values.

marine_qc.helpers.time_control.convert_date_to_hours(dates)[source]

Convert an array of datetimes to an array of hours since the first element.

Parameters:

dates (array-like of datetime, shape (n,)) – 1-dimensional date array.

Return type:

Sequence[float]

Returns:

array-like of float, shape (n,) – 1- dimensional array containing hours since the first element in the array.

marine_qc.helpers.time_control.convert_time_in_hours(hour, minute, sec, zone, daylight_savings_time)[source]

Convert integer hour, minute, and second to time in decimal hours.

Parameters:
  • hour (int) – Hour.

  • minute (int) – Minute.

  • sec (int) – Second.

  • zone (int or float) – Correction for timezone.

  • daylight_savings_time (float) – Set to 1 if daylight savings time is in effect else set to 0.

Return type:

float

Returns:

float – Time converted to decimal hour in day.

marine_qc.helpers.time_control.day_in_year(year=None, month=1, day=1)[source]

Get the day in year from 1 to 365 or 366.

Parameters:
  • year (int, optional, default: None) – Year to be tested. If none, set year to default leap year.

  • month (int, default: 1) – Month to be tested.

  • day (int, default: 1) – Day to be tested.

Return type:

int

Returns:

int – Day in year. If year is not specified then the year is treated as a non-leap year and 29 February returns the same value as 1 March.

marine_qc.helpers.time_control.day_in_year_array(month, day)[source]

Get the day in year from 1 to 365. Leap years are dealt with by allowing Feb 29 and Mar 1 to be the same day.

Parameters:
  • month (1D numpy.ndarray) – Array of months.

  • day (1D numpy.ndarray) – Array of days.

Return type:

ndarray

Returns:

numpy.ndarray – Array of day number from 1-365.

marine_qc.helpers.time_control.get_month_lengths(year)[source]

Return a list holding the lengths of the months in a given year.

Parameters:

year (int) – Year for which you want month lengths.

Return type:

list[int]

Returns:

list of int – List of month lengths.

marine_qc.helpers.time_control.jul_day(year, month, day)[source]

Routine to calculate julian day. This is the weird Astronomical thing which counts from 1 Jan 4713 BC.

Parameters:
  • year (int) – Year.

  • month (int) – Month.

  • day (int) – Day.

Return type:

int

Returns:

int – Julian day.

Notes

This is one of those routines that looks baffling but works. No one is sure exactly how. It gets written once and then remains untouched for centuries, mysteriously working.

marine_qc.helpers.time_control.leap_year(years_since_1980)[source]

Check if input year is a Leap year.

Parameters:

years_since_1980 (int) – Number of years since 1980.

Return type:

int

Returns:

int – 1 if it is a leap year, 0 otherwise.

marine_qc.helpers.time_control.leap_year_correction(time_in_hours, day, years_since_1980)[source]

Make leap year correction.

Parameters:
  • time_in_hours (float) – Time in hours.

  • day (int) – Day number.

  • years_since_1980 (int) – Years since 1980.

Return type:

float

Returns:

float – Leap year corrected time.

marine_qc.helpers.time_control.pentad_to_month_day(p)[source]

Given a pentad number, return the month and day of the first day in the pentad.

Parameters:

p (int) – Pentad number from 1 to 73.

Return type:

tuple[int, int]

Returns:

tuple of int – A tuple of two ints representing month and day of the first day of the pentad.

marine_qc.helpers.time_control.relative_year_number(year, reference=1979)[source]

Get number of year relative to reference year (1979 by default).

Parameters:
  • year (int) – Year.

  • reference (int, default: 1979) – Reference year.

Return type:

int

Returns:

int – Number of year relative to reference year.

marine_qc.helpers.time_control.split_date(date)[source]

Split datetime date into year, month, day and hour.

Parameters:

date (datetime) – Date to split.

Return type:

dict[str, float]

Returns:

dict – Dictionary containing year, month, day and hour.

marine_qc.helpers.time_control.time_difference(times1, times2)[source]

Convert two arrays of datetimes to the difference in hours.

Parameters:
Return type:

ndarray

Returns:

array-like of float, shape (n,) – 1-dimensional array containing the time difference in hours computed as times2 - times1.

Raises:

TypeError – If inspect_arrays does not return numpy ndarrays.

marine_qc.helpers.time_control.time_in_whole_days(time_in_hours, day, years_since_1980, leap)[source]

Calculate from time in hours to time in whole days.

Parameters:
  • time_in_hours (int) – Time in hours.

  • day (int) – Day number.

  • years_since_1980 (int) – Number of years since 1980.

  • leap (int) – Set to 1 for a leap year, else set to 0.

Return type:

float

Returns:

float – Time in whole days.

marine_qc.helpers.time_control.valid_month_day(year=None, month=1, day=1)[source]

Return True if month and day combination are allowed, False otherwise. Assumes that Feb 29th is valid.

Parameters:
  • year (int, optional, default: None) – Year to be tested. If none, set year to default leap year.

  • month (int, default: 1) – Month to be tested.

  • day (int, default: 1) – Day to be tested.

Return type:

bool

Returns:

bool – True if month and day (or year month and day) are a valid combination (e.g. 12th March) and False if not (e.g. 30th February).

Notes

Assumes that February 29th is a valid date.

marine_qc.helpers.time_control.which_pentad(month, day)[source]

Take month and day as inputs and return pentad in range 1-73.

Parameters:
  • month (int) – Month containing the day for which we want to calculate the pentad.

  • day (int) – Day for the day for which we want to calculate the pentad.

Return type:

int

Returns:

int – Pentad (5-day period) containing input day, from 1 (1 Jan-5 Jan) to 73 (27-31 Dec).

Raises:

ValueError – If month not in range 1-12 or day not in range 1-31.

Notes

The calculation is rather simple. It just loops through the year and adds up days till it reaches the day we are interested in. February 29th is treated as though it were March 1st in a regular year.

marine_qc.helpers.time_control.which_pentad_array(month, day)[source]

Take month and day arrays as inputs and return array of pentads in range 1-73.

Parameters:
  • month (numpy.ndarray) – Month containing the day for which we want to calculate the pentad.

  • day (numpy.ndarray) – Day for the day for which we want to calculate the pentad.

Return type:

ndarray

Returns:

numpy.ndarray – Pentad (5-day period) containing input day, from 1 (1 Jan-5 Jan) to 73 (27-31 Dec).