From b3f639f61bec53e6551fa140f2097d83fa7f2d5a Mon Sep 17 00:00:00 2001 From: Peter Yoachim Date: Fri, 12 Jan 2024 16:02:16 -0800 Subject: [PATCH] unit test for AltAzShadowMaskBasisFunction and add to example scheduler --- .../scheduler/example/example_scheduler.py | 16 ++----- .../model_observatory/kinem_model.py | 4 ++ tests/scheduler/test_utils.py | 47 +++++++++++++++++-- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/rubin_scheduler/scheduler/example/example_scheduler.py b/rubin_scheduler/scheduler/example/example_scheduler.py index 9d988d08..7f928c60 100644 --- a/rubin_scheduler/scheduler/example/example_scheduler.py +++ b/rubin_scheduler/scheduler/example/example_scheduler.py @@ -402,12 +402,10 @@ def blob_for_long( # Masks, give these 0 weight bfs.append( ( - bf.ZenithShadowMaskBasisFunction( + bf.AltAzShadowMaskBasisFunction( nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt, - penalty=np.nan, - site="LSST", ), 0.0, ) @@ -606,7 +604,7 @@ def gen_greedy_surveys( # Masks, give these 0 weight bfs.append( ( - bf.ZenithShadowMaskBasisFunction(nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt), + bf.AltAzShadowMaskBasisFunction(nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt), 0, ) ) @@ -824,12 +822,10 @@ def generate_blobs( # Masks, give these 0 weight bfs.append( ( - bf.ZenithShadowMaskBasisFunction( + bf.AltAzShadowMaskBasisFunction( nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt, - penalty=np.nan, - site="LSST", ), 0.0, ) @@ -1033,12 +1029,10 @@ def generate_twi_blobs( # Masks, give these 0 weight bfs.append( ( - bf.ZenithShadowMaskBasisFunction( + bf.AltAzShadowMaskBasisFunction( nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt, - penalty=np.nan, - site="LSST", ), 0.0, ) @@ -1232,7 +1226,7 @@ def generate_twilight_near_sun( bfs.append((bf.NearSunTwilightBasisFunction(nside=nside, max_airmass=max_airmass), 0)) bfs.append( ( - bf.ZenithShadowMaskBasisFunction(nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt), + bf.AltAzShadowMaskBasisFunction(nside=nside, shadow_minutes=shadow_minutes, max_alt=max_alt), 0, ) ) diff --git a/rubin_scheduler/scheduler/model_observatory/kinem_model.py b/rubin_scheduler/scheduler/model_observatory/kinem_model.py index 852ad26f..b366ce0b 100644 --- a/rubin_scheduler/scheduler/model_observatory/kinem_model.py +++ b/rubin_scheduler/scheduler/model_observatory/kinem_model.py @@ -244,8 +244,12 @@ def setup_telescope( self.mount_settletime = settle_time if alt_limits is None: self.alt_limits = [[self.telalt_minpos_rad, self.telalt_maxpos_rad]] + else: + self.alt_limits = np.radians(alt_limits) if az_limits is None: self.az_limits = [[0, 2.0 * np.pi]] + else: + self.az_limits = np.radians(az_limits) def setup_optics(self, ol_slope=1.0 / 3.5, cl_delay=[0.0, 36.0], cl_altlimit=[0.0, 9.0, 90.0]): """ diff --git a/tests/scheduler/test_utils.py b/tests/scheduler/test_utils.py index ad7c910e..0fb6d34e 100644 --- a/tests/scheduler/test_utils.py +++ b/tests/scheduler/test_utils.py @@ -6,7 +6,7 @@ from rubin_scheduler.data import get_data_dir from rubin_scheduler.scheduler import sim_runner from rubin_scheduler.scheduler.example import example_scheduler, run_sched -from rubin_scheduler.scheduler.model_observatory import ModelObservatory +from rubin_scheduler.scheduler.model_observatory import KinemModel, ModelObservatory from rubin_scheduler.scheduler.utils import restore_scheduler, run_info_table, season_calc from rubin_scheduler.utils import survey_start_mjd @@ -30,7 +30,7 @@ def test_example(self): """Test the example scheduler executes all the expected surveys""" mjd_start = survey_start_mjd() scheduler = example_scheduler(mjd_start=mjd_start) - observatory, scheduler, observations = run_sched(scheduler, mjd_start=mjd_start, survey_length=5) + observatory, scheduler, observations = run_sched(scheduler, mjd_start=mjd_start, survey_length=7) u_notes = np.unique(observations["note"]) # Note that some of these may change and need to be updated if survey @@ -63,7 +63,7 @@ def test_example(self): "twilight_near_sun, 2", "twilight_near_sun, 3", ] - + for note in notes_to_check: assert note in u_notes @@ -71,6 +71,47 @@ def test_example(self): os.path.isfile(os.path.join(get_data_dir(), "scheduler/dust_maps/dust_nside_32.npz")), "Test data not available.", ) + def test_altaz_limit(self): + """Test that setting some azimuth limits via the kinematic model works""" + mjd_start = survey_start_mjd() + scheduler = example_scheduler(mjd_start=mjd_start) + km = KinemModel(mjd0=mjd_start) + km.setup_telescope(az_limits=[[0.0, 90.0], [270.0, 360.0]]) + mo = ModelObservatory(mjd_start=mjd_start, kinem_model=km) + + mo, scheduler, observations = sim_runner( + mo, + scheduler, + survey_length=3.0, + verbose=False, + filename=None, + ) + + az = np.degrees(observations["az"]) + forbidden = np.where((az > 90) & (az < 270))[0] + # Let a few pairs try to complete since by default we don't use an agressive shadow_minutes + n_forbidden = np.size( + [obs for obs in observations[forbidden]["note"] if (("pair_33" not in obs) | (", b" not in obs))] + ) + + assert n_forbidden == 0 + + km = KinemModel(mjd0=mjd_start) + km.setup_telescope(alt_limits=[[40.0, 70.0]]) + mo = ModelObservatory(mjd_start=mjd_start, kinem_model=km) + + mo, scheduler, observations = sim_runner( + mo, + scheduler, + survey_length=3.0, + verbose=False, + filename=None, + ) + alt = np.degrees(observations["alt"]) + n_forbidden = np.size(np.where((alt > 70) & (alt < 40))[0]) + + assert n_forbidden == 0 + def test_restore(self): """Test we can restore a scheduler properly""" # MJD set so it's in test data range