Skip to content

Commit 0f185ed

Browse files
authored
Merge branch 'main' into ants2d
2 parents 6dbcd22 + 6fd4b07 commit 0f185ed

5 files changed

Lines changed: 47 additions & 8 deletions

File tree

docs/sphinx/source/whatsnew/v0.15.2.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ Bug fixes
3030
data type integer, users can expect modeled cell temperature values to
3131
increase slightly.
3232
(:issue:`2608`, :pull:`2745`)
33-
33+
* Fixes a regression in :py:func:`pvlib.tracking.calc_surface_orientation`
34+
introduced in v0.15.1 (:pull:`2702`) that caused a broadcasting
35+
``ValueError`` when ``tracker_theta`` was a 2-D (or higher rank) array.
36+
(:issue:`2747`, :pull:`2749`)
37+
3438

3539
Enhancements
3640
~~~~~~~~~~~~
@@ -42,6 +46,9 @@ Enhancements
4246
* Accelerate :py:func:`~pvlib.bifacial.utils.vf_ground_sky_2d_integ` by one or
4347
two orders of magnitude. This also makes :py:mod:`pvlib.bifacial.infinite_sheds` faster.
4448
(:pull:`2740`)
49+
* Added mapping of the parameter ``"albedo"`` in
50+
:py:func:`~pvlib.iotools.get_nasa_power` when ``map_variables=True``
51+
(:pull:`2753`)
4552

4653

4754
Documentation
@@ -74,3 +81,5 @@ Contributors
7481
~~~~~~~~~~~~
7582
* :ghuser:`Omesh37`
7683
* Cliff Hansen (:ghuser:`cwhanse`)
84+
* Arthur Onno (:ghuser:`ArthurOnnoTerabase`)
85+
* Adam R. Jensen (:ghuser:`AdamRJensen`)

pvlib/iotools/nasa_power.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
'T2M': 'temp_air',
1919
'WS2M': 'wind_speed_2m',
2020
'WS10M': 'wind_speed',
21+
'ALLSKY_SRF_ALB': 'albedo',
2122
}
2223

2324

pvlib/tracking.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,11 @@ def _unit_normal(axis_azimuth, axis_tilt, theta):
233233
Returns
234234
-------
235235
ndarray
236-
Shape (N,3) where theta has length N
236+
Shape ``theta.shape + (3,)``, with a minimum rank of 2. For 1-D
237+
``theta`` of length N this is ``(N, 3)``.
237238
"""
238239

239-
theta = np.asarray(theta)
240+
theta = np.atleast_1d(np.asarray(theta))
240241

241242
cA, sA = cosd(-axis_azimuth), sind(-axis_azimuth)
242243
cT, sT = cosd(-axis_tilt), sind(-axis_tilt)
@@ -248,7 +249,7 @@ def _unit_normal(axis_azimuth, axis_tilt, theta):
248249
y = sA * sTh - cA * sT * cTh
249250
z = cT * cTh
250251

251-
result = np.column_stack((x, y, z))
252+
result = np.stack((x, y, z), axis=-1)
252253

253254
return result
254255

@@ -296,7 +297,7 @@ def calc_surface_orientation(tracker_theta, axis_tilt=0, axis_azimuth=0):
296297

297298
# project unit_normal to x-y plane to calculate azimuth
298299
surface_azimuth = np.degrees(
299-
np.arctan2(unit_normal[:, 0], unit_normal[:, 1]))
300+
np.arctan2(unit_normal[..., 0], unit_normal[..., 1]))
300301

301302
surface_azimuth = np.where(surface_tilt == 0., axis_azimuth - 90.,
302303
surface_azimuth)

tests/iotools/test_meteonorm.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ def expected_meta():
3434
'description': 'Global horizontal irradiance',
3535
'name': 'global_horizontal_irradiance',
3636
'unit': {
37-
'description': 'Watt per square meter', 'name': 'W/m**2'}},
37+
'description': 'watt per square meter', 'name': 'W/m**2'}},
3838
{'aggregation_method': 'average',
3939
'description': 'Global horizontal irradiance with shading taken into account', # noqa: E501
4040
'name': 'global_horizontal_irradiance_with_shading',
41-
'unit': {'description': 'Watt per square meter',
41+
'unit': {'description': 'watt per square meter',
4242
'name': 'W/m**2'}},
4343
],
4444
'surface_azimuth': 180,
@@ -245,7 +245,7 @@ def expected_meteonorm_tmy_meta():
245245
'aggregation_method': 'average',
246246
'description': 'Diffuse horizontal irradiance',
247247
'name': 'diffuse_horizontal_irradiance',
248-
'unit': {'description': 'Watt per square meter',
248+
'unit': {'description': 'watt per square meter',
249249
'name': 'W/m**2'},
250250
}],
251251
'surface_azimuth': 90,

tests/test_tracking.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,3 +557,31 @@ def test_calc_surface_orientation_special():
557557
# in a modulo-360 sense.
558558
np.testing.assert_allclose(np.round(out['surface_azimuth'], 4) % 360,
559559
expected_azimuths, rtol=1e-5, atol=1e-5)
560+
561+
562+
@pytest.mark.parametrize('shape', [(3, 5), (1, 7), (4, 1), (2, 3, 4)])
563+
def test_calc_surface_orientation_2d(shape):
564+
# Regression test for GH#2747: calc_surface_orientation must accept
565+
# tracker_theta of arbitrary rank, not just 1-D. Compare the >1-D result
566+
# to the 1-D result computed on the flattened input.
567+
rotations_flat = np.linspace(-90, 90, int(np.prod(shape)))
568+
rotations_nd = rotations_flat.reshape(shape)
569+
570+
out_1d = tracking.calc_surface_orientation(rotations_flat,
571+
axis_tilt=20,
572+
axis_azimuth=180)
573+
out_nd = tracking.calc_surface_orientation(rotations_nd,
574+
axis_tilt=20,
575+
axis_azimuth=180)
576+
577+
assert out_nd['surface_tilt'].shape == shape
578+
assert out_nd['surface_azimuth'].shape == shape
579+
np.testing.assert_allclose(out_nd['surface_tilt'].reshape(-1),
580+
out_1d['surface_tilt'])
581+
np.testing.assert_allclose(out_nd['surface_azimuth'].reshape(-1),
582+
out_1d['surface_azimuth'])
583+
584+
# _unit_normal must preserve the input rank, appending a trailing axis
585+
# of length 3.
586+
unorm = tracking._unit_normal(180., 20., rotations_nd)
587+
assert unorm.shape == shape + (3,)

0 commit comments

Comments
 (0)