Source code for ska_ost_senscalc.mid.validation

"""
This module provides semantic validation for inputs to the Sensitivity Calculator,
including checking for required values, setting default values, and domain related checks.

Syntactic validation and basic validation, for example of min/max values of numbers, is done
by Connexion and the OpenAPI spec.
"""
from ska_ost_senscalc.mid_utilities import CalculatorMode, Weighting

DEFAULT_CALCULATE_PARAMS = {
    "pmv": 10,
    "el": 45,
    "array_configuration": "AA4",
    "alpha": 2.75,
    "n_subbands": 1,
}

DEFAULT_WEIGHTING_PARAMS = {
    "taper": 0.0,
}


[docs]def validate_and_set_defaults_for_calculate(user_input: dict) -> dict: """ :param user_input: the parameters from the HTTP request to /calculate :return: A new copy of the input dict, with defaults set for missing values :raises: ValueError if the input data is not valid """ # Merge the default params and the user input into a new dict. The union operator for a dict will # take the rightmost value, ie if the user_input contains a key then it will not be overwritten by the defaults user_input = DEFAULT_CALCULATE_PARAMS | user_input if user_input.get("integration_time") and user_input.get("sensitivity"): raise ValueError( "Only one of 'sensitivity' or 'integration_time' can be specified" " at once." ) _validate_zoom_parameters(user_input) _validate_subband_parameters(user_input) return user_input
[docs]def validate_and_set_defaults_for_weighting(user_input: dict) -> dict: """ :param user_input: the parameters from the HTTP request to /weighting :return: A new copy of the input dict, with defaults set for missing values :raises: ValueError if the input data is not valid """ user_input = DEFAULT_WEIGHTING_PARAMS | user_input if ( user_input.get("frequency") is None and user_input.get("zoom_frequencies") is None ): raise ValueError("Parameter 'frequency' or 'zoom_frequencies' is required") if ( user_input.get("calculator_mode") is CalculatorMode.CONTINUUM.value and user_input.get("frequency") is None ): raise ValueError( "Parameter 'frequency' must be set for 'continuum' calculator mode" ) if ( user_input.get("calculator_mode") is CalculatorMode.LINE.value and user_input.get("zoom_frequencies") is None ): raise ValueError( "Parameter 'zoom_frequencies' must be set for 'line' calculator mode" ) if (user_input.get("weighting") == Weighting.ROBUST.value) and user_input.get( "robustness" ) is None: raise ValueError("Parameter 'robustness' should be set for 'robust' weighting") return user_input
def _validate_zoom_parameters(user_input: dict) -> None: """ :param user_input: the parameters from the HTTP request :raises: ValueError if the input data relevant for zoom mode is not valid """ if user_input.get("zoom_frequencies"): # Check that zoom_frequencies has the same length as zoom_resolutions if not user_input.get("zoom_resolutions"): raise ValueError( "Parameter 'zoom_resolutions' must also be set when setting" " 'zoom_frequencies'." ) if len(user_input.get("zoom_frequencies")) != len( user_input.get("zoom_resolutions") ): raise ValueError( "Parameters 'zoom_resolutions' and 'zoom_frequencies' must" " have the same length." ) if user_input.get("sensitivity"): if user_input.get("zoom_sensitivities"): if len(user_input.get("zoom_sensitivities")) != len( user_input.get("zoom_resolutions") ): raise ValueError( "Parameters 'zoom_sensitivities' and" " 'zoom_frequencies' must have the same length." ) else: # Check that zoom_sensitivities are specified if requesting a sensitivity raise ValueError( "Parameter 'zoom_sensitivities' must be set when setting" " 'zoom_frequencies' and 'sensitivity'." ) elif user_input.get("zoom_resolutions"): raise ValueError( "Parameter 'zoom_frequencies' must also be set when setting" " 'zoom_resolutions'." ) def _validate_subband_parameters(user_input: dict) -> None: """ :param user_input: the parameters from the HTTP request :raises: ValueError if the input data relevant for subband calculations is not valid """ if not user_input.get("sensitivity"): # Validation currently only needs to be done for the sensitivity -> integration time calculation return n_subbands = user_input.get("n_subbands") subband_sensitivities = user_input.get("subband_sensitivities") if n_subbands > 1 and not subband_sensitivities: raise ValueError( "Parameter 'subband_sensitivities' must be set when setting 'sensitivity' and" "'n_subbands' is greater than 1." ) if subband_sensitivities and n_subbands <= 1: raise ValueError( "Parameter 'n_subbands' must be greater than 1 when setting 'subband_sensitivities' and 'sensitivity'." ) if ( n_subbands and subband_sensitivities and n_subbands != len(subband_sensitivities) ): raise ValueError( "Parameter 'subband_sensitivities' must have the same length as the value of 'n_subbands' for" "'n_subbands' greater than 1." )