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,
}

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_chunk_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_chunk_parameters(user_input: dict) -> None: """ :param user_input: the parameters from the HTTP request :raises: ValueError if the input data relevant for chunk 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_chunks = user_input.get("n_chunks") chunk_sensitivities = user_input.get("chunk_sensitivities") if n_chunks and not chunk_sensitivities: raise ValueError( "Parameter 'chunk_sensitivities' must also be set when setting 'n_chunks' and 'sensitivity'." ) if chunk_sensitivities and not n_chunks: raise ValueError( "Parameter 'n_chunks' must also be set when setting 'chunk_sensitivities' and 'sensitivity'." ) if n_chunks and chunk_sensitivities and n_chunks != len(chunk_sensitivities): raise ValueError( "Parameters 'n_chunks' and 'chunk_sensitivities' must have the same length." )