From 5d2a27821390d091977ce3f5dc99627199e6e6a4 Mon Sep 17 00:00:00 2001 From: Dylan Pulver Date: Tue, 1 Sep 2026 12:53:37 +0300 Subject: [PATCH] Fix turbine_type search parameter in get_oedb_windturbineconfig The `turbine_type` branch filtered the `turbine_type` column with the value of `search_params["name"]`. Searching by `turbine_type` alone raised `KeyError: 'name'`, and passing both silently ignored the requested turbine type. In the OEDB wind turbine library the two columns differ for 58 of the 68 entries that carry a power curve, so the two are not interchangeable. --- RELEASE_NOTES.rst | 5 +++++ atlite/resource.py | 4 +++- test/test_resource.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index c06f88ed..b2658101 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -35,6 +35,11 @@ Upcoming Release **Bug fixes** +* Fix ``get_oedb_windturbineconfig`` applying the documented ``turbine_type`` + search parameter to the value of ``name``. Searching by ``turbine_type`` + alone raised ``KeyError: 'name'``, and combining it with ``name`` silently + ignored the requested turbine type. + * Fix ``Cutout.line_rating`` passing line azimuth in radians while ``convert_line_rating`` interpreted ``psi`` as degrees. Azimuths are now computed in degrees, matching the documented unit. diff --git a/atlite/resource.py b/atlite/resource.py index 616ac894..545b419a 100644 --- a/atlite/resource.py +++ b/atlite/resource.py @@ -507,7 +507,9 @@ def get_oedb_windturbineconfig( if "name" in search_params: selector &= df.name.str.contains(search_params["name"], case=False) if "turbine_type" in search_params: - selector &= df.turbine_type.str.contains(search_params["name"], case=False) + selector &= df.turbine_type.str.contains( + search_params["turbine_type"], case=False + ) if "manufacturer" in search_params: selector &= df.manufacturer.str.contains( search_params["manufacturer"], case=False diff --git a/test/test_resource.py b/test/test_resource.py index f7e82f6d..92eae3e2 100644 --- a/test/test_resource.py +++ b/test/test_resource.py @@ -9,11 +9,54 @@ @author: fabian """ +import json + +import pandas as pd import pytest +from atlite import resource from atlite.resource import get_oedb_windturbineconfig, get_windturbineconfig +@pytest.fixture +def oedb_turbines(monkeypatch): + """Two-row stand-in for the OEDB library, with 'name' != 'turbine_type'. + + In the live OEDB wind turbine library the two columns hold different + strings for most entries, so a filter has to be applied to the column it + names. Patching the module-level cache keeps the test offline. + """ + df = pd.DataFrame({ + "id": [0, 1], + "manufacturer": ["Enercon", "Nordex"], + "name": ["E-101/3500 E2", "Gamma Series"], + "turbine_type": ["E-101/3500", "N131/3600"], + "has_power_curve": [True, True], + "power_curve_wind_speeds": [json.dumps([0.0, 25.0])] * 2, + "power_curve_values": [json.dumps([0.0, 3500.0]), json.dumps([0.0, 3600.0])], + "hub_height": [149.0, 134.0], + "source": ["test", "test"], + }) + monkeypatch.setattr(resource, "_oedb_turbines", df) + + +def test_oedb_windturbineconfig_turbine_type_alone(oedb_turbines): + # 'turbine_type' is a documented search parameter and has to work on its own. + assert get_oedb_windturbineconfig(turbine_type="N131/3600")["name"] == "N131/3600" + + +def test_oedb_windturbineconfig_turbine_type_narrows(oedb_turbines): + # A 'turbine_type' matching no turbine must narrow the result to nothing, + # even when a 'name' that does match is given alongside it. + with pytest.raises(RuntimeError, match="No turbine found"): + get_oedb_windturbineconfig(name="E-101/3500", turbine_type="N131/3600") + + +def test_oedb_windturbineconfig_manufacturer_search(oedb_turbines): + # Control: the neighbouring search parameters keep working. + assert get_oedb_windturbineconfig(manufacturer="Nordex")["name"] == "N131/3600" + + def test_oedb_windturbineconfig(): # test int search assert get_oedb_windturbineconfig(1)