<jupyter_start><jupyter_text>How to calculate shear***<jupyter_code>import datetime
print('Last updated: {}'.format(datetime.date.today().strftime('%d %B, %Y')))<jupyter_output>Last updated: 18 July, 2019<jupyter_text>***  Outline: The brightwind library allows for shear to be calculated from wind speed measurements using either the power law or the logarithmic law, through the calculation of the shear exponent (alpha) or the roughness coefficient respectively. Alpha/roughness values can be calculated by average wind speed, time of day/month, direction sector or by individual timestamp. The calculated shear can then be applied to wind speed timeseries to scale the wind speeds from one height to another.This tutorial will cover:1. How to calculate average shear and use it to scale a wind speed timeseries.1. How to calculate shear by direction sector.1. How to calculate shear by time of day and month.1. How to calculate shear by individual timestamp.1. How to scale a wind speed timeseries using a predefined value of alpha/roughness.***  Step 1: Calculate average shear and scale a wind speed timeseriesThe average shear exponent can be calculated across an entire timeseries using the `Average` class in the brightwind library.- First, upload the relevant data, defining the anemometers data and heights of these anemometers.<jupyter_code>import brightwind as bw
import pprint

# load data as dataframe and apply cleaning (see previous tutorials for these.)
data = bw.load_csv(r'C:\Users\Stephen\Documents\Analysis\demo_data.csv')
data = bw.apply_cleaning(data, r'C:\Users\Stephen\Documents\Analysis\demo_cleaning_file.csv')

# Specify columns in data which contain the anemometer measurements from which to calculate shear
anemometers = data[['Spd80mN','Spd60mN','Spd40mN']]

# Specify the heights of these anemometers in a list
heights = [80, 60, 40]<jupyter_output>Cleaning applied. (Please remember to assign the cleaned returned DataFrame to a variable.)<jupyter_text>- To calculate average shear from the data contained in `anemometers` using the power law, type the following:<jupyter_code>avg_shear_by_power_law = bw.Shear.Average(anemometers, heights)<jupyter_output><empty_output><jupyter_text>- To calculate shear using the log law instead of the power law, simply add the argument `calc_method='log_law'`. This is an option for all shear calculations.<jupyter_code>avg_shear_by_log_law = bw.Shear.Average(anemometers, heights, calc_method='log_law')<jupyter_output><empty_output><jupyter_text>- This function returns an object, i.e. `avg_shear_by_power_law` or  `avg_shear_by_log_law`, which contains lots of information about the calculation that was carried out. - To view what information is available, such as a plot and the average alpha value, type the following and press 'Tab': ![image1](images/how_to_calculate_shear_1.png) - To show the average alpha calculated, type:<jupyter_code>avg_shear_by_power_law.alpha<jupyter_output><empty_output><jupyter_text>- To show the average roughness calculated, type:<jupyter_code>avg_shear_by_log_law.roughness<jupyter_output><empty_output><jupyter_text>- To show the plot, type:<jupyter_code>avg_shear_by_power_law.plot<jupyter_output><empty_output><jupyter_text>- Other useful information about the object can be obtained using `.info`. This is wrapped with the 'pretty print' library to make it more readable.<jupyter_code>pprint.pprint(avg_shear_by_log_law.info)<jupyter_output>{'input data': {'calculation_method': 'log_law',
                'input_wind_speeds': {'column_names': ['Spd80mN',
                                                       'Spd60mN',
                                                       'Spd40mN'],
                                      'heights(m)': [80, 60, 40],
                                      'min_spd(m/s)': 3}},
 'output data': {'concurrent_period_in_years': 1.511,
                 'roughness': 0.054854089027648524}}<jupyter_text>Once the alpha/roughness values have been calculated, they can be applied to a wind speed timeseries to scale the wind speeds from one height to another. - To scale the wind speed timeseries, i.e. `data['Spd80mN']`, from 80 m to 100 m height using the average alpha value previously calculated, use the `.apply()` function attached to the avg_shear_by_power_law object.<jupyter_code># .head(10) is simply used to not display so much data
