Skip to content
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

Perform dayofyear-based calculations according to UTC, not local time #2055

Open
wants to merge 55 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
6c4c32a
Add clearsky.ipynb (Remove before merge)
yhkee0404 May 19, 2024
9ce02d5
Fix clearsky.lookup_linke_turbidity to be timezone-aware
yhkee0404 May 19, 2024
0ad7a68
Fix irradiance.get_extra_radiation to be timezone-aware
yhkee0404 May 19, 2024
05961d2
Rerun and clear errors in clearsky.ipynb
yhkee0404 May 19, 2024
45a36cb
Remove clearsky.ipynb
yhkee0404 May 19, 2024
b00a2d4
Update what's new
yhkee0404 May 19, 2024
7bb7e02
Merge branch 'main' into clearsky-timezone
yhkee0404 May 23, 2024
6d1ab57
Merge branch 'main' into clearsky-timezone
yhkee0404 May 26, 2024
3fed282
Add docstring Notes to lookup_linke_turbidity
yhkee0404 Jun 1, 2024
6f98df7
Add tools._pandas_to_utc
yhkee0404 Jun 1, 2024
fe5b5c1
Update what's new
yhkee0404 Jun 4, 2024
97afcb8
Add docstring Notes to _pandas_to_doy
yhkee0404 Jun 5, 2024
defddfd
Revert _datetimelike_scalar_to_datetimeindex
yhkee0404 Jun 5, 2024
a08ca79
Revert tests.test_irradiance.times
yhkee0404 Jun 5, 2024
6baa1ed
Replace lowercase utc with uppercase
yhkee0404 Jun 5, 2024
4515366
Fix clearsky lookup_linke_turbidity and _interpolate_turbidity
yhkee0404 Jun 5, 2024
83a61ba
Fix linter
yhkee0404 Jun 8, 2024
745579c
Fix clearsky._interpolate_turbidity to keep timezone
yhkee0404 Jun 8, 2024
b6d238a
Revert irradiance.py
yhkee0404 Jun 8, 2024
fa62003
Clarify UTC input of ephem.Date
yhkee0404 Jun 8, 2024
5d80876
Fix tz-naive delta_t of dni_extra nrel
yhkee0404 Jun 8, 2024
3e95694
Fix tz-naive delta_t of get_solarposition nrel_numpy
yhkee0404 Jun 8, 2024
59cb82b
Avoid future midnight of location.get_sun_rise_set_transit spa
yhkee0404 Jun 8, 2024
6e1c251
Fix tz-naive delta_t of location.get_sun_rise_set_transit spa
yhkee0404 Jun 8, 2024
0baa338
Fix local midnight of hour_angle and sun_rise_set_transit
yhkee0404 Jun 8, 2024
cd45c74
Fix dayofyear of solarposition decl and eot, i.e. clearsky.bird
yhkee0404 Jun 8, 2024
1e6914d
Fix dayofyear of spectrum.spectrl2 dni_extra spencer
yhkee0404 Jun 8, 2024
dd78f3e
Fix monthly SeasonalTiltMount orientation
yhkee0404 Jun 8, 2024
35e0756
Fix year and dayofyear of solrad
yhkee0404 Jun 8, 2024
758ea98
Fix flake8
yhkee0404 Jun 15, 2024
5102347
Merge branch 'main' into clearsky-timezone
yhkee0404 Jun 15, 2024
1c940fb
Merge branch 'main' of https://github.com/pvlib/pvlib-python into cle…
cwhanse Jul 1, 2024
12c6a49
resolve whatsnew
cwhanse Jul 1, 2024
ab7d307
don't change v0.11.0
cwhanse Jul 1, 2024
82aa0df
Merge branch 'main' into clearsky-timezone
cwhanse Aug 12, 2024
c4862b5
minor adjustment to test_clearsky
cwhanse Aug 12, 2024
57d052e
undo edit to get_solrad
cwhanse Aug 12, 2024
85eae01
undo edit to get_solrad
cwhanse Aug 12, 2024
3fc5579
Merge branch 'main' of https://github.com/pvlib/pvlib-python into cle…
cwhanse Sep 4, 2024
f255e8b
Update pvlib/clearsky.py
cwhanse Sep 4, 2024
63df590
Update docs/sphinx/source/whatsnew/v0.11.1.rst
cwhanse Sep 4, 2024
639ce7f
Update docs/sphinx/source/whatsnew/v0.11.1.rst
cwhanse Sep 4, 2024
33f778f
Update docs/examples/irradiance-transposition/plot_seasonal_tilt.py
yhkee0404 Sep 6, 2024
16f0e5a
Revert benchmarks/benchmarks/solarposition.py
yhkee0404 Sep 9, 2024
2745954
Revert test_lookup_linke_turbidity_nointerp
yhkee0404 Sep 9, 2024
eb2707f
Revert solrad.py
yhkee0404 Sep 9, 2024
ab953b5
Revert plot_seasonal_tilt.py except notes
yhkee0404 Sep 9, 2024
b8246c0
Update test_sun_rise_set_transit_spa with delta_t
yhkee0404 Sep 12, 2024
7da25f4
Update test_nrel_earthsun_distance with delta_t
yhkee0404 Sep 12, 2024
70d06cb
Update test_sun_rise_set_transit_geometric with naive tz
yhkee0404 Sep 12, 2024
dea79d3
Update test_hour_angle with inversion and naive tz
yhkee0404 Sep 12, 2024
2143c94
Remove _is_leap_year from _interpolate_turbidity
yhkee0404 Sep 12, 2024
80a6afb
Merge branch 'main' into clearsky-timezone
yhkee0404 Sep 12, 2024
87cd719
Merge branch 'main' into clearsky-timezone
yhkee0404 Sep 18, 2024
c4b65e1
Update docs/sphinx/source/whatsnew/v0.11.1.rst
yhkee0404 Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.11.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Enhancements

Bug fixes
~~~~~~~~~
* Fixes clearsky.lookup_linke_turbidity and irradiance.get_extra_radiation to be timezone-aware
(:issue:`2054`, :pull:`2055`)
yhkee0404 marked this conversation as resolved.
Show resolved Hide resolved


Testing
Expand All @@ -42,3 +44,4 @@ Contributors
* Cliff Hansen (:ghuser:`cwhanse`)
* Mark Mikofski (:ghuser:`mikofski`)
* Siddharth Kaul (:ghuser:`k10blogger`)
* Yunho Kee (:ghuser:`yhkee0404`)
17 changes: 14 additions & 3 deletions pvlib/clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
Returns
-------
turbidity : Series

Notes
-----
Linke turbidity is obtained from a file of historical monthly averages.
The returned value for each time is either the monthly value or an
interpolated value to smooth the transition between months.
Interpolation is done on the day of year, and for this purpose time is
first converted to UTC.
cwhanse marked this conversation as resolved.
Show resolved Hide resolved
"""

# The .h5 file 'LinkeTurbidities.h5' contains a single 2160 x 4320 x 12
Expand Down Expand Up @@ -198,13 +206,16 @@ def lookup_linke_turbidity(time, latitude, longitude, filepath=None,
with h5py.File(filepath, 'r') as lt_h5_file:
lts = lt_h5_file['LinkeTurbidity'][latitude_index, longitude_index]

time_utc = tools._pandas_to_utc(time)

if interp_turbidity:
linke_turbidity = _interpolate_turbidity(lts, time)
linke_turbidity = _interpolate_turbidity(lts, time_utc)
else:
months = time.month - 1
linke_turbidity = pd.Series(lts[months], index=time)
months = time_utc.month - 1
linke_turbidity = pd.Series(lts[months], index=time_utc)

linke_turbidity /= 20.
linke_turbidity.index = time

return linke_turbidity

Expand Down
2 changes: 1 addition & 1 deletion pvlib/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def _handle_extra_radiation_types(datetime_or_doy, epoch_year):
# a better way to do it.
if isinstance(datetime_or_doy, pd.DatetimeIndex):
to_doy = tools._pandas_to_doy # won't be evaluated unless necessary
def to_datetimeindex(x): return x # noqa: E306
cwhanse marked this conversation as resolved.
Show resolved Hide resolved
to_datetimeindex = tools._pandas_to_utc
to_output = partial(pd.Series, index=datetime_or_doy)
elif isinstance(datetime_or_doy, pd.Timestamp):
to_doy = tools._pandas_to_doy
Expand Down
20 changes: 4 additions & 16 deletions pvlib/solarposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import warnings
import datetime

from pvlib import atmosphere
from pvlib import atmosphere, tools
from pvlib.tools import datetime_to_djd, djd_to_datetime


Expand Down Expand Up @@ -200,11 +200,7 @@
raise ImportError('Could not import built-in SPA calculator. ' +
'You may need to recompile the SPA code.')

# if localized, convert to UTC. otherwise, assume UTC.
try:
time_utc = time.tz_convert('UTC')
except TypeError:
time_utc = time
time_utc = tools._pandas_to_utc(time)

Check warning on line 203 in pvlib/solarposition.py

View check run for this annotation

Codecov / codecov/patch

pvlib/solarposition.py#L203

Added line #L203 was not covered by tests
cwhanse marked this conversation as resolved.
Show resolved Hide resolved

spa_out = []

Expand Down Expand Up @@ -645,11 +641,7 @@
except ImportError:
raise ImportError('PyEphem must be installed')

# if localized, convert to UTC. otherwise, assume UTC.
try:
time_utc = time.tz_convert('UTC')
except TypeError:
time_utc = time
time_utc = tools._pandas_to_utc(time)

sun_coords = pd.DataFrame(index=time)

Expand Down Expand Up @@ -766,11 +758,7 @@
# the SPA algorithm needs time to be expressed in terms of
# decimal UTC hours of the day of the year.

# if localized, convert to UTC. otherwise, assume UTC.
try:
time_utc = time.tz_convert('UTC')
except TypeError:
time_utc = time
time_utc = tools._pandas_to_utc(time)

# strip out the day of the year and calculate the decimal hour
DayOfYear = time_utc.dayofyear
Expand Down
12 changes: 6 additions & 6 deletions pvlib/tests/test_clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def test_ineichen_altitude():

def test_lookup_linke_turbidity():
times = pd.date_range(start='2014-06-24', end='2014-06-25',
freq='12h', tz='America/Phoenix')
freq='12h', tz='utc').tz_convert('America/Phoenix')
# expect same value on 2014-06-24 0000 and 1200, and
# diff value on 2014-06-25
expected = pd.Series(
Expand All @@ -203,7 +203,7 @@ def test_lookup_linke_turbidity():

def test_lookup_linke_turbidity_leapyear():
times = pd.date_range(start='2016-06-24', end='2016-06-25',
freq='12h', tz='America/Phoenix')
freq='12h', tz='utc').tz_convert('America/Phoenix')
# expect same value on 2016-06-24 0000 and 1200, and
# diff value on 2016-06-25
expected = pd.Series(
Expand All @@ -214,8 +214,8 @@ def test_lookup_linke_turbidity_leapyear():


def test_lookup_linke_turbidity_nointerp():
times = pd.date_range(start='2014-06-24', end='2014-06-25',
freq='12h', tz='America/Phoenix')
times = pd.date_range(start='2014-06-01', end='2014-06-02',
cwhanse marked this conversation as resolved.
Show resolved Hide resolved
freq='12h', tz='utc').tz_convert('America/Phoenix')
# expect same value for all days
expected = pd.Series(np.array([3., 3., 3.]), index=times)
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875,
Expand All @@ -225,7 +225,7 @@ def test_lookup_linke_turbidity_nointerp():

def test_lookup_linke_turbidity_months():
times = pd.date_range(start='2014-04-01', end='2014-07-01',
freq='1M', tz='America/Phoenix')
freq='1M', tz='utc').tz_convert('America/Phoenix')
expected = pd.Series(
np.array([2.89918032787, 2.97540983607, 3.19672131148]), index=times
)
Expand All @@ -235,7 +235,7 @@ def test_lookup_linke_turbidity_months():

def test_lookup_linke_turbidity_months_leapyear():
times = pd.date_range(start='2016-04-01', end='2016-07-01',
freq='1M', tz='America/Phoenix')
freq='1M', tz='utc').tz_convert('America/Phoenix')
expected = pd.Series(
np.array([2.89918032787, 2.97540983607, 3.19672131148]), index=times
)
Expand Down
6 changes: 3 additions & 3 deletions pvlib/tests/test_irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
def times():
# must include night values
return pd.date_range(start='20140624', freq='6h', periods=4,
tz='US/Arizona')
tz='utc').tz_convert('US/Arizona')
cwhanse marked this conversation as resolved.
Show resolved Hide resolved


@pytest.fixture
Expand Down Expand Up @@ -112,7 +112,7 @@ def test_get_extra_radiation_nrel_numba(times):
# and reset to no-numba state
irradiance.get_extra_radiation(times, method='nrel')
assert_allclose(result,
[1322.332316, 1322.296282, 1322.261205, 1322.227091])
[1322.375560, 1322.338415, 1322.302221, 1322.266984])


def test_get_extra_radiation_invalid():
Expand Down Expand Up @@ -612,7 +612,7 @@ def test_disc_value(pressure, expected):
# see GH 449 for pressure=None vs. 101325.
columns = ['dni', 'kt', 'airmass']
times = pd.DatetimeIndex(['2014-06-24T1200', '2014-06-24T1800'],
tz='America/Phoenix')
tz='utc').tz_convert('America/Phoenix')
cwhanse marked this conversation as resolved.
Show resolved Hide resolved
ghi = pd.Series([1038.62, 254.53], index=times)
zenith = pd.Series([10.567, 72.469], index=times)
out = irradiance.disc(ghi, zenith, times, pressure=pressure)
Expand Down
32 changes: 29 additions & 3 deletions pvlib/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,28 @@
-------
dayofyear
"""
return pd_object.dayofyear
return _pandas_to_utc(pd_object).dayofyear
yhkee0404 marked this conversation as resolved.
Show resolved Hide resolved


