From 3da5140151887510c10b30b84f5e0d52d3e52f82 Mon Sep 17 00:00:00 2001 From: Peter Yoachim Date: Thu, 7 Sep 2023 16:34:22 -0700 Subject: [PATCH 1/3] basis functions for twilight survey --- .../basis_functions/basis_functions.py | 24 ++++++++++++++ .../basis_functions/feasibility_funcs.py | 31 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/rubin_sim/scheduler/basis_functions/basis_functions.py b/rubin_sim/scheduler/basis_functions/basis_functions.py index 4d871ccd0..9e9f2dbbf 100644 --- a/rubin_sim/scheduler/basis_functions/basis_functions.py +++ b/rubin_sim/scheduler/basis_functions/basis_functions.py @@ -37,6 +37,7 @@ "AvoidDirectWind", "BalanceVisits", "RewardNObsSequence", + "FilterDistBasisFunction" ) import warnings @@ -194,6 +195,29 @@ def check_feasibility(self, conditions): return result +class FilterDistBasisFunction(BaseBasisFunction): + """Track filter distribution, increase reward as fraction of observations in + specified filter drops. + """ + + def __init__(self, filtername="r"): + super(FilterDistBasisFunction, self).__init__(filtername=filtername) + + self.survey_features = {} + # Count of all the observations + self.survey_features["n_obs_count_all"] = features.NObsCount(filtername=None) + # Count in filter + self.survey_features["n_obs_count_in_filt"] = features.NObsCount( + filtername=filtername + ) + + def _calc_value(self, conditions, indx=None): + result = self.survey_features["n_obs_count_all"].feature / ( + self.survey_features["n_obs_count_in_filt"].feature + 1 + ) + return result + + class NObsPerYearBasisFunction(BaseBasisFunction): """Reward areas that have not been observed N-times in the last year diff --git a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py index 7e90cac6e..07eb83331 100644 --- a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py +++ b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py @@ -19,6 +19,7 @@ "EndOfEveningBasisFunction", "TimeToScheduledBasisFunction", "LimitObsPnightBasisFunction", + "SunHighLimitBasisFunction", ) import matplotlib.pylab as plt @@ -52,6 +53,36 @@ def check_feasibility(self, conditions): return result +class SunHighLimitBasisFunction(BaseBasisFunction): + """Only execute if the sun is high. Have a sum alt limit for sunset, and a time + until 12 degree twilight for sun rise. + + Parameters + ---------- + sun_alt_limit : `float` + The sun altitude limit (degrees). Sun must be higher than this at sunset to execute + """ + + def __init__(self, sun_alt_limit=-14.8, time_to_12deg=21.0, time_remaining=15.0): + super(SunHighLimitBasisFunction, self).__init__() + self.sun_alt_limit = np.radians(sun_alt_limit) + self.time_to_12deg = time_to_12deg / 60.0 / 24.0 + self.time_remaining = time_remaining / 60.0 / 24.0 + + def check_feasibility(self, conditions): + result = False + + # If the sun is high, it's ok to execute + if conditions.sun_alt > self.sun_alt_limit: + result = True + time_left = conditions.sun_n12_rising - conditions.mjd + if time_left < self.time_to_12deg: + result = True + if time_left < self.time_remaining: + result = False + return result + + class OnceInNightBasisFunction(BaseBasisFunction): """Stop observing if something has been executed already in the night From 8037e1dc50acb9cbeeae0b0a0be5deb42f3956b9 Mon Sep 17 00:00:00 2001 From: Peter Yoachim Date: Thu, 7 Sep 2023 16:36:31 -0700 Subject: [PATCH 2/3] default to u swaps with y for simple filter scheduler --- rubin_sim/scheduler/basis_functions/basis_functions.py | 6 ++---- rubin_sim/scheduler/basis_functions/feasibility_funcs.py | 4 ++++ rubin_sim/scheduler/schedulers/filter_scheduler.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/rubin_sim/scheduler/basis_functions/basis_functions.py b/rubin_sim/scheduler/basis_functions/basis_functions.py index 9e9f2dbbf..897d18198 100644 --- a/rubin_sim/scheduler/basis_functions/basis_functions.py +++ b/rubin_sim/scheduler/basis_functions/basis_functions.py @@ -37,7 +37,7 @@ "AvoidDirectWind", "BalanceVisits", "RewardNObsSequence", - "FilterDistBasisFunction" + "FilterDistBasisFunction", ) import warnings @@ -207,9 +207,7 @@ def __init__(self, filtername="r"): # Count of all the observations self.survey_features["n_obs_count_all"] = features.NObsCount(filtername=None) # Count in filter - self.survey_features["n_obs_count_in_filt"] = features.NObsCount( - filtername=filtername - ) + self.survey_features["n_obs_count_in_filt"] = features.NObsCount(filtername=filtername) def _calc_value(self, conditions, indx=None): result = self.survey_features["n_obs_count_all"].feature / ( diff --git a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py index 07eb83331..5f545894f 100644 --- a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py +++ b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py @@ -61,6 +61,10 @@ class SunHighLimitBasisFunction(BaseBasisFunction): ---------- sun_alt_limit : `float` The sun altitude limit (degrees). Sun must be higher than this at sunset to execute + time_to_12deg : `float` + How much time must be remaining before 12 degree twilight in the morning (minutes) + time_remaining : `float` + Minimum about of time that must be available before trying to execute (minutes) """ def __init__(self, sun_alt_limit=-14.8, time_to_12deg=21.0, time_remaining=15.0): diff --git a/rubin_sim/scheduler/schedulers/filter_scheduler.py b/rubin_sim/scheduler/schedulers/filter_scheduler.py index a7ff45196..b47d58aac 100644 --- a/rubin_sim/scheduler/schedulers/filter_scheduler.py +++ b/rubin_sim/scheduler/schedulers/filter_scheduler.py @@ -29,7 +29,7 @@ def __call__(self, conditions): if IntRounded(conditions.moon_phase) > self.illum_limit_ir: result = ["g", "r", "i", "z", "y"] else: - result = ["u", "g", "r", "i", "y"] + result = ["u", "g", "r", "i", "z"] return result From 13a903c6ba60492f8adeddbb1f1c5e320f2f0da5 Mon Sep 17 00:00:00 2001 From: Peter Yoachim Date: Fri, 8 Sep 2023 16:03:03 -0700 Subject: [PATCH 3/3] throw error if configured in a way that will never execute --- rubin_sim/scheduler/basis_functions/feasibility_funcs.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py index 5f545894f..899ea27e6 100644 --- a/rubin_sim/scheduler/basis_functions/feasibility_funcs.py +++ b/rubin_sim/scheduler/basis_functions/feasibility_funcs.py @@ -69,6 +69,11 @@ class SunHighLimitBasisFunction(BaseBasisFunction): def __init__(self, sun_alt_limit=-14.8, time_to_12deg=21.0, time_remaining=15.0): super(SunHighLimitBasisFunction, self).__init__() + if time_to_12deg < time_remaining: + raise ValueError( + "time_to_12deg value of %f is less than time_remaining value of %f." + % (time_to_12deg, time_remaining) + ) self.sun_alt_limit = np.radians(sun_alt_limit) self.time_to_12deg = time_to_12deg / 60.0 / 24.0 self.time_remaining = time_remaining / 60.0 / 24.0