avg_shear_by_power_law.apply(data['Spd80mN'], 80, 100).head(10)<jupyter_output><empty_output><jupyter_text>- To scale the same data, but using the roughness value calculated via the log law, use the `.apply()` function attached to the `avg_shear_by_log_law` object:<jupyter_code>avg_shear_by_log_law.apply(data['Spd80mN'], 80, 100).head(10)<jupyter_output><empty_output><jupyter_text>- This sheared up wind speed timeseries can also be assigned to a new variable in your DataFrame.<jupyter_code>data['Spd100m'] = avg_shear_by_power_law.apply(data['Spd80mN'], 80, 100)
data.Spd100m.head(10)<jupyter_output><empty_output><jupyter_text>It is also possible to plot the two shear profiles using both calculation methods overlaid on each other using the argument `plot_both`. In addition, the profiles can be extended up to any height using `max_plot_height`. The apply function will only apply the resulting shear based on the `calc_method` specified, in this case 'power_law'.<jupyter_code>avg_shear_by_power_law = bw.Shear.Average(anemometers, heights, plot_both=True, 
                                          max_plot_height=120)<jupyter_output><empty_output><jupyter_text>***  Step 2: Calculate shear by direction sectorIf you have direction measurements to accompany wind speed measurements, the shear can be calculated for specified direction sectors using the `BySector` class. - To calculate the shear by direction sector, simply type:<jupyter_code>shear_by_sector_power_law = bw.Shear.BySector(anemometers, heights, data['Dir78mS'])<jupyter_output><empty_output><jupyter_text>- Again, various information such as the alpha values can be displayed from this object:<jupyter_code>shear_by_sector_power_law.alpha<jupyter_output><empty_output><jupyter_text>- The direction bins can be defined by the user for use in the BySector calculations. - These bins must begin at 0, be listed as increasing and advise they are even sizes.- For example, to use the custom bins [0,30,60,90,120,150,180,210,240,270,300,330,360], simply type the following:<jupyter_code>custom_bins = [0,30,60,90,120,150,180,210,240,270,300,330,360]
shear_by_sector_power_law_custom_bins = bw.Shear.BySector(anemometers, heights, data['Dir78mS'], 
                                                          direction_bin_array=custom_bins)
shear_by_sector_power_law.alpha<jupyter_output><empty_output><jupyter_text>To scale the same data, but using the alpha values calculated for each direction section use the `.apply()` function attached to the `shear_by_sector_by_power_law` object. Corresponding wind direction measurements for the wind speeds to be scaled must also be passed to the function.- Using `data['Dir78mS']` as the direction measurements, type:<jupyter_code>shear_by_sector_power_law.apply(data['Spd80mN'], data['Dir78mS'], 80, 100).head(10)<jupyter_output><empty_output><jupyter_text>***  Step 3: Calculate shear by time of day and monthShear can also be calculated by time of day and month using the `TimeOfDay` class. To do so, type:<jupyter_code>shear_by_tod_power_law = bw.Shear.TimeOfDay(anemometers, heights, segments_per_day=24, 
                                            plot_type='line')<jupyter_output><empty_output><jupyter_text>- The alpha values calculated are saved in a DataFrame and can be accessed using `.alpha()`:<jupyter_code>shear_by_tod_power_law.alpha<jupyter_output><empty_output><jupyter_text>- Arguments such as `segments_per_day` and `segement_start_time` can be set to specify the number of time period segments in a day and the start time of the first segment. Different plot types are also available, such as `'step'` and `'12x24'`, shown below.<jupyter_code>shear_by_tod_power_law = bw.Shear.TimeOfDay(anemometers, heights, segments_per_day=2,
                                            segment_start_time=7, plot_type='step')
