Skip to content

Commit bf90617

Browse files
committed
Merge branch 'reindl-components' of https://github.com/cbcrespo/pvlib-python into reindl-components
2 parents 0688d0c + 525e285 commit bf90617

25 files changed

Lines changed: 484 additions & 168 deletions

docs/examples/irradiance-transposition/plot_rtranpose_limitations.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#
2929
# In this example we look at a single point in time and consider a full range
3030
# of possible GHI and POA global values as shown in figures 3 and 4 of [1]_.
31-
# Then we use :py:meth:`pvlib.irradiance.ghi_from_poa_driesse_2023` to estimate
31+
# Then we use :py:meth:`pvlib.irradiance.ghi_from_poa_driesse_2024` to estimate
3232
# the original GHI from POA global.
3333
#
3434
# References
@@ -45,7 +45,7 @@
4545

4646
from pvlib.irradiance import (erbs_driesse,
4747
get_total_irradiance,
48-
ghi_from_poa_driesse_2023,
48+
ghi_from_poa_driesse_2024,
4949
)
5050

5151
matplotlib.rcParams['axes.grid'] = True
@@ -92,7 +92,7 @@
9292

9393
poa_test = 200
9494

95-
ghi_hat = ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
95+
ghi_hat = ghi_from_poa_driesse_2024(surface_tilt, surface_azimuth,
9696
solar_zenith, solar_azimuth,
9797
poa_test,
9898
dni_extra,
@@ -156,7 +156,7 @@
156156
# out, other times not.
157157
#
158158

159-
result = ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
159+
result = ghi_from_poa_driesse_2024(surface_tilt, surface_azimuth,
160160
solar_zenith, solar_azimuth,
161161
poa_global,
162162
dni_extra,

docs/examples/irradiance-transposition/plot_rtranpose_year.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# Recovering GHI from POA irradiance is termed "reverse transposition."
2222
#
2323
# In this example we start with a TMY file and calculate POA global irradiance.
24-
# Then we use :py:meth:`pvlib.irradiance.ghi_from_poa_driesse_2023` to estimate
24+
# Then we use :py:meth:`pvlib.irradiance.ghi_from_poa_driesse_2024` to estimate
2525
# the original GHI from POA global. Details of the method found in [1]_.
2626
#
2727
# Another method for reverse tranposition called GTI-DIRINT is also
@@ -49,7 +49,7 @@
4949
from pvlib import iotools, location
5050
from pvlib.irradiance import (get_extra_radiation,
5151
get_total_irradiance,
52-
ghi_from_poa_driesse_2023,
52+
ghi_from_poa_driesse_2024,
5353
aoi,
5454
)
5555

@@ -114,7 +114,7 @@
114114

115115
start = time.process_time()
116116

117-
df['ghi_rev'] = ghi_from_poa_driesse_2023(TILT, ORIENT,
117+
df['ghi_rev'] = ghi_from_poa_driesse_2024(TILT, ORIENT,
118118
solpos.apparent_zenith,
119119
solpos.azimuth,
120120
df.poa_global,

docs/sphinx/source/reference/irradiance/reverse-transposition.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ Reverse transposition models
66
.. autosummary::
77
:toctree: ../generated/
88

9-
irradiance.ghi_from_poa_driesse_2023
9+
irradiance.ghi_from_poa_driesse_2024
1010
irradiance.gti_dirint

docs/sphinx/source/user_guide/modeling_topics/timetimezones.rst

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Time and time zones
55

66
Dealing with time and time zones can be a frustrating experience in any
77
programming language and for any application. pvlib-python relies on
8-
:py:mod:`pandas` and `pytz <http://pythonhosted.org/pytz/>`_ to handle
8+
:py:mod:`pandas` and the builtin :py:mod:`python:zoneinfo` to handle
99
time and time zones. Therefore, the vast majority of the information in
1010
this document applies to any time series analysis using pandas and is
1111
not specific to pvlib-python.
@@ -14,52 +14,53 @@ General functionality
1414
---------------------
1515

1616
pvlib makes extensive use of pandas due to its excellent time series
17-
functionality. Take the time to become familiar with pandas' `Time
18-
Series / Date functionality page
19-
<http://pandas.pydata.org/pandas-docs/version/0.18.0/timeseries.html>`_.
17+
functionality. Take the time to become familiar with pandas'
18+
:external+pandas:doc:`Time Series / Date functionality page <user_guide/timeseries>`.
2019
It is also worthwhile to become familiar with pure Python's
21-
:py:mod:`python:datetime` module, although we usually recommend
22-
using the corresponding pandas functionality where possible.
20+
:py:mod:`python:datetime` module, although we usually recommend using the
21+
corresponding pandas functionality where possible.
2322

2423
First, we'll import the libraries that we'll use to explore the basic
2524
time and time zone functionality in python and pvlib.
2625

2726
.. ipython:: python
2827
2928
import datetime
29+
import zoneinfo
3030
import pandas as pd
31-
import pytz
3231
3332
3433
Finding a time zone
3534
*******************
3635

37-
pytz is based on the Olson time zone database. You can obtain a list of
38-
all valid time zone strings with ``pytz.all_timezones``. It's a long
39-
list, so we only print every 20th time zone.
36+
``zoneinfo`` is based on the IANA (Olson) time zone database. You can obtain
37+
a set of all valid time zone strings with ``zoneinfo.available_timezones()``.
38+
It's a large set, so we only print every 20th time zone (sorted for
39+
consistency).
4040

4141
.. ipython:: python
4242
43-
len(pytz.all_timezones)
44-
pytz.all_timezones[::20]
43+
len(zoneinfo.available_timezones())
44+
sorted(zoneinfo.available_timezones())[::20]
4545
4646
Wikipedia's `List of tz database time zones
4747
<https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_ is also
4848
good reference.
4949

50-
The ``pytz.country_timezones`` function is useful, too.
50+
You can filter the available time zones using Python's built-in
51+
:py:func:`python:filter` function.
5152

5253
.. ipython:: python
5354
54-
pytz.country_timezones('US')
55+
sorted(filter(lambda x: 'America' in x, zoneinfo.available_timezones()))
5556
56-
And don't forget about Python's :py:func:`python:filter` function.
57+
And you can also filter for GMT-based fixed offset zones:
5758

5859
.. ipython:: python
5960
60-
list(filter(lambda x: 'GMT' in x, pytz.all_timezones))
61+
sorted(filter(lambda x: 'GMT' in x, zoneinfo.available_timezones()))
6162
62-
Note that while pytz has ``'EST'`` and ``'MST'``, it does not have
63+
Note that while the IANA database has ``'EST'`` and ``'MST'``, it does not have
6364
``'PST'``. Use ``'Etc/GMT+8'`` instead, or see :ref:`fixedoffsets`.
6465

6566
Timestamps
@@ -125,7 +126,7 @@ vs. the UTC offset in summer...
125126
pd.Timestamp('2015-6-1 00:00').tz_localize('US/Mountain')
126127
pd.Timestamp('2015-6-1 00:00').tz_localize('Etc/GMT+7')
127128
128-
pandas and pytz make this time zone handling possible because pandas
129+
pandas makes this time zone handling possible because pandas
129130
stores all times as integer nanoseconds since January 1, 1970.
130131
Here is the pandas time representation of the integers 1 and 1e9.
131132

@@ -174,12 +175,13 @@ specifications, but watch out for the counter-intuitive sign convention.
174175
175176
pd.Timestamp('2015-1-1 00:00', tz='Etc/GMT-2')
176177
177-
Fixed offset time zones can also be specified as offset minutes
178-
from UTC using ``pytz.FixedOffset``.
178+
Fixed offset time zones can also be specified using
179+
:py:class:`python:datetime.timezone` with a
180+
:py:class:`python:datetime.timedelta` offset.
179181

180182
.. ipython:: python
181183
182-
pd.Timestamp('2015-1-1 00:00', tz=pytz.FixedOffset(120))
184+
pd.Timestamp('2015-1-1 00:00', tz=datetime.timezone(datetime.timedelta(hours=2)))
183185
184186
You can also specify the fixed offset directly in the ``tz_localize``
185187
method, however, be aware that this is not documented and that the
@@ -216,8 +218,8 @@ expected.
216218
# tz naive pandas Timestamp object
217219
pd.Timestamp(naive_python_dt)
218220
219-
# tz aware python datetime.datetime object
220-
aware_python_dt = pytz.timezone('US/Mountain').localize(naive_python_dt)
221+
# tz aware python datetime.datetime object using zoneinfo
222+
aware_python_dt = naive_python_dt.replace(tzinfo=zoneinfo.ZoneInfo('US/Mountain'))
221223
222224
# tz aware pandas Timestamp object
223225
pd.Timestamp(aware_python_dt)
@@ -234,13 +236,14 @@ passed to ``Timestamp``.
234236
# tz naive pandas Timestamp object (time=midnight)
235237
pd.Timestamp(naive_python_date)
236238
237-
You cannot localize a native Python date object.
239+
You cannot localize a native Python date object directly; you must first
240+
convert it to a :py:class:`python:datetime.datetime`.
238241

239242
.. ipython:: python
240243
:okexcept:
241244
242-
# fail
243-
pytz.timezone('US/Mountain').localize(naive_python_date)
245+
# fail: datetime.date has no tzinfo support via replace
246+
naive_python_date.replace(tzinfo=zoneinfo.ZoneInfo('US/Mountain'))
244247
245248
246249
pvlib-specific functionality
@@ -348,7 +351,7 @@ UTC, and then convert it to the desired time zone.
348351

349352
.. ipython:: python
350353
351-
fixed_tz = pytz.FixedOffset(tmy3_metadata['TZ'] * 60)
354+
fixed_tz = datetime.timezone(datetime.timedelta(hours=tmy3_metadata['TZ']))
352355
solar_position_hack = solar_position_notz.tz_localize('UTC').tz_convert(fixed_tz)
353356
354357
solar_position_hack.index

docs/sphinx/source/whatsnew.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ What's New
66

77
These are new features and improvements of note in each release.
88

9+
.. include:: whatsnew/v0.15.3.rst
910
.. include:: whatsnew/v0.15.2.rst
1011
.. include:: whatsnew/v0.15.1.rst
1112
.. include:: whatsnew/v0.15.0.rst
Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,86 @@
11
.. _whatsnew_0_15_2:
22

33

4-
v0.15.2 (Anticipated June 2026)
5-
-------------------------------
6-
7-
Breaking Changes
8-
~~~~~~~~~~~~~~~~
4+
v0.15.2 (June 16, 2026)
5+
-----------------------
96

107

118
Deprecations
129
~~~~~~~~~~~~
10+
* Deprecate :py:attr:`pvlib.location.Location.pytz`.
11+
Use :py:attr:`~pvlib.location.Location.tz` instead. (:issue:`2343`, :pull:`2757`)
12+
* Rename :py:func:`!pvlib.irradiance.ghi_from_poa_driesse_2023` to
13+
:py:func:`~pvlib.irradiance.ghi_from_poa_driesse_2024`. The year now reflects
14+
the publication date. The old name will be removed in v0.17.0.
15+
(:issue:`2774`, :pull:`2777`)
1316

1417

1518
Bug fixes
1619
~~~~~~~~~
17-
* Corrects a bug in :py:func:`pvlib.temperature.fuentes`. If inputs were
18-
data type integer, users can expect modeled cell temperature values to
19-
increase slightly.
20-
(:issue:`2608`, :pull:`2745`)
21-
* Fixes a regression in :py:func:`pvlib.tracking.calc_surface_orientation`
20+
* Fix :py:func:`pvlib.temperature.fuentes` truncating the output if `poa_global` input was
21+
data type integer. Users can expect modeled cell temperature values to
22+
increase slightly. (:issue:`2608`, :pull:`2745`)
23+
* Fix a regression in :py:func:`pvlib.tracking.calc_surface_orientation`
2224
introduced in v0.15.1 (:pull:`2702`) that caused a broadcasting
2325
``ValueError`` when ``tracker_theta`` was a 2-D (or higher rank) array.
2426
(:issue:`2747`, :pull:`2749`)
2527
* Document that timestamps returned by :py:func:`~pvlib.iotools.get_era5`
2628
represent the end of the averaging interval, consistent with ERA5
2729
conventions. (:issue:`2772`, :pull:`2773`)
30+
* Fix header parsing in :py:func:`pvlib.iotools.read_nsrdb_psm4` with quoted
31+
commas in column names. This allows spectral-on-demand files to be read. (:issue:`2736`, :pull:`2771`)
32+
* Update :py:func:`~pvlib.iotools.get_meteonorm_tmy` to comply
33+
with the updated Meteonorm API. As part of this, the ``data_version``
34+
parameter now has no effect and will be removed in the future. (:pull:`2781`)
2835

2936

3037
Enhancements
3138
~~~~~~~~~~~~
3239
* Add the ``front_side_fraction`` parameter to
3340
:py:func:`pvlib.snow.loss_townsend` to support Townsend snow-loss
3441
workflows for bifacial systems. (:issue:`2755`, :pull:`2756`)
35-
36-
* Added mapping of the parameter ``"albedo"`` in
37-
:py:func:`~pvlib.iotools.get_nasa_power` when ``map_variables=True``
38-
(:pull:`2753`)
42+
* Add the following parameters to :py:func:`~pvlib.iotools.get_nasa_power`
43+
when ``map_variables=True``: ``temp_dew``, ``precipitable_water``,
44+
``relative_humidity``, ``ghi_extra``, ``dhi_clear``, ``longwave_down``,
45+
and ``albedo``. (:issue:`2731`, :pull:`2753`, :pull:`2762`)
3946

4047

4148
Documentation
4249
~~~~~~~~~~~~~
43-
* Clarifies that :py:func:`pvlib.soiling.hsu` has an implicit minimum
50+
* Clarify that :py:func:`pvlib.soiling.hsu` has an implicit minimum
4451
soiling ratio of approximately 0.6563 due to the mathematical form
4552
of the model. (:issue:`2534`, :pull:`2743`)
46-
* Clarifies how Linke turbidity values can be provided to
47-
:py:func:`pvlib.clearsky.ineichen` via
48-
:py:func:`pvlib.clearsky.lookup_linke_turbidity` (:issue:`2598`, :pull:`2746`)
53+
* Clarify how Linke turbidity values can be provided to
54+
:py:func:`pvlib.clearsky.ineichen` via
55+
:py:func:`pvlib.clearsky.lookup_linke_turbidity`. (:issue:`2598`, :pull:`2746`)
4956

5057

5158
Testing
5259
~~~~~~~
53-
54-
55-
Benchmarking
56-
~~~~~~~~~~~~
57-
58-
59-
Requirements
60-
~~~~~~~~~~~~
61-
62-
63-
Maintenance
64-
~~~~~~~~~~~
60+
* Add test coverage for :py:func:`pvlib.irradiance.dirint` with
61+
``np.array`` and ``pd.Series`` inputs. (:issue:`2751`, :pull:`2752`)
6562

6663

6764
Contributors
6865
~~~~~~~~~~~~
6966
* :ghuser:`Omesh37`
67+
* :ghuser:`gaoflow`
7068
* Cliff Hansen (:ghuser:`cwhanse`)
7169
* :ghuser:`shethkajal7`
7270
* Arthur Onno (:ghuser:`ArthurOnnoTerabase`)
7371
* Adam R. Jensen (:ghuser:`AdamRJensen`)
72+
* :ghuser:`JoLo90`
73+
* Karl Hill (:ghuser:`karlhillx`)
74+
* Rajiv Daxini (:ghuser:`RDaxini`)
75+
* Vincent Filter (:ghuser:`vfilter`)
76+
* Klaus Jäger (:ghuser:`solartube`)
77+
* Carolina Crespo (:ghuser:`cbcrespo`)
78+
* Ioannis Sifnaios (:ghuser:`IoannisSifnaios`)
79+
* Anton Driesse (:ghuser:`adriesse`)
80+
* Mark Mikofski (:ghuser:`mikofski`)
81+
* Rodrigo Amaro e Silva (:ghuser:`ramaroesilva`)
82+
* Will Hobbs (:ghuser:`williamhobbs`)
83+
* Echedey Luis (:ghuser:`echedey-ls`)
84+
* Cliff Hansen (:ghuser:`cwhanse`)
85+
* Will Holmgren (:ghuser:`wholmgren`)
86+
* Kevin Anderson (:ghuser:`kandersolar`)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.. _whatsnew_0_15_3:
2+
3+
4+
v0.15.3 (Anticipated September, 2026)
5+
-------------------------------------
6+
7+
Breaking Changes
8+
~~~~~~~~~~~~~~~~
9+
10+
11+
Deprecations
12+
~~~~~~~~~~~~
13+
14+
15+
Bug fixes
16+
~~~~~~~~~
17+
18+
19+
Enhancements
20+
~~~~~~~~~~~~
21+
22+
23+
Documentation
24+
~~~~~~~~~~~~~
25+
26+
27+
Testing
28+
~~~~~~~
29+
30+
31+
Benchmarking
32+
~~~~~~~~~~~~
33+
34+
35+
Requirements
36+
~~~~~~~~~~~~
37+
38+
39+
Maintenance
40+
~~~~~~~~~~~
41+
42+
43+
Contributors
44+
~~~~~~~~~~~~
45+

docs/tutorials/solarposition.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
"outputs": [],
122122
"source": [
123123
"times = pd.date_range(start=datetime.datetime(2014,6,23), end=datetime.datetime(2014,6,24), freq='1Min')\n",
124-
"times_loc = times.tz_localize(tus.pytz)"
124+
"times_loc = times.tz_localize(tus.tz)"
125125
]
126126
},
127127
{

0 commit comments

Comments
 (0)