-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add sunrise / sunset to Location #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Probably a good idea, though it's not likely to happen as part of that PR. Are you aware of the get_sun_rise_set_transit function? It returns both sunrise and sunset. I'm less interested in All that being said, I've found that filtering using zenith or elevation angle is usually a better approach. |
I'm in need of this functionality, and am looking for opinions about implementation. I'd prefer methods attached to a Currently I'd like to avoid a workflow that calculates ephemeris twice (once to get solar position, and again to get sunrise and sunset), which is what happens with the current Thoughts? |
couple of ideas
or
Is that right? |
Sorry if I'm picking at a typo, but so we're all on the same page...
I'm not sure how avoid two different functions because it seems that they do two different things. A function to calculate sunrise/sunset should accept a date and return a collection of datetimes. A function to calculate solar position should accept a datetime and return a collection of angles. I'm having a hard time thinking outside of this box. In any case, the |
Silly me, sunset/rise is at zenith of |
Assuming it holds water, I'm curious how much more performant the above analytical solution might be. Perhaps it could be added as one of the |
i guess it seems to work, if I compare it to the online spa calculator I get nearly the correct sunrise/sunset times: from datetime import datetime, timedelta
import numpy as np
import pytz
import pandas as pd
from pvlib.solarposition import (
equation_of_time_pvcdrom, declination_spencer71)
dt = pd.DatetimeIndex(start='2018-01-01 0:00:00',
end='2018-12-31 23:59:59',
freq='H').tz_localize('Etc/GMT+7')
lat, lon = 39.743, -105.178
latrad, lonrad = np.radians(lat), np.radians(lon) # radians
eoq = equation_of_time_pvcdrom(dt.dayofyear) # minutes
decl = declination_spencer71(dt.dayofyear) # radians
def get_sunset_angle(decl, latrad):
return np.arccos(-np.tan(decl) * np.tan(latrad))
# solar noon is at hour angle zero
# so sunrise is just negative of sunset
ss_angrad = get_sunset_angle(decl, latrad) # radians
ss_ang = np.degrees(ss_angrad)
sr_angrad = -ss_angrad # radians
sr_ang = -ss_ang
def local_hours(times, hour_ang, lon, eoq):
timezone = times.tz.utcoffset(times).total_seconds() / 3600.
return (hour_ang - lon - eoq/4.)/15. + 12. + timezone
sslh = local_hours(dt, ss_ang, lon, eoq)
srlh = local_hours(dt, sr_ang, lon, eoq)
print(sslh[0], srlh[0]) # analytical hours
#16.69168401501784 7.455555262428694
print(timedelta(hours=sslh[0]) +
pytz.timezone('Etc/GMT+7').localize(datetime(2018, 1, 1, 0, 0, 0)))
#2018-01-01 16:41:30.062454-07:00
print(timedelta(hours=srlh[0]) +
pytz.timezone('Etc/GMT+7').localize(datetime(2018, 1, 1, 0, 0, 0)))
#2018-01-01 07:27:19.998945-07:00
#from NREL MIDC SPA at (39.743, -105.178)
#Date,Time,sunrise,transit,sunset
#1/1/2018,0:00:00,7.364246,12.073578,16.785242
from pvlib.spa_c_files.spa_py import spa_calc
result = spa_calc(
year=2018, month=1, day=1, hour=0, minute=0, second=0,
time_zone=-7, longitude=-105.178, latitude=39.743,
elevation=1830.14, pressure=820, temperature=11, delta_t=67)
print(result['sunset'], result['sunrise']) # SPA hours
#16.785243982117017 7.364247922706669
print(timedelta(hours=16.785242) +
pytz.timezone('Etc/GMT+7').localize(datetime(2018, 1, 1, 0, 0, 0)))
#2018-01-01 16:47:06.871200-07:00
print(timedelta(hours=7.364246) +
pytz.timezone('Etc/GMT+7').localize(datetime(2018, 1, 1, 0, 0, 0)))
#2018-01-01 07:21:51.285600-07:00 It's about 6 minute difference 😦 |
Maybe I should've tried the other declination or eoq formulas? |
Your formula matches the one in my Vignola book. Maybe the SPA version gives you apparent zenith == 90? On the rare occasions when I need sunrise/sunset times I usually have a time series of some sort I'm working with, and just interpolate the timestamp for |
You're not, and thanks.
This is important and I had missed this.
Right. Now that I look at the spa module it is clear that we won't calculate the ephemeris twice (which I had in mind when I was considering an earlier suggestion that sunrise/sunset are based on zenith, then mistakenly transposed that idea to the spa and pyephem functions).
We're in the same box. |
@adriesse I knew the analytical functions don't account for atmospheric refraction, I just didn't realize it would be so large. Visibly the largest difference in zenith to me appears at noon, but it makes sense that refraction would be larger when the angle is greatest, ie sunrise/sunset. Always learning, thanks! @cwhanse glad you can get what you need from spa |
In reference to changes in #93:
add the following functions to
:py:class:
Location``:get_sunrise
andget_sunset
and deferred from theseget_dayduration
.This helps filtering values, e.g. set night values to
np.nan
.The text was updated successfully, but these errors were encountered: