Ejemplo n.º 1
0
    def _get_ra_target_intervals(self, target, up, airmass, effective_horizon):
        star = Star(self.site['latitude'], target, effective_horizon)

        if up:
            day_interval_func = self._find_when_target_is_up
        else:
            day_interval_func = self._find_when_target_is_down

        # Find rise/set/transit for each day
        intervals = []
        current_date = self.start_date
        while current_date < self.end_date + ONE_DAY:
            one_day_intervals = day_interval_func(target, current_date, star,
                                                  airmass)

            # Add today's intervals to the accumulating list of intervals
            intervals.extend(one_day_intervals)

            # Move on to tomorrow
            current_date += ONE_DAY

        # Collapse adjacent intervals into continuous larger intervals
        intervals = coalesce_adjacent_intervals(intervals)
        intervals = intersect_intervals(intervals,
                                        [(self.start_date, self.end_date)])

        return intervals
Ejemplo n.º 2
0
    def test_coalesce_adjacent_intervals(self):
        input_intervals = list(self.some_adjacent_intervals)
        received = coalesce_adjacent_intervals(self.some_adjacent_intervals)

        assert_equal(received, self.expected_coalescence)

        # Confirm the input list was not modified in place
        assert_equal(input_intervals, self.some_adjacent_intervals)
Ejemplo n.º 3
0
    def get_ha_intervals(self, target):
        """Returns the hour angle intervals for the given target.

        Returns the hour anle intervals for the given target and given site and date range set in this visibility object.
        The hour angle intervals are uninterupted chunks of time that the target is within the hour angle limits of the
        telescope.

        Args:
            target (dict): A dictionary of target details in the rise-set library format
        Returns:
            list: A list of tuples of start/end datetime pairs that make up the intervals over which this target is within HA limits.
        """
        SIDEREAL_SOLAR_DAY_RATIO = 1.002737909350
        SIDEREAL_SOLAR_DAY = datetime.timedelta(
            seconds=(ONE_DAY.total_seconds() / SIDEREAL_SOLAR_DAY_RATIO))

        earliest_date = self.start_date - SIDEREAL_SOLAR_DAY

        tdb = date_to_tdb(earliest_date)
        mjd = gregorian_to_ut_mjd(earliest_date)
        gmst = ut_mjd_to_gmst(mjd)

        # Need the apparent ra/dec for getting correct ha limits on high dec targets
        apparent_ra, apparent_dec = mean_to_apparent(target, tdb)

        # Flip the neg/pos ha limits if site is in the southern hemisphere
        ha_neg = self.ha_limit_neg
        ha_pos = self.ha_limit_pos
        if self.site['latitude'].in_degrees() < 0:
            ha_neg = -self.ha_limit_pos
            ha_pos = -self.ha_limit_neg

        # the rise time
        hour_rise = ha_neg + apparent_ra.in_hours() - \
            self.site['longitude'].in_hours() - gmst.in_hours()
        hour_rise /= SIDEREAL_SOLAR_DAY_RATIO

        # the set time
        hour_set  = ha_pos + apparent_ra.in_hours() - \
            self.site['longitude'].in_hours() - gmst.in_hours()
        hour_set /= SIDEREAL_SOLAR_DAY_RATIO

        current_rise = earliest_date + datetime.timedelta(hours=hour_rise)
        current_set = earliest_date + datetime.timedelta(hours=hour_set)

        # Find hour angle limits for each day
        intervals = []
        while current_set < (self.end_date + SIDEREAL_SOLAR_DAY):
            intervals.append((current_rise, current_set))
            current_rise += SIDEREAL_SOLAR_DAY
            current_set += SIDEREAL_SOLAR_DAY

        # do not exceed start/end dates
        intervals = coalesce_adjacent_intervals(intervals)
        intervals = intersect_intervals(intervals,
                                        [(self.start_date, self.end_date)])

        return intervals
Ejemplo n.º 4
0
def find_moving_object_network_up_intervals(window, elements, site_filename, chunksize):
    '''Network wide wrapper for find_moving_object_up_intervals.'''

    sites = initialise_sites(site_filename)
    up_intervals_at = {}
    for site in sites:
        up_intervals, altitudes = find_moving_object_up_intervals(window, elements, site,
                                                                  chunksize)
        coalesced_intervals = coalesce_adjacent_intervals(up_intervals)
        up_intervals_at[site['name']] = coalesced_intervals

    return up_intervals_at
Ejemplo n.º 5
0
    def _get_chunked_intervals(self,
                               target,
                               target_intervals,
                               compare_func,
                               constraint,
                               chunksize=datetime.timedelta(minutes=30)):
        '''Returns a set of datetime 2-tuples, each of which represents an interval
           of time that the target is greater than the constraint away from the thing-to-be-avoided.
           The supplied compare_func calculates the distance to it's specific obstacle (moon, zenith).
        '''
        intervals = []

        for start, end in target_intervals:
            chunkstart = start
            chunkend = min(chunkstart + chunksize, end)
            while chunkstart != chunkend and chunkend <= end:
                # get the tdb date of the start time of the interval
                tdb = date_to_tdb(chunkstart)
                # get the apparent ra/dec for the target, and for the moon at this timestamp
                if is_sidereal_target(target):
                    target_app_ra, target_app_dec = mean_to_apparent(
                        target, tdb)
                else:
                    target_app_ra, target_app_dec = elem_to_topocentric_apparent(
                        chunkstart, target, self.site, target_to_jform(target))

                if compare_func({
                        'time': chunkstart,
                        'tdb': tdb
                }, target_app_ra, target_app_dec, constraint):
                    intervals.append((chunkstart, chunkend))

                # increment the chunkstart/end up
                chunkstart = chunkend
                chunkend = min(chunkstart + chunksize, end)

        intervals = coalesce_adjacent_intervals(intervals)
        return intervals
Ejemplo n.º 6
0
def get_rise_set_intervals(request_dict, site=''):
    intervals = []
    site = site if site else request_dict['location'].get('site', '')
    site_details = configdb.get_sites_with_instrument_type_and_location(
            request_dict['molecules'][0]['instrument_name'],
            site,
            request_dict['location'].get('observatory', ''),
            request_dict['location'].get('telescope', '')
    )
    if not site_details:
        return intervals
    intervals_by_site = {}
    if request_dict.get('id'):
        cache_key = '{0}.rsi'.format(request_dict['id'])
        intervals_by_site = cache.get(cache_key, {})
    for site in site_details:
        if intervals_by_site.get(site):
            intervals.extend(intervals_by_site[site])
        else:
            intervals_by_site[site] = []
            rise_set_site = get_rise_set_site(site_details[site])
            rise_set_target = get_rise_set_target(request_dict['target'])
            for window in request_dict['windows']:
                visibility = get_rise_set_visibility(rise_set_site, window['start'], window['end'], site_details[site])

                intervals_by_site[site].extend(
                    visibility.get_observable_intervals(
                        rise_set_target,
                        airmass=request_dict['constraints']['max_airmass'],
                        moon_distance=Angle(degrees=request_dict['constraints']['min_lunar_distance'])
                    )
                )
            intervals.extend(intervals_by_site[site])
    if request_dict.get('id'):
        cache.set(cache_key, intervals_by_site, 86400 * 30)  # cache for 30 days

    return coalesce_adjacent_intervals(intervals)