Skip to content

Commit

Permalink
Merge pull request #375 from NREL/hour_angle_filter
Browse files Browse the repository at this point in the history
Hour angle filter
  • Loading branch information
mdeceglie authored May 26, 2023
2 parents aa4af78 + 13d0f9b commit 20bc73c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
20 changes: 16 additions & 4 deletions rdtools/analysis_chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ def _calc_clearsky_poa(self, times=None, rescale=True, **kwargs):
freq='1min')
aggregate = True

if self.pvlib_location is None:
if not hasattr(self, 'pvlib_location'):
raise ValueError(
'pvlib location must be provided using set_clearsky()')
if self.pv_tilt is None or self.pv_azimuth is None:
if not hasattr(self, 'pv_tilt') or not hasattr(self, 'pv_azimuth'):
raise ValueError(
'pv_tilt and pv_azimuth must be provided using set_clearsky()')

Expand Down Expand Up @@ -332,9 +332,9 @@ def _calc_clearsky_tamb(self):
Calculate clear-sky ambient temperature and store in self.temperature_ambient_clearsky
'''
times = self.poa_global_clearsky.index
if self.pvlib_location is None:
if not hasattr(self, 'pvlib_location'):
raise ValueError(
'pvlib location must be provided using set_clearsky()')
'pvlib_location must be provided using set_clearsky()')
loc = self.pvlib_location

cs_amb_temp = clearsky_temperature.get_clearsky_tamb(
Expand Down Expand Up @@ -464,6 +464,18 @@ def _call_clearsky_filter(filter_string):
f = filtering.clip_filter(
self.pv_power, **self.filter_params['clip_filter'])
filter_components['clip_filter'] = f
if 'hour_angle_filter' in self.filter_params:
if not hasattr(self, 'pvlib_location'):
raise ValueError(
'The pvlib location must be provided using set_clearsky() '
'or by directly setting TrendAnalysis.pvlib_location '
'in order to use the hour_angle_filter')
loc = self.pvlib_location
f = filtering.hour_angle_filter(
energy_normalized, loc.latitude, loc.longitude,
**self.filter_params['hour_angle_filter'])
filter_components['hour_angle_filter'] = f

if case == 'clearsky':
filter_components['pvlib_clearsky_filter'] = _call_clearsky_filter('pvlib_clearsky_filter')
if 'sensor_pvlib_clearsky_filter' in self.filter_params:
Expand Down
15 changes: 15 additions & 0 deletions rdtools/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,3 +948,18 @@ def directional_tukey_filter(series, roll_period=pd.to_timedelta('7 Days'), k=1.
((backward_dif > backward_dif_lower) & (backward_dif < backward_dif_upper))
)
return mask


def hour_angle_filter(series, lat, lon, min_hour_angle=-30, max_hour_angle=30):
'''
Creates a filter based on the hour angle of the sun (15 degrees per hour)
'''

times = series.index
spa = pvlib.solarposition.get_solarposition(times, lat, lon)
eot = spa['equation_of_time']
hour_angle = pvlib.solarposition.hour_angle(times, lon, eot)
hour_angle = pd.Series(hour_angle, index=times)
mask = (hour_angle >= min_hour_angle) & (hour_angle <= max_hour_angle)

return mask
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pvlib==0.9.0
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2019.3
arch==4.11
arch==5.5.0
filterpy==1.4.5
requests==2.25.1
retrying==1.3.3
Expand Down

0 comments on commit 20bc73c

Please sign in to comment.