shear_by_tod_power_law = bw.Shear.TimeOfDay(anemometers, heights, segments_per_day=24, 
                                            segment_start_time=7, plot_type='12x24')<jupyter_output><empty_output><jupyter_text>- By setting `by_month=False`, shear is averaged over all months for each daily segment:<jupyter_code>shear_by_tod_power_law = bw.Shear.TimeOfDay(anemometers, heights, segments_per_day=24,
                                            segment_start_time=7, by_month=False, 
                                            plot_type='line')<jupyter_output><empty_output><jupyter_text>- To apply the shear values calculated, as previously:<jupyter_code>shear_by_tod_power_law.apply(data['Spd80mN'],80,100).head(10)<jupyter_output><empty_output><jupyter_text>***  Step 4: Calculating shear by timestampShear can be calculated for each individual timestamp of a wind speed data series using the `TimeSeries` class. This takes some time, as tens of thousands of calculations must be carried out, so try it first on a subset of the data, i.e. the first 1000 entries. To do so, type:<jupyter_code>anemometers_subset = anemometers[:1000]
ts_by_power_law = bw.Shear.TimeSeries(anemometers_subset, heights)<jupyter_output><empty_output><jupyter_text>In other methods such as `Average` and `BySector`, shear is only calculated for each timestamp where an anemometer reading exists at each height. This can be problamatic when calculating shear by individual timestamps. To maximise the ammount of data used for shear calculations and increase coverage we can calculate shear for every timestamp where two or more anemometer readings exist. If you wish to do this, pass the `maximise_data=True` argument to the function. Please be aware that due to the nature of calculating shear for every timestamp, this function takes some time to run.<jupyter_code>ts_by_power_law_max = bw.Shear.TimeSeries(anemometers_subset, heights, maximise_data=True)<jupyter_output><empty_output><jupyter_text>- As can be seen in the `.info` of each object, the coverage increased when `maximise_data` was used.<jupyter_code>pprint.pprint(ts_by_power_law.info)
pprint.pprint(ts_by_power_law_max.info)<jupyter_output>{'input data': {'calculation_method': 'power_law',
                'input_wind_speeds': {'column_names': ['Spd80mN',
                                                       'Spd60mN',
                                                       'Spd40mN'],
                                      'heights(m)': [80, 60, 40],
                                      'min_spd(m/s)': 3}},
 'output data': {'alpha': Timestamp
2016-01-09 17:10:00    0.237991
2016-01-09 17:20:00   -0.027865
2016-01-09 17:30:00    0.002393
2016-01-09 17:40:00    0.028834
2016-01-09 17:50:00   -0.028915
2016-01-09 18:00:00   -0.006296
2016-01-09 18:10:00    0.078150
2016-01-09 18:20:00   -0.019781
2016-01-09 18:30:00    0.150555
2016-01-09 18:40:00    0.080081
2016-01-09 18:50:00    0.078663
2016-01-09 19:00:00    0.007701
2016-01-09 19:10:00    0.060346
2016-01-09 19:20:00    0.049886
2016-01-09 19:30:00    0.001436
2016-01-09 19:40:00   -0.044120
2016-01-09 19:50:00    0.068740
2016-01-09 20:00:00    0.376291
2016-01-09 20[...]<jupyter_text>To apply the alpha values calculated to a wind series with corresponding timestamps:<jupyter_code>ts_by_power_law.apply(data['Spd80mN'], 80, 100).head(10)<jupyter_output><empty_output><jupyter_text>***  Step 4: Scale a wind speed timeseries using a predefined value of alpha/roughnessA wind speed timeseries can also be scaled using a user-defined fixed value for alpha or roughness.  - For example, to scale the wind speed measurements, `data['Spd80mN']`, from 80 m to 100 m, using an alpha value of 0.2, type:<jupyter_code>bw.Shear.scale(data['Spd80mN'], 80, 100, alpha=0.2).head(10)<jupyter_output><empty_output><jupyter_text>- To scale the wind speed measurements, `data['Spd80mN']`, from 80 m to 100 m, using a roughness of 0.3, type:<jupyter_code>bw.Shear.scale(data['Spd80mN'], 80, 100, roughness=0.3, calc_method='log_law').head(10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08949163553678739, 'fraction_numerical': 0.05538411564073412, 'mean_word_length': 4.437086092715232, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '188865', 'license': 'MIT', 'n_tokens_mistral': 4351, 'n_tokens_neox': 3764, 'n_words': 1195, 'path': 'docs/source/tutorials/how_to_calculate_shear.ipynb', 'repo_name': 'altosphere/brightwind', 'size': '12314'}