def _pandas_to_utc(pd_object):
cwhanse marked this conversation as resolved.
Show resolved Hide resolved
"""
Converts a pandas datetime-like object to UTC, if localized.
Otherwise, assume UTC.

Parameters
----------
pd_object : DatetimeIndex or Timestamp

Returns
-------
pandas object localized to or assumed to be UTC.
"""
#

Check failure on line 226 in pvlib/tools.py

View workflow job for this annotation

GitHub Actions / flake8-linter

W291 trailing whitespace
try:
pd_object_utc = pd_object.tz_convert('UTC')
except TypeError:
pd_object_utc = pd_object
return pd_object_utc


def _doy_to_datetimeindex(doy, epoch_year=2014):
Expand All @@ -230,11 +251,16 @@


def _datetimelike_scalar_to_doy(time):
return pd.DatetimeIndex([pd.Timestamp(time)]).dayofyear
return _datetimelike_scalar_to_datetimeindex(time).dayofyear


def _datetimelike_scalar_to_datetimeindex(time):
return pd.DatetimeIndex([pd.Timestamp(time)])

timestamp = pd.Timestamp(time)

timestamp_utc = _pandas_to_utc(timestamp)
cwhanse marked this conversation as resolved.
Show resolved Hide resolved

return pd.DatetimeIndex([timestamp_utc])


def _scalar_out(arg):
Expand Down
Loading