Source code for rubin_scheduler.scheduler.utils.too_objects
import numpy as np
from rubin_scheduler.utils import _approx_ra_dec2_alt_az
__all__ = [
"TargetoO",
"SimTargetooServer",
]
[docs]
class TargetoO:
"""Class to hold information about a target of opportunity object
Parameters
----------
tooid : `str`
Unique ID for the ToO. Probably using `source` from EFD.
footprints : `np.array`
np.array healpix maps. 1 for areas to observe, 0 for no observe.
Can use np.nan for no-observe pixels, but that will be interpreted
to mean the map cannot expand if the resolution chages.
mjd_start : `float`
The MJD the ToO starts
duration : `float`
Duration of the ToO (days).
ra_rad_center : `float`
RA of the estimated center of the event (radians).
dec_rad_center : `float`
Dec of the estimated center of the event (radians).
too_type : `str`
The type of ToO that is made.
posterior_distance : `float`
The posterior distance of the event. (kpc)
interrupt_queue : `bool`
This ToO is urgent, so if it is high enoug in the
sky, the scheduler should flush its queue so ToO
observations can start without waiting.
alt_limit : `float`
Altitude limit that some part of the ToO footprint
must be above to trigger a queue flush (degrees).
"""
def __init__(
self,
tooid,
footprint,
mjd_start,
duration=None,
ra_rad_center=None,
dec_rad_center=None,
too_type=None,
posterior_distance=None,
interrupt_queue=True,
alt_limit=20,
):
self.footprint = footprint
self.duration = duration
self.id = tooid
self.mjd_start = mjd_start
self.ra_rad_center = ra_rad_center
self.dec_rad_center = dec_rad_center
self.too_type = too_type
self.posterior_distance = posterior_distance
self.alt_limit = np.radians(alt_limit)
self.interrupt_queue = interrupt_queue
[docs]
def queue_should_flush(self, conditions):
"""Given current conditions, is the ToO
probably visible and should interrupt the queue
"""
# Kwarg set saying don't interrupt
if not self.interrupt_queue:
return False
result = True
# If we have a ra,dec center, check it is above alt limit
if self.ra_rad_center is not None:
alt, az = _approx_ra_dec2_alt_az(
self.ra_rad_center,
self.dec_rad_center,
conditions.site.latitude_rad,
conditions.site.longitude_rad,
conditions.mjd,
)
if alt < self.alt_limit:
result = False
# No ra,dec center, check if any part of footprint
# is above alt limit.
else:
indx = np.where(conditions.alt >= self.alt_limit)[0]
# footprint pixels could be NaN for not-observe, use 0 here.
fp_pix = np.nan_to_num(self.footprint[indx], copy=True, nan=0)
if np.max(fp_pix) == 0:
result = False
return result
[docs]
class SimTargetooServer:
"""Wrapper to deliver a targetoO object at the right time"""
def __init__(self, targeto_o_list):
self.targeto_o_list = targeto_o_list
self.mjd_starts = np.array([too.mjd_start for too in self.targeto_o_list])
durations = np.array([too.duration for too in self.targeto_o_list], dtype="float")
# Fill any Nans with a default value.
# This should never be necessary in full simulations, where duration
# is always set by gen_events.
np.nan_to_num(durations, copy=False, nan=3)
self.mjd_ends = self.mjd_starts + durations
def __call__(self, mjd):
in_range = np.where((mjd > self.mjd_starts) & (mjd < self.mjd_ends))[0]
result = None
if in_range.size > 0:
result = [self.targeto_o_list[i] for i in in_range]
return result