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_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_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_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 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_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_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'])