"""
The service layer is responsible for turning validated inputs into the relevant calculation inputs,
calling any calculation functions and collating the results.
"""
from typing import TypedDict
from ska_ost_senscalc.common.beam import calculate_weighting
from ska_ost_senscalc.common.model import WeightingInput
from ska_ost_senscalc.low.bright_source_lookup import BrightSourceCatalog
from ska_ost_senscalc.low.calculator import calculate_sensitivity
from ska_ost_senscalc.low.model import CalculatorInput
from ska_ost_senscalc.subarray import SubarrayStorage
from ska_ost_senscalc.utilities import Telescope
subarray_storage = SubarrayStorage(Telescope.LOW)
FLUX_DENSITY_THRESHOLD_JY = 10.0
[docs]class BeamSizeResponse(TypedDict):
"""
BeamSizeResponse is a typed dictionary constrained to match the schema of
the JSON object outlining the synthesized beam size, as contained in the
parent JSON result of a weighting endpoint query.
"""
beam_maj_scaled: float
beam_min_scaled: float
beam_pa: float
[docs]class WeightingResponse(TypedDict):
"""
SingleWeightingResponse is a typed dictionary constrained to match the
schema of a single weighting calculation, as performed for the main
continuum or zoom weighting calculation and for each subband frequency.
Child SingleWeightingResponse JSON object for each of these calculations
are contained in the parent JSON result
"""
weighting_factor: float
sbs_conv_factor: list[float]
beam_size: list[BeamSizeResponse]
[docs]class SensitivityResponse(TypedDict):
"""
SensitivityResponse is a typed dictionary constrained to match the
schema of a single sensitivity calculation.
"""
sensitivity: float
units: str
warn_msg: str | None
def _get_calculation_value(calculator_input: CalculatorInput) -> dict:
result = calculate_sensitivity(calculator_input)
response = {"sensitivity": result.sensitivity, "units": result.units}
mwa_cat = BrightSourceCatalog(threshold_jy=FLUX_DENSITY_THRESHOLD_JY)
if mwa_cat.check_for_bright_sources(
calculator_input.pointing_centre, calculator_input.freq_centre
):
response["warn_msg"] = (
"The specified pointing contains at least one source brighter "
+ f"than {FLUX_DENSITY_THRESHOLD_JY} Jy. Your observation may be "
+ "dynamic range limited."
)
return response
[docs]def get_subarray_response():
"""
return the appropriate subarray objects
"""
return [
{
"name": subarray.name,
"label": subarray.label,
"n_stations": subarray.n_stations,
}
for subarray in subarray_storage.list()
]