-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from NREL/combined_update
Combine update
- Loading branch information
Showing
12 changed files
with
618 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ | |
.DS_Store | ||
|
||
docs/.ipynb_checkpoints/degradation_example-checkpoint.ipynb | ||
*.ipynb_checkpoints* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
include versioneer.py | ||
include rdtools/_version.py | ||
include rdtools/data/* |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import h5py | ||
from numpy import arange | ||
from datetime import timedelta | ||
import math | ||
import pandas as pd | ||
import pkg_resources | ||
import numpy as np | ||
|
||
|
||
def get_clearsky_tamb(times, latitude, longitude, window_size=40, gauss_std=20): | ||
''' | ||
:param times: DateTimeIndex in local time | ||
:param latitude: float degrees | ||
:param longitude: float degrees | ||
:return: pandas Series of cell sky ambient temperature | ||
''' | ||
|
||
filepath = pkg_resources.resource_filename('rdtools', 'data/temperature.hdf5') | ||
|
||
buffer = timedelta(days=window_size) | ||
freq_actual = pd.infer_freq(times) | ||
dt_daily = pd.date_range(times[0] - buffer, times[-1] + buffer, freq='D') | ||
|
||
f = h5py.File(filepath, "r") | ||
|
||
a = f['temperature']['day'] | ||
b = f['temperature']['night'] | ||
|
||
lons = len(a[:, 0, 0]) | ||
lats = len(a[0, :, 0]) | ||
|
||
lon_temp = longitude - 180 | ||
if lon_temp < 0: | ||
lon_temp += 360 | ||
lon_index = round(float(lons) * float(lon_temp) / 360.0) | ||
lat_index = round(float(lats) * (90.0 - float(latitude)) / 180.0) | ||
|
||
df = pd.DataFrame(index=dt_daily) | ||
df['month'] = df.index.month | ||
|
||
ave_day = [] | ||
ave_night = [] | ||
|
||
radius = 0 | ||
for k in range(12): | ||
|
||
day = _get_pixel_value(a, lon_index, lat_index, k, radius) | ||
night = _get_pixel_value(b, lon_index, lat_index, k, radius) | ||
|
||
if day == float("NaN"): | ||
day = a[:, lat_index, k] | ||
if night == float("NaN"): | ||
night = a[:, lat_index, k] | ||
|
||
ave_day.append(day) | ||
ave_night.append(night) | ||
|
||
for i in range(12): | ||
df.loc[df['month'] == i + 1, 'day'] = ave_day[i] | ||
df.loc[df['month'] == i + 1, 'night'] = ave_night[i] | ||
|
||
df = df.rolling(window=window_size, win_type='gaussian', min_periods=1, center=True).mean(std=gauss_std) | ||
|
||
df = df.resample(freq_actual).interpolate(method='linear') | ||
df['month'] = df.index.month | ||
|
||
df = df.reindex(times, method='nearest') | ||
|
||
utc_offsets = [y.utcoffset().total_seconds() / 3600.0 for y in df.index] | ||
|
||
def solar_noon_offset(utc_offset): | ||
return longitude / 180.0 * 12.0 - utc_offset | ||
|
||
df['solar_noon_offset'] = solar_noon_offset(np.array(utc_offsets)) | ||
|
||
df['hour_of_day'] = df.index.hour + df.index.minute / 60.0 | ||
df['Clear Sky Temperature (C)'] = _get_temperature(df['hour_of_day'].values, df['night'].values,\ | ||
df['day'].values, df['solar_noon_offset'].values) | ||
return df['Clear Sky Temperature (C)'] | ||
|
||
|
||
def _get_pixel_value(data, i, j, k, radius): | ||
list = [] | ||
for x in arange(i - radius, i + radius + 1): | ||
if x < 0 or x >= len(data[:, 0, 0]): | ||
continue | ||
for y in arange(j - radius, j + radius + 1): | ||
if y < 0 or y >= len(data[0, :, 0]): | ||
continue | ||
|
||
value = data[x, y, k] | ||
if value == float("NaN"): | ||
continue | ||
|
||
list.append(value) | ||
|
||
if len(list) == 0: | ||
return float("NaN") | ||
|
||
return pd.Series(list).median() | ||
|
||
|
||
def _get_temperature(hour_of_day, night_temp, day_temp, solar_noon_offset): | ||
hour_offset = 8.0 + solar_noon_offset | ||
temp_scaler = 0.7 | ||
t_diff = day_temp - night_temp | ||
t_ave = (day_temp + night_temp) / 2.0 | ||
v = np.cos((hour_of_day + hour_offset) / 24.0 * 2.0 * np.pi) | ||
t = t_diff * 0.5 * v * temp_scaler + t_ave | ||
return t |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import pandas as pd | ||
|
||
|
||
def poa_filter(poa, low_irradiance_cutoff=200, high_irradiance_cutoff=1200): | ||
# simple filter based on irradiance sensors | ||
return (poa > low_irradiance_cutoff) & (poa < high_irradiance_cutoff) | ||
|
||
|
||
def tcell_filter(tcell, low_tcell_cutoff=-50, high_tcell_cutoff=110): | ||
# simple filter based on temperature sensors | ||
return (tcell > low_tcell_cutoff) & (tcell < high_tcell_cutoff) | ||
|
||
|
||
def clip_filter(power, quant=0.98, low_power_cutoff=0.01): | ||
''' | ||
Filter data points likely to be affected by clipping | ||
with power greater than or equal to 99% of the 'quant' | ||
quantile and less than 'low_power_cutoff' | ||
Parameters | ||
---------- | ||
power: Pandas series (numeric) | ||
AC power | ||
quant: float | ||
threshold for quantile | ||
low_power_cutoff | ||
Returns | ||
------- | ||
Pandas Series (boolean) | ||
mask to exclude points equal to and | ||
above 99% of the percentile threshold | ||
''' | ||
v = power.quantile(quant) | ||
return (power < v * 0.99) & (power > low_power_cutoff) | ||
|
||
|
||
def csi_filter(measured_poa, clearsky_poa, threshold=0.15): | ||
''' | ||
Filtering based on clear sky index (csi) | ||
Parameters | ||
---------- | ||
measured_poa: Pandas series (numeric) | ||
Plane of array irradiance based on measurments | ||
clearsky_poa: Pandas series (numeric) | ||
Plane of array irradiance based on a clear sky model | ||
threshold: float | ||
threshold for filter | ||
Returns | ||
------- | ||
Pandas Series (boolean) | ||
mask to exclude points below the threshold | ||
''' | ||
|
||
csi = measured_poa / clearsky_poa | ||
return (csi >= 1.0 - threshold) & (csi <= 1.0 + threshold) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
nose==1.3.7 | ||
numpy==1.11.2 | ||
pandas==0.19.1 | ||
pandas==0.19.2 | ||
patsy==0.4.1 | ||
pvlib==0.4.1 | ||
python-dateutil==2.6.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import unittest | ||
import pandas as pd | ||
from datetime import datetime | ||
|
||
from rdtools.clearsky_temperature import get_clearsky_tamb | ||
|
||
|
||
class ClearSkyTemperatureTestCase(unittest.TestCase): | ||
'''Unit tests for clearsky_temperature module''' | ||
|
||
def setUp(self): | ||
|
||
dt = pd.date_range(datetime(2015,1,1), datetime(2015,2,1), freq='15min', tz = 'Asia/Shanghai') | ||
|
||
self.china_west = get_clearsky_tamb(dt, 37.951721, 80.609843) | ||
self.china_east = get_clearsky_tamb(dt, 36.693692, 117.699686) | ||
|
||
#self.china_west.to_csv("west.csv") | ||
#self.china_east.to_csv("east.csv") | ||
|
||
|
||
# Test for shifting temperature peak with longitude for same timezone | ||
def test_hour_offset(self): | ||
|
||
df = pd.DataFrame(index = self.china_west.index) | ||
df['west'] = self.china_west | ||
df['east'] = self.china_east | ||
df['hour'] = df.index.hour | ||
|
||
west_hottest_hour = df.sort_values(by='west', ascending=False)['hour'].iloc[0] | ||
east_hottest_hour = df.sort_values(by='east', ascending=False)['hour'].iloc[0] | ||
|
||
#print west_hottest_hour , east_hottest_hour | ||
|
||
self.assertTrue(west_hottest_hour > 12) | ||
self.assertTrue(east_hottest_hour > 12) | ||
self.assertTrue(west_hottest_hour > east_hottest_hour) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters