Skip to content

Commit

Permalink
Added area web query
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanHydrogen committed Aug 9, 2024
1 parent f411f39 commit a70da08
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 14 deletions.
1 change: 1 addition & 0 deletions day_integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ modules:
total_fraction: 0.7
zenith_fraction: 0.02
zenith_value: False
zenith_average: 0.02

comm:
class: pyobs.comm.local.LocalComm
Expand Down
1 change: 1 addition & 0 deletions night_integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ modules:
total_fraction: 0.1
zenith_fraction: 0.0
zenith_value: False
zenith_average: 0.0

comm:
class: pyobs.comm.local.LocalComm
Expand Down
25 changes: 19 additions & 6 deletions pyobs_cloudcover/testing/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ class TestModule(Module):
_INFLUX_ORG = "IAG"
_INFLUX_BUCKET = "allsky"

def __init__(self, image_path: str, total_fraction: float, zenith_fraction: float, zenith_value: bool, *args: Any,
def __init__(self, image_path: str, total_fraction: float, zenith_fraction: float, zenith_value: bool, zenith_average: float, *args: Any,
**kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self._image_path = image_path

self._total_fraction = total_fraction
self._zenith_fraction = zenith_fraction
self._zenith_value = zenith_value
self._zenith_average = zenith_average

self.add_background_task(self.start, restart=False, autostart=True)

Expand All @@ -54,6 +55,7 @@ async def start(self) -> None:

await self._check_http_server()


def _override_measurement_log(self, influx: InfluxDb2Container) -> None:
"""
This exploits the memory locality of other modules when using the LocalComm as a comm object.
Expand Down Expand Up @@ -81,8 +83,8 @@ def _check_influx_entries(self, influx: InfluxDb2Container) -> None:
total_cover_table = result[0].records
zenith_cover_table = result[1].records

np.testing.assert_almost_equal(total_cover_table[0].get_value(), self._total_fraction, 1)
np.testing.assert_almost_equal(zenith_cover_table[0].get_value(), self._zenith_fraction, 1)
np.testing.assert_almost_equal(total_cover_table[0].get_value(), self._total_fraction, 1, err_msg="Wrong total fraction!")
np.testing.assert_almost_equal(zenith_cover_table[0].get_value(), self._zenith_fraction, 1, err_msg="Wrong zenith cover!")

log.info("INFLUX TEST SUCCESS!")

Expand All @@ -91,10 +93,21 @@ async def _check_http_server(self) -> None:
url = cloud_cover._server._url
port = cloud_cover._server._port

await self._check_point_query(url, port)
await self._check_area_query(url, port)

log.info("SERVER TEST SUCCESS!")

async def _check_point_query(self, url: str, port: int) -> None:
async with aiohttp.ClientSession() as session:
async with session.get(f"http://{url}:{port}/query/point?ra=0.0&dec=90.0") as resp:
async with session.get(f"http://{url}:{port}/query/point?az=0.0&alt=90.0") as resp:
data = await resp.json()

assert data["value"] == self._zenith_value
np.testing.assert_almost_equal(data["value"], self._zenith_value, 2, err_msg="Wrong point query result!")

log.info("SERVER TEST SUCCESS!")
async def _check_area_query(self, url: str, port: int) -> None:
async with aiohttp.ClientSession() as session:
async with session.get(f"http://{url}:{port}/query/area?az=0.0&alt=90.0&radius=10.0") as resp:
data = await resp.json()

np.testing.assert_almost_equal(data["value"], self._zenith_average, 2, err_msg="Wrong area query result!")
27 changes: 24 additions & 3 deletions pyobs_cloudcover/web_api/coverage_query_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,38 @@ def _radec_to_altaz(self, ra: float, dec: float, obs_time: datetime.datetime) ->
coord = SkyCoord(ra, dec, unit='deg', frame="icrs", location=self._observer.location, obstime=obs_time)
coord = coord.altaz

return coord.alt.rad, coord.az.rad
return coord.alt.deg, coord.az.deg

def point_query_altaz(self, alt: float, az: float) -> Optional[bool]:
if self._cloud_query_info is None:
return None

cloud_query, obs_time = self._cloud_query_info

cloudiness = cloud_query.query_nearest_coordinate(AltAzCoord(alt, az))
cloudiness = cloud_query.query_nearest_coordinate(AltAzCoord(np.deg2rad(alt), np.deg2rad(az)))

if cloudiness is None:
return None
else:
return bool(cloudiness)
return bool(cloudiness)

def area_query_radec(self, ra: float, dec: float, radius: float) -> Optional[float]:
if self._cloud_query_info is None:
return None
cloud_query, obs_time = self._cloud_query_info

alt, az = self._radec_to_altaz(ra, dec, obs_time)

return self.area_query_altaz(alt, az, radius)

def area_query_altaz(self, alt: float, az: float, radius: float) -> Optional[float]:
if self._cloud_query_info is None:
return None
cloud_query, obs_time = self._cloud_query_info

cloudiness = cloud_query.query_radius(AltAzCoord(np.deg2rad(alt), np.deg2rad(az)), np.deg2rad(radius))

if cloudiness is None:
return None
else:
return float(cloudiness)
28 changes: 26 additions & 2 deletions pyobs_cloudcover/web_api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ def __init__(self, query_executor: CoverageQueryExecutor, url: str = "localhost"
self._port = port

app = web.Application()
app.add_routes([web.get("/query/point", self.point_query)])
app.add_routes([web.get("/query/point", self._point_query)])
app.add_routes([web.get("/query/area", self._area_query)])
self._runner = web.AppRunner(app)

def set_measurement(self, measurement: CloudCoverageInfo) -> None:
Expand All @@ -23,7 +24,7 @@ async def start(self) -> None:
site = web.TCPSite(self._runner, 'localhost', self._port)
await site.start()

async def point_query(self, request: web.Request) -> web.Response:
async def _point_query(self, request: web.Request) -> web.Response:
if "ra" in request.rel_url.query and "dec" in request.rel_url.query:
ra = float(request.rel_url.query["ra"])
dec = float(request.rel_url.query["dec"])
Expand All @@ -40,3 +41,26 @@ async def point_query(self, request: web.Request) -> web.Response:
obs_time = self._query_executor.get_obs_time()

return web.json_response({'value': cover, 'obs_time': obs_time})

async def _area_query(self, request: web.Request) -> web.Response:
if "radius" in request.rel_url.query:
radius = float(request.rel_url.query["radius"])
else:
return web.HTTPBadRequest()

if "ra" in request.rel_url.query and "dec" in request.rel_url.query:
ra = float(request.rel_url.query["ra"])
dec = float(request.rel_url.query["dec"])

cover = self._query_executor.area_query_radec(ra, dec, radius)
elif "alt" in request.rel_url.query and "az" in request.rel_url.query:
alt = float(request.rel_url.query["alt"])
az = float(request.rel_url.query["az"])

cover = self._query_executor.area_query_altaz(alt, az, radius)
else:
return web.HTTPBadRequest()

obs_time = self._query_executor.get_obs_time()

return web.json_response({'value': cover, 'obs_time': obs_time})
26 changes: 23 additions & 3 deletions tests/unit/web_api/test_coverage_query_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ def obs_time():



def test_call_no_map(observer, obs_time):
def test_point_radec_no_map(observer, obs_time):
executor = CoverageQueryExecutor(observer)

assert executor.point_query_radec(10, 10) is None


def test_call(observer, obs_time) -> None:
def test_point_radec(observer, obs_time) -> None:
executor = CoverageQueryExecutor(observer)
executor._radec_to_altaz = Mock(return_value=(np.pi/2, 0)) # type: ignore

Expand All @@ -38,11 +38,31 @@ def test_call(observer, obs_time) -> None:
assert executor.point_query_radec(10, 10) is True


def test_call_nan(observer, obs_time) -> None:
def test_point_radec_nan(observer, obs_time) -> None:
executor = CoverageQueryExecutor(observer)
executor._radec_to_altaz = Mock(return_value=(np.pi/2, 0)) # type: ignore

cloud_query = SkyPixelQuery([AltAzCoord(0, 0)], [None])
executor.set_measurement(CloudCoverageInfo(cloud_query, 1, 2, 0.1, obs_time))

assert executor.point_query_radec(10, 10) is None


def test_area_radec(observer, obs_time) -> None:
executor = CoverageQueryExecutor(observer)
executor._radec_to_altaz = Mock(return_value=(np.pi/2, 0)) # type: ignore

cloud_query = SkyPixelQuery([AltAzCoord(0, 0)], [True])
executor.set_measurement(CloudCoverageInfo(cloud_query, 1, 2, 0.1, obs_time))

assert executor.area_query_radec(10, 10, 90) == 1.0


def test_area_radec_nan(observer, obs_time) -> None:
executor = CoverageQueryExecutor(observer)
executor._radec_to_altaz = Mock(return_value=(np.pi/2, 0)) # type: ignore

cloud_query = SkyPixelQuery([AltAzCoord(0, 0)], [None])
executor.set_measurement(CloudCoverageInfo(cloud_query, 1, 2, 0.1, obs_time))

assert executor.area_query_radec(10, 10, 90) is None

0 comments on commit a70da08

Please sign in to comment.