def setup(self): self.start = datetime(2011, 11, 1, 0, 0, 0) self.end = datetime(2011, 11, 3, 0, 0, 0) self.tels = { '1m0a.doma.bpl': dict(name='1m0a.doma.bpl', tel_class='1m0', latitude=34.433157, longitude=-119.86308, horizon=25, ha_limit_neg=-12.0, ha_limit_pos=12.0, zenith_blind_spot=0.0) } self.target = ICRSTarget( # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=310.35795833333333, dec=45.280338888888885) self.prop_mot_target = ICRSTarget( # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=316.73026646, dec=38.74205644, proper_motion_ra=4106.90, proper_motion_dec=3144.68) self.instrument_config = dict(exposure_count=1, bin_x=2, bin_y=2, exposure_time=30, optical_elements={'filter': 'B'}) self.guiding_config = dict(mode='ON', optional=True, optical_elements={}, exposure_time=10) self.acquisition_config = dict(mode='OFF') self.constraints = {'max_airmass': None, 'min_lunar_distance': 0} self.configuration = Configuration( dict(id=5, target=self.target, instrument_type='1M0-SCICAM-SINISTRO', type='expose', instrument_configs=[self.instrument_config], guiding_config=self.guiding_config, acquisition_config=self.acquisition_config, constraints=self.constraints))
def setup(self): self.target = ICRSTarget( name='deneb', # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=310.35795833333333, dec=45.280338888888885, epoch=2000, ) self.telescope = dict( name='maui', latitude=20.7069444444, longitude=-156.258055556, ) self.proposal = Proposal( proposal_name='LCOSchedulerTest', user='******', tag='admin', time_remaining=10, # In hours priority=1) self.instrument_config = dict( exposure_count=1, bin_x=2, bin_y=2, exposure_time=20, extra_params={}, optical_elements={'filter': 'BSSL-UX-020'}) self.guiding_config = dict(mode='ON', optional=True, optical_elements={}, extra_params={}, exposure_time=10) self.acquisition_config = dict(mode='OFF', extra_params={}) self.constraints = {'max_airmass': None, 'min_lunar_distance': 0} self.configuration = Configuration( dict(id=5, target=self.target, type='expose', instrument_type='1M0-SCICAM-SBIG', priority=1, instrument_configs=[self.instrument_config], acquisition_config=self.acquisition_config, guiding_config=self.guiding_config, extra_params={}, constraints=self.constraints)) self.semester_start = datetime(2011, 11, 1, 0, 0, 0) self.semester_end = datetime(2011, 11, 8, 0, 0, 0) self.windows = [(self.semester_start, self.semester_end)] self.duration = 60 self.id = 1
def test_build_rr_observation(self): reservation = Reservation(priority=None, duration=10, possible_windows_dict={}) reservation.scheduled_start = 0 reservation.scheduled_resource = '1m0a.doma.bpl' proposal = Proposal({ 'id': 'testPro', 'tag': 'tagPro', 'tac_priority': 39, 'pi': 'me' }) target = ICRSTarget({'name': 'test', 'ra': 23.3, 'dec': 22.2}) request_group = RequestGroup(operator='single', requests=None, proposal=proposal, expires=None, rg_id=333333, is_staff=False, name=None, ipp_value=1.0, observation_type="RAPID_RESPONSE", submitter='') configuration = Mock() configuration.guiding_config = {'mode': 'ON', 'optional': True} configuration.type = 'EXPOSE' configuration.instrument_type = '1M0-FAKE-SCICAM' configuration.constraints = {} configuration.id = 13 configuration.target = target request = Request( configurations=[configuration], windows=None, request_id=22223, ) reservation.request = request reservation.request_group = request_group configdb_interface = Mock() configdb_interface.get_specific_instrument.return_value = 'xx03' configdb_interface.get_autoguider_for_instrument.return_value = 'xx04' received = build_observation(reservation, self.start, configdb_interface) assert_equal(received['request'], 22223) assert_equal(received['site'], 'bpl') assert_equal(received['enclosure'], 'doma') assert_equal(received['telescope'], '1m0a') assert_equal(received['configuration_statuses'][0]['configuration'], 13) assert_equal(received['configuration_statuses'][0]['instrument_name'], 'xx03') assert_equal( received['configuration_statuses'][0]['guide_camera_name'], 'xx04')
def setup(self): # Metadata missing proposal and tag parameters self.proposal = Proposal(pi='Eric Saunders') self.configdb_interface = ConfigDBInterface( configdb_url='', telescope_classes=[], telescopes_file='test/telescopes.json', active_instruments_file='test/active_instruments.json') self.valid_proposal = Proposal( pi='Eric Saunders', id='Scheduler Testing', tag='admin', tac_priority=2, ) self.valid_target = ICRSTarget( name='deneb', type='ICRS', # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=310.35795833333333, dec=45.280338888888885, rot_mode='SKY', rot_angle=0.0, acquire_mode='OPTIONAL', ) self.valid_expose_mol = dict( type='expose', exposure_count=1, bin_x=2, bin_y=2, instrument_name='1m0-SciCam-SINISTRO', filter='B', exposure_time=30, priority=1, ag_mode='Optional', defocus=0.0, )
def test_visibility_intervals_at_low_horizon_are_allowed_by_hour_angle( self): window_dict = { 'start': datetime(2013, 3, 22, 0, 0, 0), 'end': datetime(2013, 3, 23, 0, 0, 0), } tel_name = '1m0a.doma.coj' tel = dict(name=tel_name, tel_class='1m0', latitude=-31.273, longitude=149.070593, horizon=15, ha_limit_neg=-4.6, ha_limit_pos=4.6, zenith_blind_spot=0.0) tels = { tel_name: tel, } target = ICRSTarget( # RA 15:41:25.91 ra=235.357958333, dec=-60.0, ) window = Window(window_dict, tel['name']) dt_windows = Windows() dt_windows.append(window) configuration = copy.deepcopy(self.configuration) configuration.target = target req = Request( configurations=[configuration], windows=dt_windows, request_id='1', duration=10, ) sem_start = datetime(2013, 3, 1, 0, 0, 0) sem_end = datetime(2013, 3, 31, 0, 0, 0) visibilities = construct_visibilities(tels, sem_start, sem_end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) # Hour angle not violated independently confirmed by hand-cranking through SLALIB expected_tps = [ { 'type': 'start', 'time': datetime(2013, 3, 22, 13, 9, 28, 988253) }, { 'type': 'end', 'time': datetime(2013, 3, 22, 19, 16, 27, 292072) }, ] for received_tp, expected_tp in zip(received[tel_name].toDictList(), expected_tps): assert_equal(received_tp['type'], expected_tp['type']) assert_equal(received_tp['time'], expected_tp['time'])
class TestKernelMappings(object): def setup(self): self.start = datetime(2011, 11, 1, 0, 0, 0) self.end = datetime(2011, 11, 3, 0, 0, 0) self.tels = { '1m0a.doma.bpl': dict(name='1m0a.doma.bpl', tel_class='1m0', latitude=34.433157, longitude=-119.86308, horizon=25, ha_limit_neg=-12.0, ha_limit_pos=12.0, zenith_blind_spot=0.0) } self.target = ICRSTarget( # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=310.35795833333333, dec=45.280338888888885) self.prop_mot_target = ICRSTarget( # ra = '20 41 25.91', # dec = '+45 16 49.22', ra=316.73026646, dec=38.74205644, proper_motion_ra=4106.90, proper_motion_dec=3144.68) self.instrument_config = dict(exposure_count=1, bin_x=2, bin_y=2, exposure_time=30, optical_elements={'filter': 'B'}) self.guiding_config = dict(mode='ON', optional=True, optical_elements={}, exposure_time=10) self.acquisition_config = dict(mode='OFF') self.constraints = {'max_airmass': None, 'min_lunar_distance': 0} self.configuration = Configuration( dict(id=5, target=self.target, instrument_type='1M0-SCICAM-SINISTRO', type='expose', instrument_configs=[self.instrument_config], guiding_config=self.guiding_config, acquisition_config=self.acquisition_config, constraints=self.constraints)) def make_constrained_request(self, airmass=None, start=datetime(2011, 11, 1, 6, 0, 0), end=datetime(2011, 11, 2, 6, 0, 0)): # A one day user supplied window window_dict = {'start': start, 'end': end} resource_name = '1m0a.doma.bpl' resource = self.tels[resource_name] window = Window(window_dict, resource['name']) dt_windows = Windows() dt_windows.append(window) configuration = copy.deepcopy(self.configuration) configuration.constraints['max_airmass'] = airmass req = Request(configurations=[configuration], windows=dt_windows, request_id=1, duration=10) return req def make_request_group(self, requests, operator='single'): proposal = Proposal({ 'id': 'TestProposal', 'tag': 'Test Proposal', 'pi': '', 'tac_priority': 10 }) rg = RequestGroup(operator=operator, requests=requests, proposal=proposal, submitter='', expires=datetime(2999, 1, 1), rg_id=1, is_staff=False, name='test group id', ipp_value=1.0, observation_type='NORMAL') return rg def make_intersection_dict(self): timepoints = [ { 'time': datetime(2011, 11, 1, 6, 0, 0), 'type': 'start' }, { 'time': datetime(2011, 11, 1, 7, 0, 0), 'type': 'end' }, ] intervals = Intervals(timepoints) intersection_dict = {'1m0a.doma.coj': intervals} return intersection_dict def make_dt_intervals_list(self): dt_intervals_list = [ self.make_intersection_dict(), self.make_intersection_dict(), ] return dt_intervals_list def make_rise_set_intervals(self, req, visibilities): intervals_for_resource = {} for configuration in req.configurations: rs_target = configuration.target.in_rise_set_format() max_airmass = configuration.constraints['max_airmass'] min_lunar_distance = configuration.constraints[ 'min_lunar_distance'] for resource, visibility in visibilities.items(): intervals = get_rise_set_timepoint_intervals( rs_target, visibility, max_airmass, min_lunar_distance) if resource in intervals_for_resource: intervals_for_resource[resource] = intervals_for_resource[ resource].intersect(intervals) else: intervals_for_resource[resource] = intervals return intervals_for_resource def test_make_cache_key(self): max_airmass = 2.5 min_lunar_distance = 30.0 resource = '1m0a.doma.lsc' rs_target = self.make_constrained_request( ).configurations[0].target.in_rise_set_format() assert_equal( make_cache_key(resource, rs_target, max_airmass, min_lunar_distance), '{}_{}_{}_{}'.format(resource, max_airmass, min_lunar_distance, repr(sorted(rs_target.items())))) def test_compute_request_availability_half_downtime(self): request = self.make_constrained_request() resource = '1m0a.doma.bpl' visibilities = construct_visibilities(self.tels, self.start, self.end) downtime_intervals = { resource: { 'all': [ (datetime(2011, 11, 1, 5), datetime(2011, 11, 1, 8)), ] } } intervals_for_resource = self.make_rise_set_intervals( request, visibilities) compute_request_availability(request, intervals_for_resource, {}) base_windows = request.windows.windows_for_resource.copy() compute_request_availability(request, intervals_for_resource, downtime_intervals) assert_equal(len(base_windows[resource]), 2) assert_equal(request.windows.size(), 1) assert_equal( request.windows.at(resource)[0], base_windows[resource][1]) def test_compute_request_availability_full_downtime(self): request = self.make_constrained_request() resource = '1m0a.doma.bpl' visibilities = construct_visibilities(self.tels, self.start, self.end) downtime_intervals = { resource: { 'all': [ (datetime(2011, 11, 1), datetime(2011, 11, 3)), ] } } intervals_for_resource = self.make_rise_set_intervals( request, visibilities) compute_request_availability(request, intervals_for_resource, {}) base_windows = request.windows.windows_for_resource.copy() compute_request_availability(request, intervals_for_resource, downtime_intervals) assert_equal(len(base_windows[resource]), 2) assert_equal(request.windows.size(), 0) def test_compute_request_availability_half_downtime_instrument_type(self): request = self.make_constrained_request() resource = '1m0a.doma.bpl' instrument_type = request.configurations[0].instrument_type visibilities = construct_visibilities(self.tels, self.start, self.end) downtime_intervals = { resource: { instrument_type: [ (datetime(2011, 11, 1, 5), datetime(2011, 11, 1, 8)), ] } } intervals_for_resource = self.make_rise_set_intervals( request, visibilities) compute_request_availability(request, intervals_for_resource, {}) base_windows = request.windows.windows_for_resource.copy() compute_request_availability(request, intervals_for_resource, downtime_intervals) assert_equal(len(base_windows[resource]), 2) assert_equal(request.windows.size(), 1) assert_equal( request.windows.at(resource)[0], base_windows[resource][1]) def test_compute_request_availability_combined_full_downtime(self): request = self.make_constrained_request() resource = '1m0a.doma.bpl' instrument_type = request.configurations[0].instrument_type visibilities = construct_visibilities(self.tels, self.start, self.end) downtime_intervals = { resource: { 'all': [ (datetime(2011, 11, 1, 5), datetime(2011, 11, 1, 8)), ], instrument_type: [ (datetime(2011, 11, 1, 8), datetime(2011, 11, 3)), ] } } intervals_for_resource = self.make_rise_set_intervals( request, visibilities) compute_request_availability(request, intervals_for_resource, {}) base_windows = request.windows.windows_for_resource.copy() compute_request_availability(request, intervals_for_resource, downtime_intervals) assert_equal(len(base_windows[resource]), 2) assert_equal(request.windows.size(), 0) def test_compute_request_availability_different_instrument_downtime(self): request = self.make_constrained_request() resource = '1m0a.doma.bpl' visibilities = construct_visibilities(self.tels, self.start, self.end) downtime_intervals = { resource: { 'not_my_inst': [ (datetime(2011, 11, 1), datetime(2011, 11, 3)), ] } } intervals_for_resource = self.make_rise_set_intervals( request, visibilities) compute_request_availability(request, intervals_for_resource, {}) base_windows = request.windows.windows_for_resource.copy() compute_request_availability(request, intervals_for_resource, downtime_intervals) assert_equal(len(base_windows[resource]), 2) assert_equal(request.windows.size(), 2) def test_construct_compound_reservation(self): request = self.make_constrained_request() requests = [request, request] operator = 'and' request_group = self.make_request_group(requests, operator) sem_start = self.start # TODO: Replace with cleaner mock patching request_group.proposal.tac_priority = 1 received = construct_compound_reservation(request_group, sem_start) assert_equal(len(received.reservation_list), len(requests)) assert_equal(received.type, operator) def test_construct_many_compound_reservation(self): request = self.make_constrained_request() requests = [request, request] operator = 'many' request_group = self.make_request_group(requests, operator) sem_start = self.start # TODO: Replace with cleaner mock patching request_group.proposal.tac_priority = 1 received = construct_many_compound_reservation(request_group, 0, sem_start) assert_equal(len(received.reservation_list), 1) assert_equal(received.type, 'single') def test_filter_on_scheduling_horizon_applies_horizon_to_singles(self): start = datetime(2011, 11, 1, 6, 0, 0) end = datetime(2011, 12, 1, 6, 0, 0) request = self.make_constrained_request(start=start, end=end) operator = 'single' requests = [request] request_group = self.make_request_group(requests, operator) request_groups = [request_group] scheduling_horizon = datetime(2011, 11, 15, 6, 0, 0) filtered_rgs = filter_on_scheduling_horizon(request_groups, scheduling_horizon) expected_window_start = start expected_window_end = scheduling_horizon assert_equal(1, len(filtered_rgs)) output_ur = filtered_rgs[0] assert_equal(1, len(output_ur.requests)) bpl_1m0a_doma_windows = output_ur.requests[0].windows.at( '1m0a.doma.bpl') assert_equal(1, len(bpl_1m0a_doma_windows)) assert_equal(bpl_1m0a_doma_windows[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows[0].end, expected_window_end) def test_filter_on_scheduling_horizon_applies_horizon_to_manys(self): start = datetime(2011, 11, 1, 6, 0, 0) end = datetime(2011, 12, 1, 6, 0, 0) request1 = self.make_constrained_request(start=start, end=end) request2 = self.make_constrained_request(start=start, end=end) operator = 'many' requests = [request1, request2] request_group = self.make_request_group(requests, operator) request_groups = [request_group] scheduling_horizon = datetime(2011, 11, 15, 6, 0, 0) filtered_rgs = filter_on_scheduling_horizon(request_groups, scheduling_horizon) expected_window_start = start expected_window_end = scheduling_horizon assert_equal(1, len(filtered_rgs)) output_ur = filtered_rgs[0] assert_equal(2, len(output_ur.requests)) bpl_1m0a_doma_windows1 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') bpl_1m0a_doma_windows2 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') assert_equal(1, len(bpl_1m0a_doma_windows1)) assert_equal(1, len(bpl_1m0a_doma_windows2)) assert_equal(bpl_1m0a_doma_windows1[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows1[0].end, expected_window_end) assert_equal(bpl_1m0a_doma_windows2[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows2[0].end, expected_window_end) def test_filter_on_scheduling_horizon_no_horizon_applied_to_oneof(self): start = datetime(2011, 11, 1, 6, 0, 0) end = datetime(2011, 12, 1, 6, 0, 0) request1 = self.make_constrained_request(start=start, end=end) request2 = self.make_constrained_request(start=start, end=end) operator = 'oneof' requests = [request1, request2] request_group = self.make_request_group(requests, operator) request_groups = [request_group] scheduling_horizon = datetime(2011, 11, 15, 6, 0, 0) filtered_rgs = filter_on_scheduling_horizon(request_groups, scheduling_horizon) expected_window_start = start expected_window_end = end assert_equal(1, len(filtered_rgs)) output_ur = filtered_rgs[0] assert_equal(2, len(output_ur.requests)) bpl_1m0a_doma_windows1 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') bpl_1m0a_doma_windows2 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') assert_equal(1, len(bpl_1m0a_doma_windows1)) assert_equal(1, len(bpl_1m0a_doma_windows2)) assert_equal(bpl_1m0a_doma_windows1[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows1[0].end, expected_window_end) assert_equal(bpl_1m0a_doma_windows2[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows2[0].end, expected_window_end) def test_filter_on_scheduling_horizon_no_horizon_applied_to_and(self): start = datetime(2011, 11, 1, 6, 0, 0) end = datetime(2011, 12, 1, 6, 0, 0) request1 = self.make_constrained_request(start=start, end=end) request2 = self.make_constrained_request(start=start, end=end) operator = 'and' requests = [request1, request2] request_group = self.make_request_group(requests, operator) request_groups = [request_group] scheduling_horizon = datetime(2011, 11, 15, 6, 0, 0) filtered_rgs = filter_on_scheduling_horizon(request_groups, scheduling_horizon) expected_window_start = start expected_window_end = end assert_equal(1, len(filtered_rgs)) output_ur = filtered_rgs[0] assert_equal(2, len(output_ur.requests)) bpl_1m0a_doma_windows1 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') bpl_1m0a_doma_windows2 = output_ur.requests[0].windows.at( '1m0a.doma.bpl') assert_equal(1, len(bpl_1m0a_doma_windows1)) assert_equal(1, len(bpl_1m0a_doma_windows2)) assert_equal(bpl_1m0a_doma_windows1[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows1[0].end, expected_window_end) assert_equal(bpl_1m0a_doma_windows2[0].start, expected_window_start) assert_equal(bpl_1m0a_doma_windows2[0].end, expected_window_end) def test_make_target_intervals(self): window_dict = {'start': self.start, 'end': self.end} resource_name = '1m0a.doma.bpl' resource = self.tels[resource_name] window = Window(window_dict, resource['name']) dt_windows = Windows() dt_windows.append(window) req = Request(configurations=[self.configuration], windows=dt_windows, request_id='1') visibilities = construct_visibilities(self.tels, self.start, self.end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) date_format = '%Y-%m-%d %H:%M:%S.%f' rise_set_dark_intervals = (datetime.strptime( '2011-11-01 02:02:43.257196', date_format), datetime.strptime( '2011-11-01 07:52:00.564199', date_format), datetime.strptime( '2011-11-02 02:01:50.423880', date_format), datetime.strptime( '2011-11-02 07:48:04.692316', date_format)) # Verify we get the intervals we expect for resource_name, received_intervals in received.items(): for i, received_tp in enumerate(received_intervals.toDictList()): assert_equal(received_tp['time'], rise_set_dark_intervals[i]) def test_proper_motion_in_rise_set(self): target_dict = self.prop_mot_target.in_rise_set_format() # According to Rob's calculations, proper motion RA and dec should be as follows # See https://issues.lcogt.net/issues/8723 for more info converted_proper_motion_ra = 5.265450459478893 converted_proper_motion_dec = 3.14468 assert_almost_equals( target_dict['ra_proper_motion'].in_degrees_per_year(), converted_proper_motion_ra / 3600.0) assert_almost_equals( target_dict['dec_proper_motion'].in_degrees_per_year(), converted_proper_motion_dec / 3600.0) def test_user_interval_is_honoured(self): # A one day user supplied window window_dict = { 'start': datetime(2011, 11, 1, 6, 0, 0), 'end': datetime(2011, 11, 2, 6, 0, 0) } resource_name = '1m0a.doma.bpl' resource = self.tels[resource_name] window = Window(window_dict, resource['name']) dt_windows = Windows() dt_windows.append(window) req = Request(configurations=[self.configuration], windows=dt_windows, request_id='1') visibilities = construct_visibilities(self.tels, self.start, self.end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) # The user windows constrain the available observing windows (compare to # previous test) date_format = '%Y-%m-%d %H:%M:%S.%f' rise_set_dark_intervals = ( datetime.strptime('2011-11-01 06:00:00.0', date_format), datetime.strptime('2011-11-01 07:52:00.564199', date_format), datetime.strptime('2011-11-02 02:01:50.423880', date_format), datetime.strptime('2011-11-02 06:00:00.0', date_format), ) # Verify we get the intervals we expect for resource_name, received_intervals in received.items(): for i, received_tp in enumerate(received_intervals.toDictList()): assert_equal(received_tp['time'], rise_set_dark_intervals[i]) def test_multiple_user_intervals_are_honoured(self): # A one day user supplied window windows = [{ 'start': datetime(2011, 11, 1, 6, 0, 0), 'end': datetime(2011, 11, 1, 9, 0, 0) }, { 'start': datetime(2011, 11, 2, 1, 0, 0), 'end': datetime(2011, 11, 2, 4, 0, 0) }] dt_windows = Windows() resource_name = '1m0a.doma.bpl' for w in windows: dt_windows.append(Window(w, self.tels[resource_name]['name'])) req = Request(configurations=[self.configuration], windows=dt_windows, request_id='1') visibilities = construct_visibilities(self.tels, self.start, self.end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) # The user windows constrain the available observing windows (compare to # previous tests) date_format = '%Y-%m-%d %H:%M:%S.%f' rise_set_dark_intervals = ( datetime.strptime('2011-11-01 06:00:00.0', date_format), datetime.strptime('2011-11-01 07:52:00.564199', date_format), datetime.strptime('2011-11-02 02:01:50.423880', date_format), datetime.strptime('2011-11-02 04:00:00.0', date_format), ) # Verify we get the intervals we expect for resource_name, received_intervals in received.items(): for i, received_tp in enumerate(received_intervals.toDictList()): assert_equal(received_tp['time'], rise_set_dark_intervals[i]) def test_visibility_intervals_are_limited_by_hour_angle(self): window_dict = { 'start': datetime(2013, 3, 22, 0, 0, 0), 'end': datetime(2013, 3, 23, 0, 0, 0), } tel_name = '1m0a.doma.coj' tel = dict(name=tel_name, tel_class='1m0', latitude=-31.273, longitude=149.070593, horizon=15, ha_limit_neg=-4.6, ha_limit_pos=4.6, zenith_blind_spot=0.0) tels = { tel_name: tel, } target = ICRSTarget( ra=310.35795833333333, dec=-60.0, ) window = Window(window_dict, tel['name']) dt_windows = Windows() dt_windows.append(window) configuration = copy.deepcopy(self.configuration) configuration.target = target req = Request( configurations=[configuration], windows=dt_windows, request_id='1', duration=10, ) sem_start = datetime(2013, 3, 1, 0, 0, 0) sem_end = datetime(2013, 3, 31, 0, 0, 0) visibilities = construct_visibilities(tels, sem_start, sem_end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) # Hour angle not violated independently confirmed by hand-cranking through SLALIB expected_tps = [ { 'type': 'start', 'time': datetime(2013, 3, 22, 18, 8, 34, 287629) }, { 'type': 'end', 'time': datetime(2013, 3, 22, 19, 16, 27, 292072) }, ] for received_tp, expected_tp in zip(received[tel_name].toDictList(), expected_tps): assert_equal(received_tp['type'], expected_tp['type']) assert_equal(received_tp['time'], expected_tp['time']) def test_visibility_intervals_at_low_horizon_are_allowed_by_hour_angle( self): window_dict = { 'start': datetime(2013, 3, 22, 0, 0, 0), 'end': datetime(2013, 3, 23, 0, 0, 0), } tel_name = '1m0a.doma.coj' tel = dict(name=tel_name, tel_class='1m0', latitude=-31.273, longitude=149.070593, horizon=15, ha_limit_neg=-4.6, ha_limit_pos=4.6, zenith_blind_spot=0.0) tels = { tel_name: tel, } target = ICRSTarget( # RA 15:41:25.91 ra=235.357958333, dec=-60.0, ) window = Window(window_dict, tel['name']) dt_windows = Windows() dt_windows.append(window) configuration = copy.deepcopy(self.configuration) configuration.target = target req = Request( configurations=[configuration], windows=dt_windows, request_id='1', duration=10, ) sem_start = datetime(2013, 3, 1, 0, 0, 0) sem_end = datetime(2013, 3, 31, 0, 0, 0) visibilities = construct_visibilities(tels, sem_start, sem_end) intervals_for_resource = self.make_rise_set_intervals( req, visibilities) compute_request_availability(req, intervals_for_resource, {}) received = req_windows_to_kernel_intervals( req.windows.windows_for_resource) # Hour angle not violated independently confirmed by hand-cranking through SLALIB expected_tps = [ { 'type': 'start', 'time': datetime(2013, 3, 22, 13, 9, 28, 988253) }, { 'type': 'end', 'time': datetime(2013, 3, 22, 19, 16, 27, 292072) }, ] for received_tp, expected_tp in zip(received[tel_name].toDictList(), expected_tps): assert_equal(received_tp['type'], expected_tp['type']) assert_equal(received_tp['time'], expected_tp['time']) def test_construct_global_availability(self): tel_name = '1m0a.doma.lsc' sem_start = datetime(2012, 10, 1) # Resource is available from 3-7 dt0 = datetime(2013, 3, 22, 3) dt1 = datetime(2013, 3, 22, 7) dt_resource_int = Intervals([ { 'time': dt0, 'type': 'start' }, { 'time': dt1, 'type': 'end' }, ]) epoch_resource_int = normalise_dt_intervals(dt_resource_int, sem_start) resource_windows = {tel_name: epoch_resource_int} # Resource is unavailable from 4-5 dt2 = datetime(2013, 3, 22, 4) dt3 = datetime(2013, 3, 22, 5) masked_inervals = { '1m0a.doma.lsc': Intervals([{ 'time': dt2, 'type': 'start' }, { 'time': dt3, 'type': 'end' }]) } # Expected available intervals after masking are # 3-4, 5-7 received = construct_global_availability(masked_inervals, sem_start, resource_windows) received_int = received[tel_name] timepoints = received_int.toDictList() assert_equal(len(timepoints), 4) r0 = normalised_epoch_to_datetime(timepoints[0]['time'], datetime_to_epoch(sem_start)) r1 = normalised_epoch_to_datetime(timepoints[1]['time'], datetime_to_epoch(sem_start)) # r2 = normalised_epoch_to_datetime(timepoints[2]['time'], # datetime_to_epoch(sem_start)) r3 = normalised_epoch_to_datetime(timepoints[3]['time'], datetime_to_epoch(sem_start)) assert_equal(r0, dt0) assert_equal(r1, dt2) assert_equal(r3, dt1) def test_airmass_is_honoured_high_airmass(self): airmass = 3.0 req_airmass3 = self.make_constrained_request(airmass) req_no_airmass = self.make_constrained_request() visibilities = construct_visibilities(self.tels, self.start, self.end) intervals_for_resource = self.make_rise_set_intervals( req_no_airmass, visibilities) compute_request_availability(req_no_airmass, intervals_for_resource, {}) received_no_airmass = req_windows_to_kernel_intervals( req_no_airmass.windows.windows_for_resource) timepoints_no_airmass = received_no_airmass[ '1m0a.doma.bpl'].toDictList() intervals_for_resource = self.make_rise_set_intervals( req_airmass3, visibilities) compute_request_availability(req_airmass3, intervals_for_resource, {}) received_airmass3 = req_windows_to_kernel_intervals( req_airmass3.windows.windows_for_resource) timepoints_airmass3 = received_airmass3['1m0a.doma.bpl'].toDictList() assert_equal(timepoints_no_airmass, timepoints_airmass3) def test_airmass_is_honoured_low_airmass(self): airmass = 1.0 req_airmass1 = self.make_constrained_request(airmass) req_no_airmass = self.make_constrained_request() visibilities = construct_visibilities(self.tels, self.start, self.end) intervals_for_resource = self.make_rise_set_intervals( req_no_airmass, visibilities) compute_request_availability(req_no_airmass, intervals_for_resource, {}) received_no_airmass = req_windows_to_kernel_intervals( req_no_airmass.windows.windows_for_resource) intervals_for_resource = self.make_rise_set_intervals( req_airmass1, visibilities) compute_request_availability(req_airmass1, intervals_for_resource, {}) received_airmass1 = req_windows_to_kernel_intervals( req_airmass1.windows.windows_for_resource) assert_not_equal(received_airmass1, received_no_airmass) assert_equal(len(received_airmass1), 0)
def setup(self): self.target = ICRSTarget( name='deneb', ra=310.35795833333333, dec=45.280338888888885, epoch=2000, ) self.telescope = dict(name='1m0a.doma.ogg', latitude=20.7069444444, longitude=-156.258055556, tel_class='1m0', horizon=15, status='online', ha_limit_neg=-4.6, ha_limit_pos=4.6, zenith_blind_spot=0.0) self.telescopes = {'1m0a.doma.ogg': self.telescope} self.proposal = Proposal(id='LCOSchedulerTest', pi='Eric Saunders', tag='admin', tac_priority=1) self.instrument_config = dict(exposure_count=1, bin_x=2, bin_y=2, exposure_time=60 * 25, optical_elements={'filter': 'b'}) self.guiding_config = dict(mode='ON', optional=True, optical_elements={}, exposure_time=10) self.acquisition_config = dict(mode='OFF') self.constraints = {'max_airmass': None, 'min_lunar_distance': 0} self.configuration = Configuration( **dict(id=5, target=self.target, type='expose', instrument_type='1M0-SCICAM-SBIG', priority=1, instrument_configs=[self.instrument_config], acquisition_config=self.acquisition_config, guiding_config=self.guiding_config, constraints=self.constraints)) self.base_time = datetime(2016, 9, 14, 6, 0) resource_1 = '1m0a.doma.ogg' self.window_1 = Window( { 'start': self.base_time, 'end': self.base_time + timedelta(hours=0, minutes=30) }, resource_1) self.windows_1 = Windows() self.windows_1.append(self.window_1) resource_2 = '1m0a.doma.ogg' self.window_2 = Window( { 'start': self.base_time + timedelta(hours=0, minutes=30), 'end': self.base_time + timedelta(hours=1, minutes=0) }, resource_2) self.windows_2 = Windows() self.windows_2.append(self.window_2) self.resource_3 = '1m0a.doma.ogg' self.window_3 = Window( { 'start': self.base_time + timedelta(hours=1, minutes=0), 'end': self.base_time + timedelta(hours=1, minutes=30) }, self.resource_3) self.windows_3 = Windows() self.windows_3.append(self.window_3) self.request_1 = Request(configurations=[self.configuration], windows=self.windows_1, request_id=1, duration=1750) self.request_2 = Request(configurations=[self.configuration], windows=self.windows_2, request_id=2, duration=1750) self.request_3 = Request(configurations=[self.configuration], windows=self.windows_2, request_id=3, duration=1750) self.request_4 = Request(configurations=[self.configuration], windows=self.windows_3, request_id=4, duration=1750) self.request_5 = Request(configurations=[self.configuration], windows=self.windows_3, request_id=5, duration=1750) self.and_request_group_1 = RequestGroup( operator='and', requests=[self.request_1, self.request_2], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=1, is_staff=False, observation_type='NORMAL', ipp_value=1.0, name='ur 1', submitter='') self.and_request_group_2 = RequestGroup( operator='and', requests=[self.request_3, self.request_4], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=2, is_staff=False, observation_type='NORMAL', ipp_value=1.0, name='ur 2', submitter='') self.many_request_group_1 = RequestGroup( operator='many', requests=[self.request_1, self.request_2], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=3, is_staff=False, observation_type='NORMAL', ipp_value=1.5, name='ur 3', submitter='') self.many_request_group_2 = RequestGroup( operator='many', requests=[self.request_3, self.request_4], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=4, is_staff=False, observation_type='NORMAL', ipp_value=1.5, name='ur 4', submitter='') self.rr_request_group_1 = RequestGroup( operator='many', requests=[self.request_5], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=5, is_staff=False, observation_type='RAPID_RESPONSE', ipp_value=1.5, name='ur 5', submitter='') self.rr_request_group_2 = RequestGroup( operator='many', requests=[self.request_1, self.request_3], proposal=self.proposal, expires=datetime(2050, 1, 1), rg_id=6, is_staff=False, observation_type='RAPID_RESPONSE', ipp_value=1.5, name='ur 6', submitter='')