diff --git a/Scheduler/feature_scheduler/maintel/fbs_config_sit_survey_block_t345.py b/Scheduler/feature_scheduler/maintel/fbs_config_sit_survey_block_t345.py new file mode 100644 index 00000000..724e9346 --- /dev/null +++ b/Scheduler/feature_scheduler/maintel/fbs_config_sit_survey_block_t345.py @@ -0,0 +1,194 @@ +# This file is part of ts_config_ocs. +# +# Developed for the Vera Rubin Observatory Telescope and Site System. +# This product includes software developed by the LSST Project +# (https://www.lsst.org). +# See the COPYRIGHT file at the top-level directory of this distribution +# for details of code ownership. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import numpy as np +from rubin_scheduler.scheduler import basis_functions, detailers, example, features +from rubin_scheduler.scheduler.schedulers import CoreScheduler +from rubin_scheduler.scheduler.surveys import BlobSurvey +from rubin_scheduler.scheduler.utils import CurrentAreaMap, Footprint +from rubin_scheduler.site_models import Almanac + + +def get_scheduler(): + nside = 32 + science_program = "BLOCK-T345" + survey_start = 60653.5 + camera_rot_limits = [-80, 80] + + map_band_to_filtername = { + "u": "u_02", + "g": "g_01", + "r": "r_03", + "i": "i_06", + "z": "z_03", + "y": "y_04", + } + + filtername = map_band_to_filtername["r"] + filtername2 = map_band_to_filtername["g"] + + # Masks are fine - no band specific information. + mask_basis_functions = example.standard_masks( + nside=nside, + # Let's avoid the moon by this many degrees + moon_distance=30.0, + # Erik says to make wind speed minor so set limit high + wind_speed_maximum=50.0, + # I think these are the values appropriate for alt limits now? + min_alt=40, + max_alt=70, + min_az=220, + max_az=360, + # Avoid going into avoidance regions 30 minutes into the future + shadow_minutes=30, + ) + # Mask basis functions have zero weights. + mask_basis_functions_weights = [0 for mask in mask_basis_functions] + + # Set up footprint stuff here instead of in rubin_scheduler. + # Use the Almanac to find the position of the sun at the start of survey. + almanac = Almanac(mjd_start=survey_start) + sun_moon_info = almanac.get_sun_moon_positions(survey_start) + sun_ra_start = sun_moon_info["sun_RA"].copy() + # So this is a dictionary of filternames : int. + filterdict = {} + for i, f in enumerate(map_band_to_filtername.values()): + filterdict[f] = i + footprints = Footprint( + filters=filterdict, + mjd_start=survey_start, + sun_ra_start=sun_ra_start, + nside=nside, + ) + # need to remap this to filtername not band + footprint = CurrentAreaMap(nside=nside) + footprint_hp, labels = footprint.return_maps() + new_dtype = np.dtype([(map_band_to_filtername[f], " 0] + [ + (i[0], i[1]) for i in rf2 if i[1] > 0 + ] + # Remove the M5Diff basis functions as unusable at present + reward_functions = [ + (bf, weight) + for (bf, weight) in reward_functions + if not isinstance(bf, basis_functions.M5DiffBasisFunction) + ] + + # unpack the basis functions and weights + reward_basis_functions_weights = [val[1] for val in reward_functions] + reward_basis_functions = [val[0] for val in reward_functions] + + # Set up blob surveys. + pair_time = 20 + if filtername2 is None: + survey_name = "simple pair %i, %s" % (pair_time, filtername) + else: + survey_name = "simple pair %i, %s%s" % (pair_time, filtername, filtername2) + + # Set up detailers for each requested observation. + detailer_list = [] + # Avoid camera rotator limits. + detailer_list.append( + detailers.CameraRotDetailer( + min_rot=np.min(camera_rot_limits), max_rot=np.max(camera_rot_limits) + ) + ) + # Reorder visits in a blob so that closest to current altitude is first. + detailer_list.append(detailers.CloseAltDetailer()) + # Add a detailer to label visits as either first or second of the pair. + if filtername2 is not None: + detailer_list.append(detailers.TakeAsPairsDetailer(filtername=filtername2)) + + # Set up the survey. + ignore_obs = ["DD"] + + BlobSurvey_params = { + "slew_approx": 7.5, + "filter_change_approx": 140.0, + "read_approx": 2.4, + "flush_time": pair_time * 3, + "smoothing_kernel": None, + "nside": nside, + "seed": 42, + "dither": True, + "twilight_scale": False, + } + + pair_survey = BlobSurvey( + reward_basis_functions + mask_basis_functions, + reward_basis_functions_weights + mask_basis_functions_weights, + filtername1=filtername, + filtername2=filtername2, + exptime=150, + ideal_pair_time=pair_time, + survey_name=survey_name, + ignore_obs=ignore_obs, + nexp=1, + detailers=detailer_list, + science_program=science_program, + **BlobSurvey_params, + ) + + # Tucking this here so we can look at how many observations + # recorded for this survey and what was the last one. + pair_survey.extra_features["ObsRecorded"] = features.NObsCount() + pair_survey.extra_features["LastObs"] = features.LastObservation() + + scheduler = CoreScheduler([pair_survey], nside=nside) + return nside, scheduler + + +if __name__ == "config": + nside, scheduler = get_scheduler() diff --git a/Scheduler/observing_blocks_maintel/AOS/BLOCK-T345.json b/Scheduler/observing_blocks_maintel/AOS/BLOCK-T345.json new file mode 100644 index 00000000..b61a4b80 --- /dev/null +++ b/Scheduler/observing_blocks_maintel/AOS/BLOCK-T345.json @@ -0,0 +1,79 @@ +{ + "name": "AOSSurveyMode", + "program": "BLOCK-T345", + "constraints": [], + "scripts": [ + { + "name": "maintel/track_target.py", + "standard": true, + "parameters": { + "target_name": "$name", + "slew_icrs": { + "ra": "$ra", + "dec": "$dec" + }, + "rot_value": "$rot", + "rot_type": "PhysicalSky", + "az_wrap_strategy": "NOUNWRAP" + } + }, + { + "name": "maintel/close_loop_comcam.py", + "standard": true, + "parameters": { + "exposure_time": 15, + "max_iter": 1, + "gain_sequence": [ + 0.5 + ], + "mode": "FAM", + "program": "$program", + "note": "closed_loop_aos_survey_mode", + "reason": "aos_survey_mode", + "filter": "$band_filter", + "used_dofs": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 37, + 38, + 39, + 40, + 41, + 42, + 45, + 46 + ], + "apply_corrections": true, + "use_ocps": true + } + } + ], + "configuration_schema": "" +} \ No newline at end of file diff --git a/Scheduler/v7/maintel_fbs_sit_block_t345.yaml b/Scheduler/v7/maintel_fbs_sit_block_t345.yaml new file mode 100644 index 00000000..df2b096e --- /dev/null +++ b/Scheduler/v7/maintel_fbs_sit_block_t345.yaml @@ -0,0 +1,47 @@ +maintel: + driver_type: feature_scheduler + mode: ADVANCE + startup_type: COLD + startup_database: /home/saluser/rubin_sim_data/fbs_observation_database_maintel.sql + instrument_name: CCCamera + models: + observatory_model: + camera: + filter_max_changes_burst_num: 1000000 + filter_max_changes_avg_num: 30000 + optics_loop_corr: + tel_optics_cl_alt_limit: + - 0 + - 60 + - 90 + park: + filter_position: r_03 + driver_configuration: + parameters: + night_boundary: -10.0 + stop_tracking_observing_script_name: maintel/stop_tracking.py + feature_scheduler_driver_configuration: + observation_database_name: /home/saluser/rubin_sim_data/fbs_observation_database_maintel.sql + scheduler_config: /net/obs-env/auto_base_packages/ts_config_ocs/Scheduler/feature_scheduler/maintel/fbs_config_sit_survey_block_t345.py + telemetry: + streams: + - name: seeing + efd_table: lsst.sal.DIMM.logevent_dimmMeasurement + efd_columns: + - fwhm + efd_delta_time: 300.0 + fill_value: 1.0 + - name: wind_speed + efd_table: lsst.sal.ESS.airFlow + efd_columns: + - speed + efd_delta_time: 300.0 + fill_value: 0.0 + csc_index: 301 + - name: wind_direction + efd_table: lsst.sal.ESS.airFlow + efd_columns: + - direction + efd_delta_time: 300.0 + fill_value: 0.0 + csc_index: 301