Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tickets/PREOPS-4643: remove dependency of prenight on scheduler pickle #57

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 2 additions & 65 deletions schedview/app/prenight/prenight.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import pandas as pd
import panel as pn
import param
import rubin_scheduler.scheduler.example
from astropy.time import Time
from rubin_scheduler.scheduler.model_observatory import ModelObservatory
from rubin_scheduler.utils import survey_start_mjd
Expand All @@ -40,7 +39,6 @@
]
DEFAULT_TIMEZONE = AVAILABLE_TIMEZONES[0]
DEFAULT_CURRENT_TIME = Time(max(Time.now().mjd, survey_start_mjd()), format="mjd")
USE_EXAMPLE_SCHEDULER = False
DEFAULT_MODEL_OBSERVATORY = ModelObservatory(init_load_length=1)
DEFAULT_MODEL_OBSERVATORY.sky_model.load_length = 1

Expand Down Expand Up @@ -93,17 +91,6 @@ class Prenight(param.Parameterized):
label="OpSim output database path or URL",
)

scheduler_fname_doc = """URL or file name of the scheduler pickle file.
Such a pickle file can either be of an instance of a subclass of
rubin_scheduler.scheduler.schedulers.CoreScheduler, or a tuple of the form
(scheduler, conditions), where scheduler is an instance of a subclass of
rubin_scheduler.scheduler.schedulers.CoreScheduler, and conditions is an
instance of rubin_scheduler.scheduler.conditions.Conditions."""
scheduler_fname = param.String(
doc=scheduler_fname_doc,
label="URL or file name of scheduler pickle file",
)

