Integer/float bug in `pvlib.temperature.fuentes`
Describe the bug
In the temperature.py module here, pvlib is using np.zeros_like which crucially returns the same type than the input.
In the unit tests, pvlib uses int instead of float values here. This leads to NumPy truncating the first float result produced (321.19 -> 321).
The final subtraction tmod_array - 273.15 then converts to a float, giving 321 - 273.15 = 47.85
That means, the results of the Fuentes functions will differ, depending on whether the input is an int or a float.
To Reproduce
Steps to reproduce the behavior:
Run the test_fuentes_timezone unit test with ints and then again with floats
Expected behavior Ints and floats should produce the same results if they have the same value (i.e., 100 vs 100.0)
Screenshots
Agreed, bug:
In [1]: import pvlib
...: import pandas as pd
...:
...: inputs = pd.DataFrame({
...: 'poa_global': [1000, 500],
...: 'temp_air': [25, 25],
...: 'wind_speed': [1, 1],
...: }, index=pd.date_range("2019-01-01", freq="h", periods=2))
...:
...: for dtype in [int, float]:
...: inputs = inputs.astype(dtype)
...: print(pvlib.temperature.fuentes(**inputs, noct_installed=45))
...:
2019-01-01 00:00:00 51.85
2019-01-01 01:00:00 41.85
Freq: h, Name: tmod, dtype: float64
2019-01-01 00:00:00 52.785863
2019-01-01 01:00:00 42.777408
Freq: h, Name: tmod, dtype: float64
Thanks for reporting, @vfilter! Please submit a bugfix PR if you're interested.
Hi, I’m interested in working on this issue as part of contributing to pvlib.
From reading the description and the current implementation of fuentes in pvlib/temperature.py, my understanding is:
Internal arrays are created with np.zeros_like(...), so they inherit the dtype of the input.
When the input is integer, the intermediate temperature values (e.g. 321.19 K) are written into an integer array and truncated (e.g. to 321), and only later converted back to float when subtracting 273.15.
This leads to different results for inputs that are numerically the same but differ only by dtype (e.g. 100 vs 100.0), which is not desirable for a physical model.
Proposed approach:
->In pvlib.temperature.fuentes, change the creation of internal arrays (currently using np.zeros_like) to ensure a floating dtype, for example:
->np.zeros_like(..., dtype=float) or
->np.zeros(shape, dtype=float) where appropriate.
Verify that this does not change behavior for typical float inputs, but removes the truncation when integer inputs are used.
Extend or add unit tests in tests/test_temperature.py to explicitly check that:
Calling fuentes with integer inputs and with float inputs (same numeric values) yields the same results within a reasonable tolerance.
Before I start implementing this, could you please confirm that:
Forcing a float dtype for the internal arrays in fuentes is the preferred approach, and
There are no specific backwards-compatibility concerns with integer-only workflows that I should be aware of?