def test_sun_rise_set_transit_ephem_error(expected_rise_set_ephem, golden): with pytest.raises(ValueError): solarposition.sun_rise_set_transit_ephem(expected_rise_set_ephem.index, golden.latitude, golden.longitude, next_or_previous='other') tz_naive = pd.DatetimeIndex([datetime.datetime(2015, 1, 2, 3, 0, 0)]) with pytest.raises(ValueError): solarposition.sun_rise_set_transit_ephem(tz_naive, golden.latitude, golden.longitude, next_or_previous='next')
def test_sun_rise_set_transit_ephem_horizon(golden): times = pd.DatetimeIndex([datetime.datetime(2016, 1, 3, 0, 0, 0) ]).tz_localize('MST') # center of sun disk center = solarposition.sun_rise_set_transit_ephem(times, latitude=golden.latitude, longitude=golden.longitude) edge = solarposition.sun_rise_set_transit_ephem(times, latitude=golden.latitude, longitude=golden.longitude, horizon='-0:34') result_rounded = (edge['sunrise'] - center['sunrise']).dt.round('min') sunrise_delta = datetime.datetime(2016, 1, 3, 7, 17, 11) - \ datetime.datetime(2016, 1, 3, 7, 21, 33) expected = pd.Series(index=times, data=sunrise_delta, name='sunrise').dt.round('min') assert_series_equal(expected, result_rounded)
def get_sun_rise_set_transit(self, times, method='pyephem', **kwargs): """ Calculate sunrise, sunset and transit times. Parameters ---------- times : DatetimeIndex Must be localized to the Location method : str, default 'pyephem' 'pyephem', 'spa', or 'geometric' kwargs are passed to the relevant functions. See solarposition.sun_rise_set_transit_<method> for details. Returns ------- result : DataFrame Column names are: ``sunrise, sunset, transit``. """ if method == 'pyephem': result = solarposition.sun_rise_set_transit_ephem( times, self.latitude, self.longitude, **kwargs) elif method == 'spa': result = solarposition.sun_rise_set_transit_spa( times, self.latitude, self.longitude, **kwargs) elif method == 'geometric': sr, ss, tr = solarposition.sun_rise_set_transit_geometric( times, self.latitude, self.longitude, **kwargs) result = pd.DataFrame(index=times, data={ 'sunrise': sr, 'sunset': ss, 'transit': tr }) else: raise ValueError('{} is not a valid method. Must be ' 'one of pyephem, spa, geometric'.format(method)) return result
def is_daylight(times, lat, lon): '''Determine if the sun is above the horizon. The resulting series has a one hour leeway for both sunrise and sunset. Arguments: times (numpy.ndarray like): A series of timestamps. lat (float): The latitude. lon (float): The longitude. Returns: pandas.Series: A boolean series indexed by the times. ''' times = DatetimeIndex(times, name='time') # Compute the time of the next sunrise, sunset, and transit (solar noon). # This computation assumes an altitude of sea-level and determined positions # based on the center of the sun. It could be adjusted for greater accuracy, # but the loss of generality probably isn't worth it. # (`rst` abreviates `rise_set_transit`) rst = solarposition.sun_rise_set_transit_ephem(times, lat, lon) # Daylight is when the next sunset preceeds the next sunrise. daylight = (rst.sunset < rst.sunrise) # Give ourselves leeway to account for the hour in which sunrise/set occurs. one_hour = pd.Timedelta(1, 'h') sunrise_edge = (rst.sunrise - rst.index < one_hour) sunset_edge = (rst.sunset - rst.index < one_hour) daylight |= sunrise_edge daylight |= sunset_edge # Ensure the series has a name. daylight.name = 'daylight' return daylight
def get_sun_rise_set_transit(self, times, method='pyephem', **kwargs): """ Calculate sunrise, sunset and transit times. Parameters ---------- times : DatetimeIndex Must be localized to the Location method : str, default 'pyephem' 'pyephem', 'spa', or 'geometric' kwargs are passed to the relevant functions. See solarposition.sun_rise_set_transit_<method> for details. Returns ------- result : DataFrame Column names are: ``sunrise, sunset, transit``. """ if method == 'pyephem': result = solarposition.sun_rise_set_transit_ephem( times, self.latitude, self.longitude, **kwargs) elif method == 'spa': result = solarposition.sun_rise_set_transit_spa( times, self.latitude, self.longitude, **kwargs) elif method == 'geometric': sr, ss, tr = solarposition.sun_rise_set_transit_geometric( times, self.latitude, self.longitude, **kwargs) result = pd.DataFrame(index=times, data={'sunrise': sr, 'sunset': ss, 'transit': tr}) else: raise ValueError('{} is not a valid method. Must be ' 'one of pyephem, spa, geometric' .format(method)) return result
def test_sun_rise_set_transit_ephem(expected_rise_set_ephem, golden): # test for Golden, CO compare to USNO, using local midnight result = solarposition.sun_rise_set_transit_ephem( expected_rise_set_ephem.index, golden.latitude, golden.longitude, next_or_previous='next', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected_rise_set_ephem, result_rounded) # test next sunrise/sunset with times times = pd.DatetimeIndex([ datetime.datetime(2015, 1, 2, 3, 0, 0), datetime.datetime(2015, 1, 2, 10, 15, 0), datetime.datetime(2015, 1, 2, 15, 3, 0), datetime.datetime(2015, 1, 2, 21, 6, 7) ]).tz_localize('MST') expected = pd.DataFrame(index=times, columns=['sunrise', 'sunset'], dtype='datetime64[ns]') expected['sunrise'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'] ]) expected['sunset'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunset'] ]) expected['transit'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit'] ]) result = solarposition.sun_rise_set_transit_ephem(times, golden.latitude, golden.longitude, next_or_previous='next', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected, result_rounded) # test previous sunrise/sunset with times times = pd.DatetimeIndex([ datetime.datetime(2015, 1, 2, 3, 0, 0), datetime.datetime(2015, 1, 2, 10, 15, 0), datetime.datetime(2015, 1, 3, 3, 0, 0), datetime.datetime(2015, 1, 3, 13, 6, 7) ]).tz_localize('MST') expected = pd.DataFrame(index=times, columns=['sunrise', 'sunset'], dtype='datetime64[ns]') expected['sunrise'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'] ]) expected['sunset'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'] ]) expected['transit'] = pd.Series( index=times, data=[ expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit'] ]) result = solarposition.sun_rise_set_transit_ephem( times, golden.latitude, golden.longitude, next_or_previous='previous', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected, result_rounded) # test with different timezone times = times.tz_convert('UTC') expected = expected.tz_convert('UTC') # resuse result from previous for col, data in expected.iteritems(): expected[col] = data.dt.tz_convert('UTC') result = solarposition.sun_rise_set_transit_ephem( times, golden.latitude, golden.longitude, next_or_previous='previous', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert(times.tz) assert_frame_equal(expected, result_rounded)
def test_sun_rise_set_transit_ephem(expected_rise_set_ephem, golden): # test for Golden, CO compare to USNO, using local midnight result = solarposition.sun_rise_set_transit_ephem( expected_rise_set_ephem.index, golden.latitude, golden.longitude, next_or_previous='next', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected_rise_set_ephem, result_rounded) # test next sunrise/sunset with times times = pd.DatetimeIndex([datetime.datetime(2015, 1, 2, 3, 0, 0), datetime.datetime(2015, 1, 2, 10, 15, 0), datetime.datetime(2015, 1, 2, 15, 3, 0), datetime.datetime(2015, 1, 2, 21, 6, 7) ]).tz_localize('MST') expected = pd.DataFrame(index=times, columns=['sunrise', 'sunset'], dtype='datetime64[ns]') expected['sunrise'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise']]) expected['sunset'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunset']]) expected['transit'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit']]) result = solarposition.sun_rise_set_transit_ephem(times, golden.latitude, golden.longitude, next_or_previous='next', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected, result_rounded) # test previous sunrise/sunset with times times = pd.DatetimeIndex([datetime.datetime(2015, 1, 2, 3, 0, 0), datetime.datetime(2015, 1, 2, 10, 15, 0), datetime.datetime(2015, 1, 3, 3, 0, 0), datetime.datetime(2015, 1, 3, 13, 6, 7) ]).tz_localize('MST') expected = pd.DataFrame(index=times, columns=['sunrise', 'sunset'], dtype='datetime64[ns]') expected['sunrise'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunrise'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'sunrise']]) expected['sunset'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'sunset']]) expected['transit'] = pd.Series(index=times, data= [expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 1), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 2), 'transit'], expected_rise_set_ephem.loc[datetime.datetime(2015, 1, 3), 'transit']]) result = solarposition.sun_rise_set_transit_ephem(times, golden.latitude, golden.longitude, next_or_previous='previous', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert('MST') assert_frame_equal(expected, result_rounded) # test with different timezone times = times.tz_convert('UTC') expected = expected.tz_convert('UTC') # resuse result from previous for col, data in expected.iteritems(): expected[col] = data.dt.tz_convert('UTC') result = solarposition.sun_rise_set_transit_ephem(times, golden.latitude, golden.longitude, next_or_previous='previous', altitude=golden.altitude, pressure=0, temperature=11, horizon='-0:34') # round to nearest minute result_rounded = pd.DataFrame(index=result.index) for col, data in result.iteritems(): result_rounded[col] = data.dt.round('min').tz_convert(times.tz) assert_frame_equal(expected, result_rounded)
def time_sun_rise_set_transit_ephem(self, ndays): solarposition.sun_rise_set_transit_ephem( self.times_daily, self.lat, self.lon)