rewards_fname = param.String(
doc="URL or file name of the rewards HDF5 file.",
label="URL or file name of rewards HDF5 file",
Expand Down Expand Up @@ -168,9 +155,6 @@ class Prenight(param.Parameterized):
# and communication overhead is reduced.
_visits_cds = param.Parameter()

# An instance of rubin_scheduler.scheduler.schedulers.CoreScheduler
_scheduler = param.Parameter()

_almanac_events = schedview.param.DataFrame(
None,
doc="Events from the rubin_scheduler alamanc",
Expand Down Expand Up @@ -419,24 +403,6 @@ def custom_hvplot3(self):
def custom_hvplot4(self):
return self.hvplot(4)

@param.depends("scheduler_fname", watch=True)
def _update_scheduler(self):
self.logger.info("Starting to update the scheduler.")
try:
(
scheduler,
conditions,
) = schedview.collect.scheduler_pickle.read_scheduler(self.scheduler_fname)

self._scheduler = scheduler
self.logger.info("Finished updating the scheduler.")
except Exception as e:
self.logger.error(f"Could not load scheduler from {self.scheduler_fname} {e}")
if USE_EXAMPLE_SCHEDULER:
self.logger.info("Starting to load example scheduler.")
self._scheduler = rubin_scheduler.scheduler.example.example_scheduler(nside=self._nside)
self.logger.info("Finished loading example scheduler.")

@param.depends(
"_visits_cds",
"_almanac_events",
Expand Down Expand Up @@ -505,7 +471,6 @@ def horizon_map(self):
return fig

@param.depends(
"_scheduler",
"_visits",
)
def visit_skymaps(self):
Expand All @@ -520,14 +485,10 @@ def visit_skymaps(self):
if self._visits is None:
return "No visits are loaded."

if self._scheduler is None:
return "No scheduler is loaded."

self.logger.info("Starting to update visit skymaps")

vmap, vmap_data = schedview.plot.visitmap.create_visit_skymaps(
visits=self._visits,
scheduler=self._scheduler,
night_date=self.night,
timezone=self.timezone,
observatory=self._observatory,
Expand Down Expand Up @@ -759,7 +720,6 @@ def make_app(
self,
night_date=None,
opsim_db=None,
scheduler=None,
rewards=None,
shown_tabs=None,
custom_hvplot_tab_settings_file=None,
Expand All @@ -772,8 +732,6 @@ def make_app(
The date of the night to display.
opsim_db : `str`, optional
Path to the opsim output database file.
scheduler : `str`, optional
Path to the scheduler pickle file.
rewards : `str`, optional
Path to the rewards hdf5 file.
shown_tabs : `list` [`str`], optional
Expand All @@ -794,9 +752,6 @@ def make_app(
if night_date is not None:
self.night = night_date

if scheduler is not None:
self.scheduler_fname = scheduler

if opsim_db is not None:
self.opsim_output_fname = opsim_db

Expand All @@ -817,7 +772,6 @@ def make_app(
parameters=[
"night",
"timezone",
"scheduler_fname",
"opsim_output_fname",
],
name="<h2>Parameters</h2>",
Expand Down Expand Up @@ -856,19 +810,12 @@ class RestrictedInputPrenight(Prenight):
path=f"{PACKAGE_DATA_DIR}/*opsim*.db", label="OpSim output database", default=None, allow_None=True
)

scheduler_fname = schedview.param.FileSelectorWithEmptyOption(
path=f"{PACKAGE_DATA_DIR}/*scheduler*.p*",
label="Scheduler pickle file",
default=None,
allow_None=True,
)

rewards_fname = schedview.param.FileSelectorWithEmptyOption(
path=f"{PACKAGE_DATA_DIR}/*rewards*.h5", label="rewards HDF5 file", default=None, allow_None=True
)

def __init__(self, data_dir=None, **kwargs):
# A few arguments (scheduler, opsim_db, rewards) will be used
# A few arguments (opsim_db, rewards) will be used
# later in this method to set the options for parameters, but
# are not themselves parameters. So, remove them them the
# params list before calling super().__init__().
Expand All @@ -880,7 +827,6 @@ def __init__(self, data_dir=None, **kwargs):
# they can be updated by key.
fname_params = {
"opsim_db": self.param["opsim_output_fname"],
"scheduler": self.param["scheduler_fname"],
"reward": self.param["rewards_fname"],
}

Expand All @@ -890,7 +836,6 @@ def __init__(self, data_dir=None, **kwargs):
if data_dir is not None:
fname_glob = {
"opsim_db": f"{data_dir}/*opsim*.db",
"scheduler": f"{data_dir}/*scheduler*.p*",
"reward": f"{data_dir}/*rewards*.h5",
}

Expand Down Expand Up @@ -920,7 +865,7 @@ def prenight_app(*args, **kwargs):
data_dir = None

specified_data_files = {}
data_args = set(["opsim_db", "scheduler", "rewards"]) & set(kwargs.keys())
data_args = set(["opsim_db", "rewards"]) & set(kwargs.keys())
for data_arg in data_args:
# Fully resolve the path to the file.
file_path = Path(kwargs[data_arg]).resolve()
Expand Down Expand Up @@ -961,14 +906,6 @@ def parse_prenight_args():
help="The path to the OpSim output database.",
)

parser.add_argument(
"--scheduler",
"-s",
type=str,
default=None,
help="The path to the scheduler pickle file.",
)

parser.add_argument(
"--rewards",
"-r",
Expand Down
32 changes: 6 additions & 26 deletions schedview/collect/footprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,13 @@
from rubin_scheduler.scheduler.utils.sky_area import EuclidOverlapFootprint


def get_footprint(scheduler=None):
"""Extract the footprint from a survey."""
# This is a hack, good enough for example code, not for production.
def get_footprint(nside=32):
"""Get the survey footprint."""

# Look through the scheduler to find a blob survey that has a footprint
# basis function
footprint = None
if scheduler is None:
nside = 32
else:
nside = scheduler.nside
for survey_tier in scheduler.survey_lists:
for survey in survey_tier:
if survey.__class__.__name__ in ["GreedySurvey"]:
for basis_function in survey.basis_functions:
bf_class = basis_function.__class__
if bf_class.__name__.startswith("Footprint"):
if footprint is None:
footprint = np.sum(basis_function.footprint.footprints, axis=0)
else:
footprint += np.sum(basis_function.footprint.footprints, axis=0)

if footprint is None:
# Load up a default footprint from rubin_scheduler
sky_area_generator = EuclidOverlapFootprint(nside=nside)
band_footprints, _ = sky_area_generator.return_maps()
footprint = np.sum(band_footprints[b] for b in band_footprints.dtype.fields.keys())
# Load up a default footprint from rubin_scheduler
sky_area_generator = EuclidOverlapFootprint(nside=nside)
band_footprints, _ = sky_area_generator.return_maps()
footprint = np.sum(band_footprints[b] for b in band_footprints.dtype.fields.keys())

footprint[footprint == 0] = np.nan
return footprint
14 changes: 5 additions & 9 deletions schedview/plot/visitmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ def plot_visit_planisphere(

def create_visit_skymaps(
visits,
scheduler,
night_date,
nside=32,
observatory=None,
timezone="Chile/Continental",
planisphere_only=False,
Expand All @@ -418,12 +418,11 @@ def create_visit_skymaps(

If a string, the file name of the opsim database from which the
visits should be loaded.
scheduler : `CoreScheduler` or `str`
The scheduler from which to extract the footprint, or the name of
a file from which such a scheduler should be loaded.
night_date : `datetime.date`
The calendar date of the evening of the night for which
to plot the visits.
nside : `int`, optional
The healpix nside to use for the map.
observatory : `ModelObservatory`, optional
Provides the location of the observatory, used to compute
night start and end times.
Expand Down Expand Up @@ -455,14 +454,11 @@ def create_visit_skymaps(
if end_time is not None:
visits.query(f"observationStartMJD <= {Time(end_time).mjd}", inplace=True)

if isinstance(scheduler, str):
scheduler, conditions = schedview.collect.scheduler_pickle.read_scheduler(scheduler)

if observatory is None:
observatory = ModelObservatory(nside=scheduler.nside, init_load_length=1)
observatory = ModelObservatory(nside=nside, init_load_length=1)
observatory.sky_model.load_length = 1

footprint = schedview.collect.footprint.get_footprint(scheduler)
footprint = schedview.collect.footprint.get_footprint(nside)
observatory.mjd = end_time.mjd
conditions = observatory.return_conditions()
data = {"visits": visits, "footprint": footprint, "conditions": conditions}
Expand Down
2 changes: 0 additions & 2 deletions tests/test_prenight.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ def test_prenight_app(self):
sample_data_dir = importlib.resources.files("schedview").joinpath("data")

sample_opsim_db = str(sample_data_dir.joinpath("sample_opsim.db"))
sample_scheduler_pickle = str(sample_data_dir.joinpath("sample_scheduler.pickle.xz"))
sample_rewards_h5 = str(sample_data_dir.joinpath("sample_rewards.h5"))

# Use a separate test custom settings file from the sample, because
Expand All @@ -24,7 +23,6 @@ def test_prenight_app(self):

app = prenight_app(
opsim_db=sample_opsim_db,
scheduler=sample_scheduler_pickle,
rewards=sample_rewards_h5,
custom_hvplot_tab_settings_file=custom_hvplot_tabs,
)
Expand Down
Loading