def runOrovannEB(startDate, endDate): location_name = "Otrøvatnet v/Nystuen 971 moh" wsTemp = gws.getMetData(54710, "TAM", startDate, endDate, 0, "list") wsSno = gws.getMetData(54710, "SA", startDate, endDate, 0, "list") wsPrec = gws.getMetData(54710, "RR", startDate, endDate, 0, "list") utm33_y = 6802070 utm33_x = 130513 temp, date = we.strip_metadata(wsTemp, get_dates=True) sno_tot = we.strip_metadata(wsSno) prec_snow = dp.delta_snow_from_total_snow(sno_tot) prec = we.strip_metadata(wsPrec) cloud_cover = dp.clouds_from_precipitation(prec) wind = [const.avg_wind_const] * len(date) rel_hum = [const.rel_hum_air] * len(date) pressure_atm = [const.pressure_atm] * len(date) # available_elements = gws.getElementsFromTimeserieTypeStation(54710, 0, 'csv') observed_ice = gro.get_all_season_ice(location_name, startDate, endDate) ice_cover, energy_balance = calculate_ice_cover_eb( utm33_x, utm33_y, date, temp, prec, prec_snow, cloud_cover, wind, rel_hum=rel_hum, pressure_atm=pressure_atm, inn_column=copy.deepcopy(observed_ice[0]), ) # Need datetime objects from now on from_date = dt.datetime.strptime(startDate, "%Y-%m-%d") to_date = dt.datetime.strptime(endDate, "%Y-%m-%d") plot_filename = "{0}Ortovann MET EB {1}-{2}.png".format(plot_folder, from_date.year, to_date.year) # pts.plot_ice_cover(ice_cover, observed_ice, date, temp, sno_tot, plot_filename) plot_filename = "{0}Ortovann MET with EB {1}-{2}.png".format(plot_folder, from_date.year, to_date.year) pts.plot_ice_cover_eb( ice_cover, energy_balance, observed_ice, date, temp, sno_tot, plot_filename, prec=prec, wind=wind, clouds=cloud_cover, )
def cc_gamma_prec_and_temp_change(*args): if len(args) == 2: ccPrec = pz.clouds_from_precipitation(args[0], method='Binary') ccPrec = cc_gamma_smoothing(ccPrec) ccTemp = cc_gamma_temp(args[1]) elif len(args) == 4: ccPrec = pz.clouds_from_precipitation(args[0], method='Binary') ccPrec = cc_gamma_smoothing(ccPrec, args[2]) ccTemp = cc_gamma_temp(args[1], args[3]) else: print("Wrong input. Method takes 2 or 4 arguments.") cc = [] for i in range(0, len(ccPrec), 1): cc.append(ccPrec[i] + ccTemp[i]) if cc[i] > 1.: cc[i] = 1. return cc
def cc_gamma_prec_and_temp_change(*args): if len(args) == 2: ccPrec = pz.clouds_from_precipitation(args[0], method='Binary') ccPrec = cc_gamma_smoothing(ccPrec) ccTemp = cc_gamma_temp(args[1]) elif len(args) == 4: ccPrec = pz.clouds_from_precipitation(args[0], method='Binary') ccPrec = cc_gamma_smoothing(ccPrec, args[2]) ccTemp = cc_gamma_temp(args[1], args[3]) else: print("Wrong resources. Method takes 2 or 4 arguments.") cc = [] for i in range(0, len(ccPrec), 1): cc.append(ccPrec[i] + ccTemp[i]) if cc[i] > 1.: cc[i] = 1. return cc
def runOrovannEB(startDate, endDate): location_name = 'Otrøvatnet v/Nystuen 971 moh' wsTemp = gws.getMetData(54710, 'TAM', startDate, endDate, 0, 'list') wsSno = gws.getMetData(54710, 'SA', startDate, endDate, 0, 'list') wsPrec = gws.getMetData(54710, 'RR', startDate, endDate, 0, 'list') utm33_y = 6802070 utm33_x = 130513 temp, date = we.strip_metadata(wsTemp, get_dates=True) sno_tot = we.strip_metadata(wsSno) prec_snow = dp.delta_snow_from_total_snow(sno_tot) prec = we.strip_metadata(wsPrec) cloud_cover = dp.clouds_from_precipitation(prec) wind = [const.avg_wind_const] * len(date) rel_hum = [const.rel_hum_air] * len(date) pressure_atm = [const.pressure_atm] * len(date) # available_elements = gws.getElementsFromTimeserieTypeStation(54710, 0, 'csv') observed_ice = gro.get_all_season_ice(location_name, startDate, endDate) ice_cover, energy_balance = calculate_ice_cover_eb( utm33_x, utm33_y, date, temp, prec, prec_snow, cloud_cover, wind, rel_hum=rel_hum, pressure_atm=pressure_atm, inn_column=copy.deepcopy(observed_ice[0])) # Need datetime objects from now on from_date = dt.datetime.strptime(startDate, "%Y-%m-%d") to_date = dt.datetime.strptime(endDate, "%Y-%m-%d") plot_filename = '{0}Ortovann MET EB {1}-{2}.png'.format(plot_folder, from_date.year, to_date.year) # pts.plot_ice_cover(ice_cover, observed_ice, date, temp, sno_tot, plot_filename) plot_filename = '{0}Ortovann MET with EB {1}-{2}.png'.format(plot_folder, from_date.year, to_date.year) pts.plot_ice_cover_eb(ice_cover, energy_balance, observed_ice, date, temp, sno_tot, plot_filename, prec=prec, wind=wind, clouds=cloud_cover)
def energy_balance_from_temp_sfc( utm33_x, utm33_y, ice_column, temp_atm, prec, prec_snow, albedo_prim, time_span_in_sec, temp_surface, age_factor_tau=None, cloud_cover=None, wind=None, rel_hum=None, pressure_atm=None): """Given surface temperature, the daily energy budget of a column of snow is expressed as: EB = S + (L_a - L_t) + (LE + H) + G + R - CC - SC TODO: Need to implement shortwave attenuation in the column top layers. Use q_s(z,t) in eq 10 in Yang et al (2012) Mandatory :param utm33_x: :param utm33_y: :param ice_column: :param temp_atm: :param prec: :param prec_snow: :param albedo_prim: :param time_span_in_sec: :param temp_surface: Optional :param age_factor_tau: :param cloud_cover: :param wind: :param pressure_atm: :return: For reference: 1 kWh is 3600 kJ. 10 000 kJ can melt 30kg ice or (3cm/m2 ice). 300 W/m2 is on avarage approx 26000kJ/m2/24hrs """ date = ice_column.date day_no = ice_column.date.timetuple().tm_yday # time given as the end of the time span time_hour = (ice_column.date + dt.timedelta(seconds=time_span_in_sec)).hour # Variables picked out from ice_column is_ice = True snow_depth = 0. snow_density = const.rho_snow if len(ice_column.column) == 0: is_ice = False # albedo_prim = 0.10 # no ice, water absobs much of the short wave else: if ice_column.column[0].type == "snow": snow_density = ice_column.column[0].density snow_depth = ice_column.column[0].height if ice_column.column[0].type == "black_ice": albedo_prim = const.alfa_black_ice if ice_column.column[0].type == "slush_ice": albedo_prim = const.alfa_slush_ice # Calculate some parameters if cloud_cover is None: cloud_cover = dp.clouds_from_precipitation(prec, method=defaults.default_cloud_cover_method) # This scenario should be avoided but I keep it for now because it it the method used in senorge_eb #if temp_surface is None: # temp_surface = ice_column.get_surface_temperature_estimate(temp_atm) # Define an energy balance object to put inn all input data. energy_balance = ebe(date) energy_balance.add_model_input( utm33_x_inn=utm33_x, utm33_y_inn=utm33_y, snow_depth_inn=snow_depth, snow_density_inn=snow_density, temp_surface_inn=temp_surface, is_ice_inn=is_ice, temp_atm_inn=temp_atm, prec_inn=prec, prec_snow_inn=prec_snow, cloud_cover_inn=cloud_cover, age_factor_tau_inn=age_factor_tau, albedo_prim_inn=albedo_prim, day_no_inn=day_no, time_hour_inn=time_hour, time_span_in_sec_inn=time_span_in_sec) # Calculate the energy balance terms S, s_inn, albedo, albedo_prim, age_factor_tau = get_short_wave( utm33_x, utm33_y, day_no, temp_atm, cloud_cover, snow_depth, snow_density, prec_snow, time_hour, time_span_in_sec, temp_surface, albedo_prim, age_factor_tau=age_factor_tau, albedo_method=defaults.default_albedo_method) L_a, L_t = get_long_wave(cloud_cover, temp_atm, temp_surface, snow_depth, is_ice, time_span_in_sec) H, LE, R_i, stability_correction = get_turbulent_flux( temp_atm, temp_surface, time_span_in_sec, ice_column, pressure_atm=pressure_atm, wind=wind, rel_hum=rel_hum) G = get_ground_heat(time_span_in_sec) R = get_prec_heat(temp_atm, prec) CC = get_cold_content_change(ice_column, temp_surface) SC, conductance = get_surface_heat_conduction(ice_column, temp_surface, time_span_in_sec) EB = S + (L_a + L_t) + (LE + H) + G + R + (CC + SC) energy_balance.add_short_wave(S, s_inn, albedo, albedo_prim, age_factor_tau) energy_balance.add_long_wave(L_a, L_t) energy_balance.add_sensible_and_latent_heat(H, LE, R_i, stability_correction) energy_balance.add_ground_heat(G) energy_balance.add_prec_heat(R) energy_balance.add_cold_content(CC) energy_balance.add_surface_heat_conduction(SC, conductance) energy_balance.add_energy_budget(EB) return energy_balance
def testCloudMaker(stnr, startDate, endDate, method): """Gets data from a eKlima station and smooths the data depending on which method we wish to test. We find the nash-sutcliffe to observations of clouds. And we plot and save the result to Plots folder. :param stnr: eKlima station where there is cloud cover for testing method. :param startDate: simulations and reference data from this data :param endDate: simulations and reference data to this data :param method: specify which method to be tested :return: Available methods to test: cc_from_prec ccFromAveragePrec ccFromAverageObsCc ccGammaPrec ccGammaTemp ccGammaPrecAndTemp""" wsTemp = getMetData(stnr, 'TAM', startDate, endDate, 0, 'list') wsPrec = getMetData(stnr, 'RR', startDate, endDate, 0, 'list') wsCC = getMetData(stnr, 'NNM', startDate, endDate, 0, 'list') temp, date = strip_metadata(wsTemp, get_dates=True) prec = strip_metadata(wsPrec) clouds = strip_metadata(wsCC) dayShift = 1 clouds = __shiftClouds(clouds, dayShift) if method == 'ccFromRandomThomas': estClouds = dpz.clouds_from_precipitation(prec, method='Random Thomas') gammaFigtext = 'No gamma smoothing and dayshift = {0}'.format(dayShift) elif method == 'ccFromPrec': estClouds = dpz.clouds_from_precipitation(prec, method='Binary') gammaFigtext = 'No gamma smoothing and dayshift = {0}'.format(dayShift) elif method == 'ccFromAveragePrec': estClouds = dpz.clouds_from_precipitation(prec, method='Average') gammaFigtext = 'No gamma smoothing and dayshift = {0}'.format(dayShift) elif method == 'ccFromPrecAndAveragePrec': estClouds = dpz.clouds_from_precipitation(prec, method='Binary and average') gammaFigtext = ''.format() elif method == 'ccFromAverageObsCc': estClouds = [sum(clouds)/float(len(clouds))] * len(clouds) gammaFigtext = ''.format() elif method == 'ccGammaPrec': gammaPrec = [2.8, 2., 0.3, 0.4] estClouds = dpz.clouds_from_precipitation(prec, method='Binary') estClouds = dgc.cc_gamma_smoothing(estClouds, gammaPrec) gammaFigtext = "gamma smoothing prec = {0} and dayshift = {1}".format(gammaPrec, dayShift) elif method == 'ccGammaTempChange': gammaTemp = [4.8, 1., 5., 0.03] estClouds = dgc.cc_gamma_temp(temp, gammaTemp) gammaFigtext = "gamma smoothing temp = {0} and dayshift = {1}".format(gammaTemp, dayShift) elif method == 'ccGammaPrecAndTempChange': gammaPrec = [2.8, 2., 0.3, 0.4] gammaTemp = [4.8, 1., 5., 0.03] estClouds = dgc.cc_gamma_prec_and_temp_change(prec, temp, gammaPrec, gammaTemp) gammaFigtext = "prec = {0} and temp = {1} and dayshift = {2}".format(gammaPrec, gammaTemp, dayShift) fileName = "{3} {0} {1} {2}.png".format(stnr, startDate[0:7], endDate[0:7], method) # What is the root mean square of estimatet vs observed clouds? # rms = np.sqrt(((np.array(estClouds) - np.array(clouds)) ** 2).mean()) # Nash–Sutcliffe model efficiency coefficient from # https://en.wikipedia.org/wiki/Nash%E2%80%93Sutcliffe_model_efficiency_coefficient numerator = 0 denominator = 0 mean_clouds = sum(clouds)/float(len(clouds)) for i in range(0, len(clouds), 1): numerator += (clouds[i] - estClouds[i])**2 denominator += (clouds[i] - mean_clouds)**2 nash_sutcliffe = 1 - numerator/denominator # Figure dimensions fsize = (16, 10) plt.figure(figsize=fsize) plt.clf() # plot total snowdepth on land plt.bar(date, prec, width=1, color="0.4") # plot the estimated cloud cover for i in range(0, len(estClouds) - 1, 1): if estClouds[i] > 0: plt.hlines(max(prec) * 1.2, date[i], date[i + 1], lw=45, color=str(-(estClouds[i] - 1.))) elif estClouds[i] == None: plt.hlines(max(prec) * 1.2, date[i], date[i + 1], lw=45, color="pink") else: plt.hlines(max(prec) * 1.2, date[i], date[i + 1], lw=45, color=str(-(estClouds[i] - 1.))) # plot cloud cover from met for i in range(0, len(clouds) - 1, 1): if clouds[i] > 0: plt.hlines(max(prec) * 1.1, date[i], date[i + 1], lw=45, color=str(-(clouds[i] - 1.))) elif clouds[i] == None: plt.hlines(max(prec) * 1.1, date[i], date[i + 1], lw=45, color="pink") else: plt.hlines(max(prec) * 1.1, date[i], date[i + 1], lw=45, color=str(-(clouds[i] - 1.))) # this plots temperature on separate right side axis plt.twinx() temp_pluss = [] temp_minus = [] for i in range(0, len(temp), 1): if temp[i] >= 0: temp_pluss.append(temp[i]) temp_minus.append(np.nan) else: temp_minus.append(temp[i]) temp_pluss.append(np.nan) plt.plot(date, temp, "black") plt.plot(date, temp_pluss, "red") plt.plot(date, temp_minus, "blue") # title and text fields plt.title("{3} {0} {1} {2}".format(stnr, startDate[0:7], endDate[0:7], method)) plt.text(date[len(date)/2], min(temp)*1.2, 'gamma smoothing [shape, scale, days back, amplification]') plt.text(date[len(date)/2], min(temp)*1.3, gammaFigtext) # this is a scatter plot of modelled and estimated cloud cover xfrac = 0.15 yfrac = (float(fsize[0])/float(fsize[1])) * xfrac xpos = 0.95-xfrac ypos = 0.42-yfrac a = plt.axes([xpos, ypos, xfrac, yfrac]) a.scatter(clouds, estClouds) plt.setp(a, xticks=[0, 0.5, 1], yticks=[0, 0.5, 1]) plt.text(0.0, 0.1, 'na_su = {0}'.format(round(nash_sutcliffe, 2)), color='yellow', bbox={'facecolor':'black'}) plt.savefig("{0}{1}".format(plot_folder, fileName)) return nash_sutcliffe
def energy_balance_from_temp_sfc(utm33_x, utm33_y, ice_column, temp_atm, prec, prec_snow, albedo_prim, time_span_in_sec, temp_surface, age_factor_tau=None, cloud_cover=None, wind=None, rel_hum=None, pressure_atm=None): """Given surface temperature, the daily energy budget of a column of snow is expressed as: EB = S + (L_a - L_t) + (LE + H) + G + R - CC - SC TODO: Need to implement shortwave attenuation in the column top layers. Use q_s(z,t) in eq 10 in Yang et al (2012) Mandatory :param utm33_x: :param utm33_y: :param ice_column: :param temp_atm: :param prec: :param prec_snow: :param albedo_prim: :param time_span_in_sec: :param temp_surface: Optional :param age_factor_tau: :param cloud_cover: :param wind: :param pressure_atm: :return: For reference: 1 kWh is 3600 kJ. 10 000 kJ can melt 30kg ice or (3cm/m2 ice). 300 W/m2 is on avarage approx 26000kJ/m2/24hrs """ date = ice_column.date day_no = ice_column.date.timetuple().tm_yday # time given as the end of the time span time_hour = (ice_column.date + dt.timedelta(seconds=time_span_in_sec)).hour # Variables picked out from ice_column is_ice = True snow_depth = 0. snow_density = const.rho_snow if len(ice_column.column) == 0: is_ice = False # albedo_prim = 0.10 # no ice, water absobs much of the short wave else: if ice_column.column[0].type == "snow": snow_density = ice_column.column[0].density snow_depth = ice_column.column[0].height if ice_column.column[0].type == "black_ice": albedo_prim = const.alfa_black_ice if ice_column.column[0].type == "slush_ice": albedo_prim = const.alfa_slush_ice # Calculate some parameters if cloud_cover is None: cloud_cover = dp.clouds_from_precipitation( prec, method=defaults.default_cloud_cover_method) # This scenario should be avoided but I keep it for now because it it the method used in senorge_eb #if temp_surface is None: # temp_surface = ice_column.get_surface_temperature_estimate(temp_atm) # Define an energy balance object to put inn all input data. energy_balance = ebe(date) energy_balance.add_model_input(utm33_x_inn=utm33_x, utm33_y_inn=utm33_y, snow_depth_inn=snow_depth, snow_density_inn=snow_density, temp_surface_inn=temp_surface, is_ice_inn=is_ice, temp_atm_inn=temp_atm, prec_inn=prec, prec_snow_inn=prec_snow, cloud_cover_inn=cloud_cover, age_factor_tau_inn=age_factor_tau, albedo_prim_inn=albedo_prim, day_no_inn=day_no, time_hour_inn=time_hour, time_span_in_sec_inn=time_span_in_sec) # Calculate the energy balance terms S, s_inn, albedo, albedo_prim, age_factor_tau = get_short_wave( utm33_x, utm33_y, day_no, temp_atm, cloud_cover, snow_depth, snow_density, prec_snow, time_hour, time_span_in_sec, temp_surface, albedo_prim, age_factor_tau=age_factor_tau, albedo_method=defaults.default_albedo_method) L_a, L_t = get_long_wave(cloud_cover, temp_atm, temp_surface, snow_depth, is_ice, time_span_in_sec) H, LE, R_i, stability_correction = get_turbulent_flux( temp_atm, temp_surface, time_span_in_sec, ice_column, pressure_atm=pressure_atm, wind=wind, rel_hum=rel_hum) G = get_ground_heat(time_span_in_sec) R = get_prec_heat(temp_atm, prec) CC = get_cold_content_change(ice_column, temp_surface) SC, conductance = get_surface_heat_conduction(ice_column, temp_surface, time_span_in_sec) EB = S + (L_a + L_t) + (LE + H) + G + R + (CC + SC) energy_balance.add_short_wave(S, s_inn, albedo, albedo_prim, age_factor_tau) energy_balance.add_long_wave(L_a, L_t) energy_balance.add_sensible_and_latent_heat(H, LE, R_i, stability_correction) energy_balance.add_ground_heat(G) energy_balance.add_prec_heat(R) energy_balance.add_cold_content(CC) energy_balance.add_surface_heat_conduction(SC, conductance) energy_balance.add_energy_budget(EB) return energy_balance