"""
Unit tests for the sensitivity_calculator.mid module.
"""
import pytest
from numpy import array
from dictdiffer import diff
import astropy.units as u
from astropy.time import Time
from astropy.coordinates import SkyCoord, AltAz
from sensitivity_calculator.utilities import DishType, TelParams
import sensitivity_calculator.mid as mid
target = SkyCoord(359.94423568 * u.deg, -00.04616002 * u.deg, frame="galactic")
never_up = SkyCoord(0.0 * u.deg, 70.0 * u.deg, frame="icrs")
# Defining some basic test cases.
# For historical reasons (changing the tests to follow the code developemnt),
# Tgal is sometimes overriden and sometimes left as the default.
eta_system = 1.0
tgal = u.K * 17.1 * (0.408 / 0.5) ** 2.75
TESTCASE1 = mid.MidCalculator(
"Band 1",
0.5 * u.GHz,
0.2 * u.GHz,
"extended",
target,
weather="Bad",
elevation=90 * u.deg,
eta_system=eta_system,
Tgal=tgal,
)
TESTCASE2 = mid.MidCalculator(
"Band 2",
1.3 * u.GHz,
0.4 * u.GHz,
"core",
target,
weather="Good",
elevation=90 * u.deg,
eta_system=eta_system,
)
tgal = u.K * 17.1 * (0.408 / 2.0) ** 2.75
TESTCASE3 = mid.MidCalculator(
"Band 3",
2.0 * u.GHz,
0.8 * u.GHz,
"full",
target,
weather="Average",
elevation=90 * u.deg,
eta_system=eta_system,
Tgal=tgal,
)
TESTCASE4 = mid.MidCalculator(
"Band 4",
4.0 * u.GHz,
0.4 * u.GHz,
"core",
target,
elevation=90 * u.deg,
weather="Good",
eta_system=eta_system,
)
tgal = u.K * 17.1 * (0.408 / 6.0) ** 2.75
TESTCASE5 = mid.MidCalculator(
"Band 5a",
6.0 * u.GHz,
0.4 * u.GHz,
"core",
target,
weather="Good",
elevation=90 * u.deg,
eta_system=eta_system,
Tgal=tgal,
)
TESTCASE6 = mid.MidCalculator(
"Band 5b",
13.0 * u.GHz,
1.0 * u.GHz,
"full",
target,
weather="Average",
elevation=90 * u.deg,
eta_system=eta_system,
)
target2 = SkyCoord("13h25m27.6s", "-43d01m09.00s", frame="icrs")
TESTCASE7 = mid.MidCalculator(
"Band 1",
0.7 * u.GHz,
0.3 * u.GHz,
"full",
target2,
"Good",
90 * u.deg,
None,
0.5,
0.5,
0.5,
0.5,
0.5,
100,
0.7,
None,
10.0 * u.K,
20.0 * u.K,
30,
0.8,
None,
15.0 * u.K,
25.0 * u.K,
15.0 * u.K,
u.K * 17.1 * (0.408 / 0.7) ** 2.75,
None,
)
# zoom
TESTCASE8 = mid.MidCalculator(
"Band 1",
0.7 * u.GHz,
0.21 * u.kHz,
"full",
target2,
"Good",
90 * u.deg,
None,
0.5,
0.5,
0.5,
0.5,
0.5,
100,
0.7,
None,
10.0 * u.K,
20.0 * u.K,
None,
0.8,
None,
15.0 * u.K,
25.0 * u.K,
15.0 * u.K,
u.K * 17.1 * (0.408 / 0.7) ** 2.75,
None,
)
[docs]def test_SEFD_antenna():
"""Verify performance of SEFD_antenna.
"""
# print('sefd antenna', mid.SEFD_antenna(1 * u.K, 100 * u.m * u.m))
assert mid.SEFD_antenna(1 * u.K, 100 * u.m * u.m).to_value(
"J / m2"
) == pytest.approx(2.761298e-25)
[docs]def test_SEFD_array():
"""Verify performance of SEFD_antenna.
"""
# print(
# "sefd array",
# mid.SEFD_array(100, 50, 2.0 * u.Unit("J / m2"), 1.0 * u.Unit("J / m2")),
# )
assert mid.SEFD_array(
100, 50, 2.0 * u.Unit("J / m2"), 1.0 * u.Unit("J / m2")
).to_value("J / m2") == pytest.approx(0.01003771)
[docs]def test_never_up():
"""Verify behaviour of mid.MidCalculator with target always below horizon
"""
with pytest.raises(RuntimeError) as err:
assert mid.MidCalculator(
"Band 1", 0.5 * u.GHz, 0.2 * u.GHz, "extended", never_up, weather="Bad"
)
assert str(err.value) == "target always below horizon"
[docs]def test_calculate_sensitivity():
"""
Verify the sensitivity of a proposed observation for a given integration
"""
# print("test sens1", TESTCASE1.calculate_sensitivity(3600 * u.s).to_value(u.Jy))
# print("test sens2", TESTCASE2.calculate_sensitivity(14400 * u.s).to_value(u.Jy))
# print("test sens3", TESTCASE3.calculate_sensitivity(3600 * u.s).to_value(u.Jy))
# print("test sens4", TESTCASE4.calculate_sensitivity(14400 * u.s).to_value(u.Jy))
# print("test sens5", TESTCASE5.calculate_sensitivity(3600 * u.s).to_value(u.Jy))
# print("test sens6", TESTCASE6.calculate_sensitivity(14400 * u.s).to_value(u.Jy))
# print("test sens7", TESTCASE7.calculate_sensitivity(10 * u.s).to_value(u.Jy))
# print("test sens8", TESTCASE8.calculate_sensitivity(10 * u.s).to_value(u.Jy))
assert TESTCASE1.calculate_sensitivity(3600 * u.s)[0].to_value(
u.Jy
) == pytest.approx(7.11707209e-06)
assert TESTCASE2.calculate_sensitivity(14400 * u.s)[0].to_value(
u.Jy
) == pytest.approx(7.51009442e-06)
assert TESTCASE3.calculate_sensitivity(3600 * u.s)[0].to_value(
u.Jy
) == pytest.approx(6.27798139e-07)
assert TESTCASE4.calculate_sensitivity(14400 * u.s)[0].to_value(
u.Jy
) == pytest.approx(2.10254896e-06)
assert TESTCASE5.calculate_sensitivity(3600 * u.s)[0].to_value(
u.Jy
) == pytest.approx(3.5579621e-06)
assert TESTCASE6.calculate_sensitivity(14400 * u.s)[0].to_value(
u.Jy
) == pytest.approx(3.94425871e-07)
assert TESTCASE7.calculate_sensitivity(10 * u.s)[0].to_value(u.Jy) == pytest.approx(
0.00336668337
)
assert TESTCASE8.calculate_sensitivity(10 * u.s)[0].to_value(u.Jy) == pytest.approx(
3.29088385
)
with pytest.raises(RuntimeError) as err:
assert TESTCASE1.calculate_sensitivity(-1 * u.s)
assert str(err.value) == "negative integration time"
[docs]def test_calculate_integration_time():
"""
Verify the integration time of a proposed observation for a given sensitivity
"""
# print("test int 1", TESTCASE1.calculate_integration_time(1 * u.uJy))
# print("test int 2", TESTCASE2.calculate_integration_time(0.1 * u.uJy))
# print("test int 3", TESTCASE3.calculate_integration_time(1 * u.uJy))
# print("test int 4", TESTCASE4.calculate_integration_time(0.1 * u.uJy))
# print("test int 5", TESTCASE5.calculate_integration_time(1 * u.uJy))
# print("test int 6", TESTCASE6.calculate_integration_time(0.1 * u.uJy))
assert TESTCASE1.calculate_integration_time(1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(182349.77454733)
assert TESTCASE2.calculate_integration_time(0.1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(81218186.15468223)
assert TESTCASE3.calculate_integration_time(1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(1418.86981324)
assert TESTCASE4.calculate_integration_time(0.1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(6365825.44939299)
assert TESTCASE5.calculate_integration_time(1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(45572.73955247)
assert TESTCASE6.calculate_integration_time(0.1 * u.uJy)[0].to_value(
u.s
) == pytest.approx(224023.34541058)
with pytest.raises(RuntimeError) as err:
assert TESTCASE1.calculate_integration_time(-1.0 * u.uJy)
assert str(err.value) == "negative sensitivity"
[docs]def test_state():
"""
Verify the method that passes the calculated values back to the front end
"""
# print("state1", TESTCASE1.state())
result = diff(
TESTCASE1.state(),
{
"weather": 20,
"eta_point": array([0.99999385]),
"eta_coherence": array([0.9999787]),
"eta_digitisation": 0.999,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 133,
"eta_dish_ska": array([0.76280495]),
"n_meer": 0,
"eta_dish_meer": array([0.64775609]),
"alpha": 2.75,
"Tsys_ska": array([55.021201]),
"Tspl_ska": 3.0,
"Trcv_ska": array([16.875]),
"Tsys_meer": array([50.50620108]),
"Tspl_meer": 4.0,
"Trcv_meer": array([11.36]),
"Tsky": array([35.15819824]),
"Tgal": 9.775614051429915,
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state2", TESTCASE2.state())
result = diff(
TESTCASE2.state(),
{
"weather": 5,
"eta_point": array([0.99995844]),
"eta_coherence": array([0.99985605]),
"eta_digitisation": 0.999,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 0,
"eta_dish_ska": array([0.88029791]),
"n_meer": 64,
"eta_dish_meer": array([0.76108191]),
"alpha": 2.75,
"Tsys_ska": array([67.30914562]),
"Tspl_ska": 3.0,
"Trcv_ska": array([7.5]),
"Tsys_meer": array([67.97063249]),
"Tspl_meer": 4.0,
"Trcv_meer": array([8.90802699]),
"Tsky": array([55.96706584]),
"Tgal": array([51.99684981]),
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state3", TESTCASE3.state())
result = diff(
TESTCASE3.state(),
{
"weather": 10,
"eta_point": array([0.99990165]),
"eta_coherence": array([0.99965931]),
"eta_digitisation": 0.998,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 133,
"eta_dish_ska": array([0.88923695]),
"n_meer": 64,
"eta_dish_meer": array([0.76896165]),
"alpha": 2.75,
"Tsys_ska": array([15.1342114]),
"Tspl_ska": 3.0,
"Trcv_ska": array([7.5]),
"Tsys_meer": array([16.13420828]),
"Tspl_meer": 4.0,
"Trcv_meer": 7.5,
"Tsky": array([4.68215327]),
"Tgal": 0.2160125933133935,
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state4", TESTCASE4.state())
result = diff(
TESTCASE4.state(),
{
"weather": 5,
"eta_point": array([0.99960671]),
"eta_coherence": array([0.99863795]),
"eta_digitisation": 0.98,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 0,
"eta_dish_ska": array([0.88726588]),
"n_meer": 64,
"eta_dish_meer": array([0.7639152]),
"alpha": 2.75,
"Tsys_ska": array([18.10947653]),
"Tspl_ska": 3.0,
"Trcv_ska": array([7.5]),
"Tsys_meer": array([19.08120347]),
"Tspl_meer": 4.0,
"Trcv_meer": 7.5,
"Tsky": array([7.69116045]),
"Tgal": array([3.26936568]),
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state5", TESTCASE5.state())
result = diff(
TESTCASE5.state(),
{
"weather": 5,
"eta_point": array([0.99911553]),
"eta_coherence": array([0.996938]),
"eta_digitisation": 0.955,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 0,
"eta_dish_ska": array([0.88026181]),
"n_meer": 64,
"eta_dish_meer": array([0.75243633]),
"alpha": 2.75,
"Tsys_ska": array([15.94213894]),
"Tspl_ska": 3.0,
"Trcv_ska": array([8.54]),
"Tsys_meer": array([15.90214001]),
"Tspl_meer": 4.0,
"Trcv_meer": 7.5,
"Tsky": array([4.54568667]),
"Tgal": 0.010529205945564165,
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state6", TESTCASE6.state())
result = diff(
TESTCASE6.state(),
{
"weather": 10,
"eta_point": array([0.99586144]),
"eta_coherence": array([0.9857067]),
"eta_digitisation": 0.955,
"eta_correlation": 0.98,
"eta_bandpass": 1.0,
"n_ska": 133,
"eta_dish_ska": array([0.85056635]),
"n_meer": 64,
"eta_dish_meer": array([0.69550408]),
"alpha": 2.75,
"Tsys_ska": array([21.76488485]),
"Tspl_ska": 3.0,
"Trcv_ska": array([13.37]),
"Tsys_meer": array([16.89515975]),
"Tspl_meer": 4.0,
"Trcv_meer": 7.5,
"Tsky": array([5.70529575]),
"Tgal": array([0.13463106]),
"altitude": 88.28669497465869,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state7", TESTCASE7.state())
result = diff(
TESTCASE7.state(),
{
"weather": 5,
"eta_point": 0.5,
"eta_coherence": 0.5,
"eta_digitisation": 0.5,
"eta_correlation": 0.5,
"eta_bandpass": 0.5,
"n_ska": 100,
"eta_dish_ska": 0.7,
"n_meer": 30,
"eta_dish_meer": 0.8,
"alpha": 2.75,
"Tsys_ska": array([44.98320474]),
"Tspl_ska": 10.0,
"Trcv_ska": 20.0,
"Tsys_meer": array([54.98320436]),
"Tspl_meer": 15.0,
"Trcv_meer": 25.0,
"Tsky": 15.0,
"Tgal": 3.8751806138724483,
"altitude": 77.70196333333334,
},
tolerance=1.0e-4,
)
assert list(result) == []
# print("state8", TESTCASE8.state())
result = diff(
TESTCASE8.state(),
{
"weather": 5,
"eta_point": 0.5,
"eta_coherence": 0.5,
"eta_digitisation": 0.5,
"eta_correlation": 0.5,
"eta_bandpass": 0.5,
"n_ska": 100,
"eta_dish_ska": 0.7,
"n_meer": 64,
"eta_dish_meer": 0.8,
"alpha": 2.75,
"Tsys_ska": array([44.98320474]),
"Tspl_ska": 10.0,
"Trcv_ska": 20.0,
"Tsys_meer": array([54.98320436]),
"Tspl_meer": 15.0,
"Trcv_meer": 25.0,
"Tsky": 15.0,
"Tgal": 3.8751806138724483,
"altitude": 77.70196333333334,
},
tolerance=1.0e-4,
)
assert list(result) == []