def average_weather(latitude, precip, tair): ''' return average weather ''' func_name = __prog__ + '\taverage_weather' indx_start = 0 indx_end = len(precip) # use dict-comprehension to initialise precip. and tair dictionaries # ========================================================================= hist_precip = {mnth: 0.0 for mnth in MNTH_NAMES_SHORT} hist_tmean = {mnth: 0.0 for mnth in MNTH_NAMES_SHORT} for indx in range(indx_start, indx_end, 12): for imnth, month in enumerate(MNTH_NAMES_SHORT): hist_precip[month] += precip[indx + imnth] hist_tmean[month] += tair[indx + imnth] # write stanza for input.txt file consisting of long term average climate # ======================================================================= ave_precip = [] ave_tmean = [] num_years = len(precip) / 12 for month in MNTH_NAMES_SHORT: ave_precip.append(hist_precip[month] / num_years) ave_tmean.append(hist_tmean[month] / num_years) year = 2001 # not a leap year pet = thornthwaite(ave_tmean, latitude, year) return ave_precip, ave_tmean, pet
def spei_pearson(precip_monthly_values, temp_monthly_values, month_scale, latitude, valid_min, valid_max, data_start_year, data_end_year, calibration_start_year, calibration_end_year): # compute the PET values using Thornthwaite's equation pet_monthly_values = thornthwaite(temp_monthly_values, latitude, data_start_year, np.nan) # offset we add to the (P - PE values) in order to bring all values into the positive range p_minus_pe_offset = 1000.0 # get the difference of P - PE, assign the values into the temperature array (in order to reuse the memory) p_minus_pe = (precip_monthly_values - pet_monthly_values) + p_minus_pe_offset # perform the SPEI computation (fit to the Pearson distribution) and assign the values into the dataset return distribution_fitter.fit_to_pearson(p_minus_pe, month_scale, valid_min, valid_max, data_start_year, data_end_year, calibration_start_year, calibration_end_year)
def calc_potential_evapotrans_fr(self): """calculate potential evapotransportation for forward runs""" thornthwaite_ten_years_fr = [] for column in fr_air_temp_data: year_temps = fr_air_temp_data[column].to_list() thornthwaite_year = thornthwaite(year_temps, farm_lat) thornthwaite_ten_years_fr.append(thornthwaite_year) return thornthwaite_ten_years_fr
def calc_potential_evapotrans_ss(self): """calculate potential evapotransportation for steady state and forward runs""" thornthwaite_ten_years_ss = [] for column in ss_air_temp_data: year_temps = ss_air_temp_data[column].to_list() thornthwaite_year = thornthwaite(year_temps, farm_lat) thornthwaite_ten_years_ss.append(thornthwaite_year) return thornthwaite_ten_years_ss
def calculate_et_t(df_single_station_temp_in: pd.DataFrame, lat_deg: float, year: int, grass_kc: list, station_in: str) -> list: """ Calculates et_t for a given station using the thornthwaite method imported from pyeto Requires daily temperature data filtered out of ghcn data, latitude in degrees, year, k_c data as a list per month, and string name :param df_single_station_temp_in: dataframe containing daily TMAX and daily TMIN :param lat_deg: latitude of the station :param year: year of the ghcn data :param grass_kc: list containing k_c data for each month :param station_in: name of the station as a string :return: none. appends result to a df """ lat_rad = convert.deg2rad(lat_deg) mmdlh = thornthwaite.monthly_mean_daylight_hours(lat_rad, year) month_mean_temp_list = [] month = 1 month_sum_min = [] month_sum_max = [] for index_local, row_local in df_single_station_temp_in.iterrows(): row_date = datetime.strptime(str(row_local["Date"]), "%Y%m%d") row_month = row_date.month if month == row_month: if row_local["Type"] == "TMIN": month_sum_min.append(int(row_local["Amount"])) elif row_local["Type"] == "TMAX": month_sum_max.append(int(row_local["Amount"])) elif row_month == month + 1: month_average = (np.mean(month_sum_max) + np.mean(month_sum_min)) / 2 month_mean_temp_list.append(month_average / 10 * grass_kc[row_month - 1] * scaling_factor / 4) month_sum_min = [] month_sum_max = [] month += 1 else: # cover the 12th month month_average = (np.mean(month_sum_max) + np.mean(month_sum_min)) / 2 month_mean_temp_list.append(month_average / 10 * grass_kc[row_month - 1] * scaling_factor / 4) try: pet2 = thornthwaite.thornthwaite(month_mean_temp_list, mmdlh, year) except ValueError as e: # necessary in case temperature data is missing months print(e) return [] et_t_list2 = [] for index_local, value in enumerate(pet2): et_t_list2.append(int(value)) print("list of et_t:", et_t_list2) print(f'Station {station_in} has complete temp data') dict_et_t = {"Station_ID": station_in} dict_et_t.update({a: b for a, b in zip([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], et_t_list2)}) list_et_t.append(dict_et_t) return et_t_list2
def add_pet_to_weather(latitude, pettmp_grid_cell): ''' feed monthly annual temperatures to Thornthwaite equations to estimate Potential Evapotranspiration [mm/month] ''' # initialise output var # ===================== nyears = int(len(pettmp_grid_cell['precip']) / 12) pettmp_reform = {} for metric in list(['precip', 'tair', 'pet']): pettmp_reform[metric] = [] precip = pettmp_grid_cell['precip'] # temper = pettmp_grid_cell['tair'] indx1 = 0 for year in range(nyears): indx2 = indx1 + 12 # precipitation and temperature precipitation = precip[indx1:indx2] # tmean = temper[indx1:indx2] # pet if max(tmean) > 0.0: pet = thornthwaite(tmean, latitude, year) else: pet = [0.0] * 12 mess = '*** Warning *** monthly temperatures are all below zero for latitude: {}'.format( latitude) print(mess) pettmp_reform['precip'] += precipitation pettmp_reform['tair'] += tmean pettmp_reform['pet'] += pet indx1 += 12 return pettmp_reform
def spei_spi_pearson_pet(precip_monthly_values, temp_monthly_values, month_scale, latitude, valid_min, valid_max, data_start_year, data_end_year, calibration_start_year, calibration_end_year): ''' This function computes PET, SPI and SPEI fitted to the Pearson Type III distribution. :param precip_monthly_values: an array of monthly total precipitation values, of the same size and shape as the input temperature array :param temp_monthly_values: an array of monthly average temperature values, of the same size and shape as the input precipitation array :param month_scale: the number of months over which the values should be scaled before computing the index :param latitude: the latitude, in degrees, of the location :param valid_min: valid minimum of the resulting SPI and SPEI values :param valid_max: valid maximum of the resulting SPI and SPEI values :param data_start_year: the initial year of the input datasets (assumes that the two inputs cover the same period) :param data_end_year: the final year of the input datasets (assumes that the two inputs cover the same period) :param calibration_start_year: the initial year of the calibration period :param calibration_end_year: the final year of the calibration period :return: an array of SPEI values, of the same size and shape as the input temperature and precipitation arrays :return: an array of SPI values, of the same size and shape as the input temperature and precipitation arrays :return: an array of PET values, of the same size and shape as the input temperature and precipitation arrays ''' # compute the SPI fitted to the Pearson Type III distribution spi = distribution_fitter.fit_to_pearson(precip_monthly_values, month_scale, valid_min, valid_max, data_start_year, data_end_year, calibration_start_year, calibration_end_year) # compute the PET values using Thornthwaite's equation pet = thornthwaite(temp_monthly_values, latitude, data_start_year, np.nan) # offset we add to the (P - PE values) in order to bring all values into the positive range p_minus_pe_offset = 1000.0 # get the difference of P - PE, assign the values into the temperature array (in order to reuse the memory) p_minus_pe = (precip_monthly_values - pet) + p_minus_pe_offset # perform the SPEI computation (fit to the Pearson distribution) and assign the values into the dataset spei = distribution_fitter.fit_to_pearson(p_minus_pe, month_scale, valid_min, valid_max, data_start_year, data_end_year, calibration_start_year, calibration_end_year) return spei, spi, pet
def test_thornthwaite(self): logger.info('Testing the PET calculation using Thornthwaite\'s equation') pet = thornthwaite.thornthwaite(self.fixture_data, self.latitude, 1895, self.fill_value) assert np.allclose(pet, self.fixture_results_pet, atol=0.001, rtol=0.000, equal_nan=True) == True, \ 'One or more of the results did not match within the specified tolerance'
output_dataset = initialize_dataset(output_file_base + variable_name + '.nc', temp_dataset, x_dim_name, y_dim_name, variable_name, variable_attributes, np.nan) # loop over the grid cells for x in range(temp_dataset.variables[x_dim_name].size): for y in range(temp_dataset.variables[y_dim_name].size): logger.info('Processing x/y {}/{}'.format(x, y)) # slice out the period of record for the x/y point temp_data = temp_dataset.variables[temp_var_name][:, x, y] # only process non-empty grid cells, i.e. the data array contains at least some non-NaN values if (isinstance(temp_data, np.ma.MaskedArray)) and temp_data.mask.all(): continue else: # we have some valid values to work with # compute the PET values using Thornthwaite's equation output_dataset.variables[variable_name][:, x, y] = \ thornthwaite(temp_data, temp_dataset.variables[y_dim_name][y], start_date.year, np.nan) except Exception, e: logger.error('Failed to complete', exc_info=True) raise