diff --git a/docs/api.rst b/docs/api.rst index 6abdc27e..72ae5f4e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -144,6 +144,20 @@ Quality checks for weather data. quality.weather.temperature_limits quality.weather.wind_limits +In addition to validating temperature by comparing with limits, module +temperature should be positively correlated with irradiance. Poor +correlation could indicate that the sensor has become detached from +the module, for example. Unlike other functions in the +:py:mod:`quality` module which return Boolean masks over the input +series, this function returns a single Boolean value indicating +whether the entire series has passed (``True``) or failed (``False``) +the quality check. + +.. autosummary:: + :toctree: generated/ + + quality.weather.module_temperature_check + .. rubric:: References .. [1] C. N. Long and Y. Shi, An Automated Quality Assessment and Control diff --git a/pvanalytics/quality/weather.py b/pvanalytics/quality/weather.py index caa7d888..5e331bab 100644 --- a/pvanalytics/quality/weather.py +++ b/pvanalytics/quality/weather.py @@ -1,5 +1,6 @@ """Quality control functions for weather data.""" from pvanalytics.quality import util +from scipy import stats def temperature_limits(air_temperature, limits=(-35.0, 50.0)): @@ -97,3 +98,30 @@ def wind_limits(wind_speed, limits=(0.0, 50.0)): upper_bound=limits[1], inclusive_lower=True ) + + +def module_temperature_check(module_temperature, irradiance, + correlation_min=0.5): + """Test whether the module temperature is correlated with irradiance. + + Parameters + ---------- + module_temperature : Series + Time series of module temperature. + irradiance : Series + Time series of irradiance with the same index as + `module_temperature`. This should be of relatively high + quality (outliers and other problems removed). + correlation_min : float, default 0.5 + Minimum correlation between `module_temperature` and + `irradiance` for the module temperature sensor to 'pass' + + Returns + ------- + bool + True if the correlation between `module_temperature` and + `irradiance` exceeds `correlation_min`. + + """ + _, _, r, _, _ = stats.linregress(module_temperature, irradiance) + return r > correlation_min diff --git a/pvanalytics/tests/quality/test_weather.py b/pvanalytics/tests/quality/test_weather.py index c2807e30..a32138e4 100644 --- a/pvanalytics/tests/quality/test_weather.py +++ b/pvanalytics/tests/quality/test_weather.py @@ -2,6 +2,7 @@ import pytest import pandas as pd import numpy as np +from pvlib import location from pandas.util.testing import assert_series_equal from pvanalytics.quality import weather @@ -87,3 +88,23 @@ def test_wind_limits(weather_data): weather_data['extreme_wind_flag'], check_names=False ) + + +def test_module_temperature(): + """Module temperature is correlated with GHI.""" + albuquerque = location.Location( + 35.0844, -106.6504, altitude=5312, tz='MST' + ) + times = pd.date_range( + start='01/01/2020', + end='03/01/2020', + freq='H', + tz='MST' + ) + clearsky = albuquerque.get_clearsky(times, model='simplified_solis') + assert weather.module_temperature_check( + clearsky['ghi']*0.6, clearsky['ghi'] + ) + assert not weather.module_temperature_check( + clearsky['ghi']*(-0.6), clearsky['ghi'] + )