def time_sun_rise_set_transit_geometric_full_comparison(self, ndays): dayofyear = self.times_daily.dayofyear declination = solarposition.declination_spencer71(dayofyear) equation_of_time = solarposition.equation_of_time_spencer71(dayofyear) solarposition.sun_rise_set_transit_geometric( self.times_daily, self.lat, self.lon, declination, equation_of_time)
def test_sun_rise_set_transit_geometric(expected_rise_set_spa, golden_mst): """Test geometric calculations for sunrise, sunset, and transit times""" times = expected_rise_set_spa.index latitude = golden_mst.latitude longitude = golden_mst.longitude eot = solarposition.equation_of_time_spencer71(times.dayofyear) # minutes decl = solarposition.declination_spencer71(times.dayofyear) # radians sr, ss, st = solarposition.sun_rise_set_transit_geometric( times, latitude=latitude, longitude=longitude, declination=decl, equation_of_time=eot) # sunrise: 2015-01-02 07:26:39.763224487, 2015-08-02 05:04:35.688533801 # sunset: 2015-01-02 16:41:29.951096777, 2015-08-02 19:09:46.597355085 # transit: 2015-01-02 12:04:04.857160632, 2015-08-02 12:07:11.142944443 test_sunrise = solarposition._times_to_hours_after_local_midnight(sr) test_sunset = solarposition._times_to_hours_after_local_midnight(ss) test_transit = solarposition._times_to_hours_after_local_midnight(st) # convert expected SPA sunrise, sunset, transit to local datetime indices expected_sunrise = pd.DatetimeIndex(expected_rise_set_spa.sunrise.values, tz='UTC').tz_convert(golden_mst.tz) expected_sunset = pd.DatetimeIndex(expected_rise_set_spa.sunset.values, tz='UTC').tz_convert(golden_mst.tz) expected_transit = pd.DatetimeIndex(expected_rise_set_spa.transit.values, tz='UTC').tz_convert(golden_mst.tz) # convert expected times to hours since midnight as arrays of floats expected_sunrise = solarposition._times_to_hours_after_local_midnight( expected_sunrise) expected_sunset = solarposition._times_to_hours_after_local_midnight( expected_sunset) expected_transit = solarposition._times_to_hours_after_local_midnight( expected_transit) # geometric time has about 4-6 minute error compared to SPA sunset/sunrise expected_sunrise_error = np.array( [0.07910089555555544, 0.06908014805555496]) # 4.8[min], 4.2[min] expected_sunset_error = np.array( [-0.1036246955555562, -0.06983406805555603]) # -6.2[min], -4.2[min] expected_transit_error = np.array( [-0.011150788888889096, 0.0036508177777765383]) # -40[sec], 13.3[sec] assert np.allclose(test_sunrise, expected_sunrise, atol=np.abs(expected_sunrise_error).max()) assert np.allclose(test_sunset, expected_sunset, atol=np.abs(expected_sunset_error).max()) assert np.allclose(test_transit, expected_transit, atol=np.abs(expected_transit_error).max())
def test_sun_rise_set_transit_geometric(expected_rise_set_spa, golden_mst): """Test geometric calculations for sunrise, sunset, and transit times""" times = expected_rise_set_spa.index latitude = golden_mst.latitude longitude = golden_mst.longitude eot = solarposition.equation_of_time_spencer71(times.dayofyear) # minutes decl = solarposition.declination_spencer71(times.dayofyear) # radians sr, ss, st = solarposition.sun_rise_set_transit_geometric( times, latitude=latitude, longitude=longitude, declination=decl, equation_of_time=eot) # sunrise: 2015-01-02 07:26:39.763224487, 2015-08-02 05:04:35.688533801 # sunset: 2015-01-02 16:41:29.951096777, 2015-08-02 19:09:46.597355085 # transit: 2015-01-02 12:04:04.857160632, 2015-08-02 12:07:11.142944443 test_sunrise = solarposition._times_to_hours_after_local_midnight(sr) test_sunset = solarposition._times_to_hours_after_local_midnight(ss) test_transit = solarposition._times_to_hours_after_local_midnight(st) # convert expected SPA sunrise, sunset, transit to local datetime indices expected_sunrise = pd.DatetimeIndex(expected_rise_set_spa.sunrise.values, tz='UTC').tz_convert(golden_mst.tz) expected_sunset = pd.DatetimeIndex(expected_rise_set_spa.sunset.values, tz='UTC').tz_convert(golden_mst.tz) expected_transit = pd.DatetimeIndex(expected_rise_set_spa.transit.values, tz='UTC').tz_convert(golden_mst.tz) # convert expected times to hours since midnight as arrays of floats expected_sunrise = solarposition._times_to_hours_after_local_midnight( expected_sunrise) expected_sunset = solarposition._times_to_hours_after_local_midnight( expected_sunset) expected_transit = solarposition._times_to_hours_after_local_midnight( expected_transit) # geometric time has about 4-6 minute error compared to SPA sunset/sunrise expected_sunrise_error = np.array( [0.07910089555555544, 0.06908014805555496]) # 4.8[min], 4.2[min] expected_sunset_error = np.array( [-0.1036246955555562, -0.06983406805555603]) # -6.2[min], -4.2[min] expected_transit_error = np.array( [-0.011150788888889096, 0.0036508177777765383]) # -40[sec], 13.3[sec] assert np.allclose(test_sunrise, expected_sunrise, atol=np.abs(expected_sunrise_error).max()) assert np.allclose(test_sunset, expected_sunset, atol=np.abs(expected_sunset_error).max()) assert np.allclose(test_transit, expected_transit, atol=np.abs(expected_transit_error).max())
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 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