def test_rise_set_2_15(self): dt_utc = datetime(2012, 2, 15) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons expected_set = timedelta(hours=13, minutes=35) # moon doesnt rise on this day, but rise_set returns the rise time for the next day expected_transit = timedelta(hours=6, minutes=26) assert_less(abs(sets.total_seconds() - expected_set.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def test_rise_set_11_1(self): dt_utc = datetime(2012, 11, 1) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons expected_set = timedelta(hours=6, minutes=43) expected_rise = timedelta(hours=20, minutes=52) expected_transit = timedelta(hours=1, minutes=22) assert_less(abs(sets.total_seconds() - expected_set.total_seconds()), self.time_tolerance) assert_less(abs(rises.total_seconds() - expected_rise.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def test_rise_set_6_15(self): dt_utc = datetime(2012, 6, 15) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons expected_set = timedelta(hours=14, minutes=12) expected_rise = timedelta(hours=3, minutes=13) expected_transit = timedelta(hours=8, minutes=42) assert_less(abs(sets.total_seconds() - expected_set.total_seconds()), self.time_tolerance) assert_less(abs(rises.total_seconds() - expected_rise.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def test_rise_set_1_2(self): dt_utc = datetime(2012, 1, 2) # parallax and semidiameter from astronomers almanac horizontal_parallax = Angle(degrees=0.9043333) semidiameter = Angle(degrees=0.2463306) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons # There is no expected set time for the january 2nd, 2012 - it spans the date boundary expected_rise = timedelta(hours=13, minutes=16) expected_transit = timedelta(hours=18, minutes=52) assert_less(abs(rises.total_seconds() - expected_rise.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def test_rise_set_2_3(self): dt_utc = datetime(2012, 2, 3) horizontal_parallax = Angle(degrees=0.9190528) semidiameter = Angle(degrees=0.2503389) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons expected_set = timedelta(hours=1, minutes=11) expected_rise = timedelta(hours=15, minutes=31) expected_transit = timedelta(hours=20, minutes=47) assert_less(abs(sets.total_seconds() - expected_set.total_seconds()), self.time_tolerance) assert_less(abs(rises.total_seconds() - expected_rise.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def test_rise_set_2_1(self): dt_utc = datetime(2012, 2, 1) horizontal_parallax = Angle(degrees=0.9062222) semidiameter = Angle(degrees=0.2468444) (transits, rises, sets) = calc_planet_rise_set(self.site, dt_utc, self.h_0, 'moon') # values from JPL Horizons expected_set = timedelta(minutes=23) expected_rise = timedelta(hours=13, minutes=47) expected_transit = timedelta(hours=19, minutes=5) assert_less(abs(sets.total_seconds() - expected_set.total_seconds()), self.time_tolerance) assert_less(abs(rises.total_seconds() - expected_rise.total_seconds()), self.time_tolerance) assert_less( abs(transits.total_seconds() - expected_transit.total_seconds()), self.time_tolerance)
def _find_when_target_is_up(self, target, dt, star=None, airmass=None): '''Returns a single datetime 2-tuple, representing an interval of uninterrupted time above the horizon at the specified site, for the requested date. Note: Even though this function currently ignores times, the dt object must be a datetime, *not* a date. TODO: Clean up this unpleasant interface - no star need be passed if the sun is the target, but one *must* be passed otherwise. This isn't obvious from the method signature. ''' effective_horizon = set_airmass_limit(airmass, self.horizon.in_degrees()) # Remove any time component of the provided datetime object dt = dt.replace(hour=0, minute=0, second=0, microsecond=0) # Get the rise/set/transit times for the target, for this day intervals = [] # TODO: Catch the RiseSetError for circumpolar stars # TODO: Return either a complete or empty interval, as appropriate # TODO: This requires either introspecting state in the error, or # TODO: calling an is_circumpolar method before this calculation if target == 'sun': transits, rises, sets = calc_sunrise_set(self.site, dt, self.twilight) elif target == 'moon': transits, rises, sets = calc_planet_rise_set( self.site, dt, MOON_REFRACTION, 'moon') else: # Test for circumpolarity if star.is_always_up(dt): # Return a full interval over the entire day intervals.append((dt, dt + ONE_DAY)) return intervals # Catch target never rising try: effective_horizon_angle = Angle(degrees=effective_horizon) transits, rises, sets = calc_rise_set(target, self.site, dt, effective_horizon_angle) except RiseSetError: return intervals _log.debug("latitude: %s", self.site['latitude'].in_degrees()) _log.debug("longitude: %s", self.site['longitude'].in_degrees()) _log.debug("twilight: %s", self.twilight) _log.debug("dt: %s", dt) _log.debug("rise: %s (%s)", rises, dt + rises) _log.debug("transit: %s (%s)", transits, dt + transits) _log.debug("set: %s (%s)", sets, dt + sets) # import ipdb; ipdb.set_trace() # Case 1: Overlapping start of day boundary # Target rose yesterday, and sets today. Rises again later today. # | x | # | x x | # | x x | x # x| x x| # x | x x | # Rise 0hr Transit Set Rise 24hr if (rises > transits) and (sets > transits): # Store the first interval - start of day until target set absolute_set = sets + dt intervals.append((dt, absolute_set)) # Store the second interval - target rise until end of day absolute_rise = rises + dt intervals.append((absolute_rise, dt + ONE_DAY)) # Case 2: Rise, set and transit all fall within the day, in order # Target rises today, transits, and sets before the day ends # | x | # | x x | # | x x | # | x x | # | x x | # | x x | # 0hr Rise Transit Set 24hr elif (rises < transits) and (sets > transits): # Only one interval - rise until target set absolute_rise = rises + dt absolute_set = sets + dt intervals.append((absolute_rise, absolute_set)) # Case 3: Overlapping end of day boundary # Target rose yesterday, and sets today. Rises again later today. # x | x | # x x | x x | # x |x x |x # x | x x | x # x | x x | # Rise Transit 0hr Set Rise Transit 24hr elif (rises < transits) and (sets < transits): # Same code as case 1! # Store the first interval - start of day until target set absolute_set = sets + dt intervals.append((dt, absolute_set)) # Store the second interval - target rise until end of day absolute_rise = rises + dt intervals.append((absolute_rise, dt + ONE_DAY)) return intervals