Skip to content

Commit 60155f6

Browse files
committed
#None: better decision on when to plan observation (see RELEASE_NOTES)
1 parent 88fc5ae commit 60155f6

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

RELEASE_NOTES

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ do not repeat trying
152152
alerts)
153153
- Removed some unnecessary imports
154154

155+
## 0.4.16
156+
157+
- Improved decision making for planning: no plans will be generated for a given event
158+
if the database already contains a cross-matched event, which localization completely
159+
covers the skymap of the current event. Thus, if the older cross-matched event has an
160+
error radius smaller than 1.5 arcmin or new area is more than 75% of the older one, no
161+
plans will be created.
162+
- Fixed type hint for `GladeCatalog.lazy_load_catalog`.
163+
155164

156165
# v0.3.0
157166

aware/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = (0, 4, 15)
1+
__version__ = (0, 4, 16)
22
__strversion__ = "{}.{}.{}".format(__version__)

aware/consumer/main.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from __future__ import annotations
1515

1616
import asyncio
17+
from io import BytesIO
1718
import pickle
1819
from contextlib import suppress
1920
from datetime import datetime
@@ -56,7 +57,6 @@
5657
from ..site import Telescopes, default_sites
5758
from ..topic import TOPICS, full_topic_name_to_short
5859

59-
6060
topics = CfgOption("topics", TOPICS, list)
6161
timeout = CfgOption("timeout", -1, float)
6262
start_date = CfgOption(
@@ -204,7 +204,7 @@ async def consume_messages(self):
204204
message = await self._poll_message(timeout=timeout.value)
205205
await self._process_message(message)
206206
# await self.consume_messages()
207-
207+
208208
# Read several new messages to have concurrency. Otherwise, if we poll,
209209
# only for the last alert type in topics alerts will be received.
210210
# for message in self.consumer.consume(
@@ -230,7 +230,7 @@ async def _poll_message(self, timeout: float) -> Message | None:
230230
"""
231231
try:
232232
message = await poll_message(self.consumer, timeout)
233-
233+
234234
log.debug(
235235
"ConsumeLoop._consume_message(): received message on %s",
236236
datetime.now().isoformat(),
@@ -322,7 +322,7 @@ def name_xmatch(info: TargetInfo) -> list[dict]:
322322
except Exception as e:
323323
log.error("Failed to crossmatch alert by name: %s", e)
324324
return matched_alerts
325-
325+
326326
if info.localization:
327327
matched_alerts = await spatial_xmatch(info)
328328
else:
@@ -359,6 +359,7 @@ def name_xmatch(info: TargetInfo) -> list[dict]:
359359
matched_error_radii = [a["error_radius"] for a in matched_alerts]
360360
i_min = np.argmin(matched_error_radii)
361361
matched_error_radius = matched_error_radii[i_min]
362+
matched_localization = matched_alerts[i_min]["localization"]
362363
error_radius = info.localization.error_radius().to_value(u.deg)
363364

364365
if error_radius < matched_error_radius:
@@ -369,8 +370,32 @@ def name_xmatch(info: TargetInfo) -> list[dict]:
369370
event,
370371
len(matched_alerts),
371372
)
372-
send_obs_data = True
373+
373374
refines_localization = True
375+
376+
# If matched error radius is already small enough, no need to
377+
# run the planner again. Since, skymap is wholy inside FOV of a
378+
# telescope anyway.
379+
SMALL_RADIUS = 1.5 / 60 # 1.5 arcmin
380+
refines_small = matched_error_radius < SMALL_RADIUS
381+
382+
# The same, when newer sky map is fully contained inside old one
383+
# borders, and its area not significantly smaller than the old
384+
# one. We probably already have plans for that skymap region.
385+
matched_moc = pickle.loads(matched_localization).moc()
386+
new_moc = info.localization.moc()
387+
SKY_MAP_AREA_FRACTION = 0.75
388+
new_inside_old = (
389+
new_moc.union(matched_moc) == new_moc
390+
and new_moc.sky_fraction
391+
> SKY_MAP_AREA_FRACTION * matched_moc.sky_fraction
392+
)
393+
394+
if refines_small or new_inside_old:
395+
send_obs_data = False
396+
else:
397+
send_obs_data = True
398+
374399
else:
375400
send_obs_data = False
376401
refines_localization = False
@@ -457,7 +482,8 @@ def name_xmatch(info: TargetInfo) -> list[dict]:
457482

458483
# Run planner in the separate thread, because it is a blocking function
459484
@aiomisc.threaded
460-
def plan_func(planner: ObservationPlanner):
485+
def plan_func(planner: ObservationPlanner) -> dict:
486+
plan_dicts = {}
461487
try:
462488
planner.plan_observations(
463489
epoch=now,
@@ -471,10 +497,11 @@ def plan_func(planner: ObservationPlanner):
471497
plan_result = planner.save_or_update_planning()
472498
json_plan_reg_fn, plan_data = plan_result
473499
plan_dicts = plan_data.get("plans", [])
474-
return plan_dicts
475500
except Exception as e:
476501
log.error("Error while planning observations: %s", e)
477502

503+
return plan_dicts
504+
478505
# Plan only for not-empty localization skymaps
479506
if info.localization is not None:
480507
plan_dicts = await plan_func(planner)
@@ -496,7 +523,7 @@ def plan_func(planner: ObservationPlanner):
496523
target_info=info,
497524
)
498525
except (LookupError, TypeError, ArithmeticError):
499-
# If registry contains site_id not presented in
526+
# If registry contains site_id not presented in
500527
# default_sites
501528
pass
502529
else:

aware/glade/main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class GladeCatalog:
105105
coord = None
106106

107107
@staticmethod
108-
def lazy_load_catalog() -> tuple(Table, SkyCoord):
108+
def lazy_load_catalog() -> tuple[Table, SkyCoord]:
109109
if not getattr(GladeCatalog, "table", None) or not getattr(
110110
GladeCatalog, "coord", None
111111
):
@@ -130,10 +130,10 @@ def query_skymap_local(
130130
dist_hi_bound: u.Unit = np.inf * u.Mpc,
131131
prob: float = 0.9,
132132
) -> list[GladeGalaxy]:
133-
log.debug("loading local GLADE+ catalog into RAM")
133+
log.debug("loading local GLADE+ catalog into RAM ...")
134134
table, coord = GladeCatalog.lazy_load_catalog()
135135

136-
log.debug("query GLADE+ catalog against %.1f per cent contour", prob * 100)
136+
log.debug("query GLADE+ catalog against %.1f per cent contour ...", prob * 100)
137137
match_res = crossmatch(sky_map_moc, coordinates=coord, contours=(prob,))
138138
galaxies = [
139139
GladeGalaxy(

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "AWARE"
7-
version = "0.4.15"
7+
version = "0.4.16"
88
authors = [{name="Nicolai Pankov", email="colinsergesen@gmail.com"}]
99
requires-python = ">=3.9,<3.12"
1010
dependencies = [

0 commit comments

Comments
 (0)