Skip to content
Snippets Groups Projects
Commit e3bf43cb authored by Jörn Künsemöller's avatar Jörn Künsemöller
Browse files

TMSS-259: Add tests for angular separation endpoint. Improve speed on sunrise...

TMSS-259: Add tests for angular separation endpoint. Improve speed on sunrise endpoint by reducing precision.
parent 67d705be
No related branches found
No related tags found
1 merge request!284Resolve TMSS-259
from astropy.time import Time
import astropy.units
from lofar.lta.sip import station_coordinates
from datetime import datetime
from datetime import datetime, timedelta, time as dtime
from astropy.coordinates.earth import EarthLocation
from astropy.coordinates import Angle, get_body
from astroplan.observer import Observer
......@@ -20,8 +20,10 @@ def create_astroplan_observer_for_station(station: str) -> Observer:
observer = Observer(location, name="LOFAR", timezone="UTC")
return observer
# default angle to the horizon at which the sunset/sunrise starts and ends, as per LOFAR definition.
SUN_SET_RISE_ANGLE_TO_HORIZON = Angle(10, unit=astropy.units.deg)
SUN_SET_RISE_PRECISION = 15 # n_grid_points; higher is more precise but very costly; astropy defaults to 150, 15 seems to cause errors of typically one minute
def timestamps_and_stations_to_sun_rise_and_set(timestamps: [datetime], stations: [str], angle_to_horizon: Angle=SUN_SET_RISE_ANGLE_TO_HORIZON) -> dict:
"""
......@@ -46,13 +48,13 @@ def timestamps_and_stations_to_sun_rise_and_set(timestamps: [datetime], stations
for station in stations:
for timestamp in timestamps:
observer = create_astroplan_observer_for_station(station)
sunrise_start = observer.sun_rise_time(time=Time(timestamp), which='previous')
sunrise_start = observer.sun_rise_time(time=Time(timestamp), which='previous', n_grid_points=SUN_SET_RISE_PRECISION)
if sunrise_start.to_datetime().date() < timestamp.date():
sunrise_start = observer.sun_rise_time(time=Time(timestamp), horizon=-angle_to_horizon, which='next')
sunrise_end = observer.sun_rise_time(time=Time(timestamp), horizon=angle_to_horizon, which='next')
sunset_start = observer.sun_set_time(time=sunrise_end, horizon=angle_to_horizon, which='next')
sunset_end = observer.sun_set_time(time=sunrise_end, horizon=-angle_to_horizon, which='next')
sunrise_next_start = observer.sun_rise_time(time=sunset_end, horizon=-angle_to_horizon, which='next')
sunrise_start = observer.sun_rise_time(time=Time(timestamp), horizon=-angle_to_horizon, which='next', n_grid_points=SUN_SET_RISE_PRECISION)
sunrise_end = observer.sun_rise_time(time=Time(timestamp), horizon=angle_to_horizon, which='next', n_grid_points=SUN_SET_RISE_PRECISION)
sunset_start = observer.sun_set_time(time=sunrise_end, horizon=angle_to_horizon, which='next', n_grid_points=SUN_SET_RISE_PRECISION)
sunset_end = observer.sun_set_time(time=sunrise_end, horizon=-angle_to_horizon, which='next', n_grid_points=SUN_SET_RISE_PRECISION)
sunrise_next_start = observer.sun_rise_time(time=sunset_end, horizon=-angle_to_horizon, which='next', n_grid_points=SUN_SET_RISE_PRECISION)
return_dict.setdefault(station, {}).setdefault("sunrise", []).append({"start": sunrise_start.to_datetime(), "end": sunrise_end.to_datetime()})
return_dict[station].setdefault("sunset", []).append({"start": sunset_start.to_datetime(), "end": sunset_end.to_datetime()})
return_dict[station].setdefault("day", []).append({"start": sunrise_end.to_datetime(), "end": sunset_start.to_datetime()})
......
......@@ -169,6 +169,7 @@ def get_sun_rise_and_set(request):
else:
stations = stations.split(',')
# todo: to improve speed for the frontend, we should probably precompute/cache these and return those (where available), to revisit after constraint table / TMSS-190 is done
return JsonResponse(timestamps_and_stations_to_sun_rise_and_set(timestamps, stations))
@permission_classes([AllowAny])
......
......@@ -165,6 +165,69 @@ class UtilREST(unittest.TestCase):
response_date = dateutil.parser.parse(r_dict['CS002']['sunrise'][i]['start']).date()
self.assertEqual(expected_date, response_date)
def test_util_angular_separation_from_bodies_yields_error_when_no_pointing_is_given(self):
r = requests.get(BASE_URL + '/util/angular_separation_from_bodies', auth=AUTH)
# assert error
self.assertEqual(r.status_code, 500)
self.assertIn("celestial coordinates", r.content.decode('utf-8'))
def test_util_angular_separation_from_bodies_returns_json_structure_with_defaults(self):
r = requests.get(BASE_URL + '/util/angular_separation_from_bodies?ras=1&decs=1', auth=AUTH)
self.assertEqual(r.status_code, 200)
r_dict = json.loads(r.content.decode('utf-8'))
# assert defaults to core and today
self.assertIn('CS002', r_dict.keys())
for key in ['sun', 'jupiter', 'moon']:
self.assertIn(key, r_dict['CS002'][0])
self.assertEqual(type(r_dict['CS002'][0]['jupiter'][0]), float)
def test_util_angular_separation_from_bodies_considers_stations(self):
stations = ['CS005', 'RS305', 'DE609']
r = requests.get(BASE_URL + '/util/angular_separation_from_bodies?ras=1&decs=1&stations=%s' % ','.join(stations), auth=AUTH)
self.assertEqual(r.status_code, 200)
r_dict = json.loads(r.content.decode('utf-8'))
# assert station is included in response and angles differ
angle_last = None
for station in stations:
self.assertIn(station, r_dict.keys())
angle = r_dict[station][0]['jupiter'][0]
if angle_last:
self.assertNotEqual(angle, angle_last)
angle_last = angle
def test_util_angular_separation_from_bodies_considers_timestamps(self):
timestamps = ['2020-01-01', '2020-02-22T16-00-00', '2020-3-11', '2020-01-01']
r = requests.get(BASE_URL + '/util/angular_separation_from_bodies?ras=1&decs=1&timestamps=%s' % ','.join(timestamps), auth=AUTH)
self.assertEqual(r.status_code, 200)
r_dict = json.loads(r.content.decode('utf-8'))
# assert all requested timestamps yield a response and angles differ
self.assertEqual(len(timestamps), len(r_dict['CS002'][0]['jupiter']))
angle_last = None
for i in range(len(timestamps)):
angle = r_dict['CS002'][0]['jupiter'][i]
if angle_last:
self.assertNotEqual(angle, angle_last)
angle_last = angle
def test_util_angular_separation_from_bodies_considers_coordinates(self):
ras = ['1.0', '1.1', '1.2']
decs = ['1.0', '1.1', '1.2']
r = requests.get(BASE_URL + '/util/angular_separation_from_bodies?ras=%s&decs=%s' % (','.join(ras), ','.join(decs)), auth=AUTH)
self.assertEqual(r.status_code, 200)
r_dict = json.loads(r.content.decode('utf-8'))
# assert all requested timestamps yield a response and angles differ
self.assertEqual(len(ras), len(r_dict['CS002']))
angle_last = None
for i in range(len(ras)):
angle = r_dict['CS002'][i]['jupiter'][0]
if angle_last:
self.assertNotEqual(angle, angle_last)
angle_last = angle
if __name__ == "__main__":
os.environ['TZ'] = 'UTC'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment