def estimate_fao56_daily(self, day_of_year, temp_c, temp_c_min, temp_c_max, tdew, elevation, latitude, rh, wind_m_s, atmos_pres): """ Estimate fao56 from weather """ sha = pyeto.sunset_hour_angle(pyeto.deg2rad(latitude), pyeto.sol_dec(day_of_year)) daylight_hours = pyeto.daylight_hours(sha) sunshine_hours = 0.8 * daylight_hours ird = pyeto.inv_rel_dist_earth_sun(day_of_year) et_rad = pyeto.et_rad(pyeto.deg2rad(latitude), pyeto.sol_dec(day_of_year), sha, ird) sol_rad = pyeto.sol_rad_from_sun_hours(daylight_hours, sunshine_hours, et_rad) net_in_sol_rad = pyeto.net_in_sol_rad(sol_rad=sol_rad, albedo=0.23) cs_rad = pyeto.cs_rad(elevation, et_rad) avp = pyeto.avp_from_tdew(tdew) net_out_lw_rad = pyeto.net_out_lw_rad( pyeto.convert.celsius2kelvin(temp_c_min), pyeto.convert.celsius2kelvin(temp_c_max), sol_rad, cs_rad, avp) net_rad = pyeto.net_rad(net_in_sol_rad, net_out_lw_rad) eto = pyeto.fao56_penman_monteith( net_rad=net_rad, t=pyeto.convert.celsius2kelvin(temp_c), ws=wind_m_s, svp=pyeto.svp_from_t(temp_c), avp=avp, delta_svp=pyeto.delta_svp(temp_c), psy=pyeto.psy_const(atmos_pres)) return eto
def get_evap_i(lat, elev, wind, srad, tmin, tmax, tavg, month): if month == 1: J = 15 else: J = 15 + (month - 1) * 30 latitude = pyeto.deg2rad(lat) atmosphericVapourPressure = pyeto.avp_from_tmin(tmin) saturationVapourPressure = pyeto.svp_from_t(tavg) ird = pyeto.inv_rel_dist_earth_sun(J) solarDeclination = pyeto.sol_dec(J) sha = [pyeto.sunset_hour_angle(l, solarDeclination) for l in latitude] extraterrestrialRad = [ pyeto.et_rad(x, solarDeclination, y, ird) for x, y in zip(latitude, sha) ] clearSkyRad = pyeto.cs_rad(elev, extraterrestrialRad) netInSolRadnet = pyeto.net_in_sol_rad(srad * 0.001, albedo=0.23) netOutSolRadnet = pyeto.net_out_lw_rad(tmin, tmax, srad * 0.001, clearSkyRad, atmosphericVapourPressure) netRadiation = pyeto.net_rad(netInSolRadnet, netOutSolRadnet) tempKelvin = pyeto.celsius2kelvin(tavg) windSpeed2m = pyeto.wind_speed_2m(wind, 10) slopeSvp = pyeto.delta_svp(tavg) atmPressure = pyeto.atm_pressure(elev) psyConstant = pyeto.psy_const(atmPressure) return pyeto.fao56_penman_monteith(netRadiation, tempKelvin, windSpeed2m, saturationVapourPressure, atmosphericVapourPressure, slopeSvp, psyConstant, shf=0.0)
et_rad=pyeto.et_rad(lat, sol_dec, sha, ird) sol_rad=pyeto.sol_rad_from_sun_hours(daylight_hours,sunshine_hours,et_rad) ni_sw_rad=pyeto.net_in_sol_rad(sol_rad, albedo=0.23) cs_rad=pyeto.cs_rad(altitude, et_rad) svp_tmin=pyeto.svp_from_t(tmin) svp_tmax=pyeto.svp_from_t(tmax) avp=pyeto.avp_from_rhmean(svp_tmin, svp_tmax, rh_mean) no_lw_rad=pyeto.net_out_lw_rad(tmink, tmaxk, sol_rad, cs_rad, avp) net_rad=pyeto.net_rad(ni_sw_rad, no_lw_rad) #Presion de vapor de saturacion svp=pyeto.svp_from_t(t) #Delta presion de vapor de saturacion delta_svp=pyeto.delta_svp(t) #Constante psicrométrica atmos_pres=pyeto.atm_pressure(altitude) psy=pyeto.psy_const(atmos_pres) #Calculo ETo Fao Penman Monteith ETo=pyeto.fao56_penman_monteith(net_rad, tk, ws, svp, avp, delta_svp, psy, shf=0.0) ETO.append(ETo) if day>=365: if Ano%4==0: Ano=Ano+1 else: day=1 if Ano%4!=1: Ano=Ano+1 ETO=pd.DataFrame.from_dict(ETO) pd.DataFrame.to_csv(ETO, esta[i]+"_ETo"+".csv", index=False, header=False) #Escribo todos los datos en el archivo
def get_data_from_WU(): ###array to store the reports wu_weather_reports = [] ## today and last 6 days definition day1 = now - datetime.timedelta(days=6) day2 = now - datetime.timedelta(days=5) day3 = now - datetime.timedelta(days=4) day4 = now - datetime.timedelta(days=3) day5 = now - datetime.timedelta(days=2) day6 = now - datetime.timedelta(days=1) day7 = now #### convert dates to WU required format days = { 'day1': day1.strftime('%Y%m%d'), 'day2': day2.strftime('%Y%m%d'), 'day3': day3.strftime('%Y%m%d'), 'day4': day4.strftime('%Y%m%d'), 'day5': day5.strftime('%Y%m%d'), 'day6': day6.strftime('%Y%m%d'), 'day7': day7.strftime('%Y%m%d') } ### make API wather hisotry call for each day for day in days: url = 'http://api.wunderground.com/api/7c2ab99a0ccee978/history_{0}/q/95316.json'.format( days[day]) headers = {'content-type': 'application/JSON; charset=utf8'} response = requests.get(url, headers=headers) data = json.loads(response.text) #ETo calculation for the day using FAO-56 Penman-Monteith method lat = pyeto.deg2rad(37.585652) altitude = 38 julian_day = datetime.datetime.strptime(days.get(day), '%Y%m%d').timetuple().tm_yday sol_dec = pyeto.sol_dec(julian_day) sha = pyeto.sunset_hour_angle(lat, sol_dec) ird = pyeto.inv_rel_dist_earth_sun(julian_day) ### net radiation calculator net_rad = pyeto.et_rad(lat, sol_dec, sha, ird) temp_c = float(data["history"]["observations"][1]["tempm"]) temp_k = float(data["history"]["observations"][1]["tempi"]) humidity = float(data["history"]["observations"][1]["hum"]) dew_point = float(data["history"]["observations"][1]["dewptm"]) ws = float(data["history"]["observations"][1]["wspdm"]) #actual and saturated vapour pressure in kPH svp = pyeto.svp_from_t(temp_c) avp = pyeto.avp_from_tdew(dew_point) delta_svp = pyeto.delta_svp(temp_c) atm_pressure = pyeto.atm_pressure(altitude) psy = pyeto.psy_const(atm_pressure) #### the ETo plugin retun results in mm, it was converted to inched ETo_in_mm = pyeto.fao56_penman_monteith(net_rad, temp_k, ws, svp, avp, delta_svp, psy, shf=0.0) ETo = ETo_in_mm * 0.039370 ## insert eto value to day weather report data["history"]["observations"][1].update( {"ETo": "{0:.2f}".format(ETo)}) ###add report to report collector array wu_weather_reports.append(data["history"]["observations"][1]) #return all reports return wu_weather_reports
def calculate_precipitation(self, d): if "rain" in d: self.rain_day = float(d["rain"]) if "snow" in d: self.snow_day = float(d["snow"]) # def calculate_ev_fao56_factor(self, d): dt = d['dt'] factor = 0.0 if dt > d['sunrise']: if dt < d['sunset']: factor = min(float(dt - d['sunrise'])/3600.0, 1.0) else: if dt > d['sunset']: factor = (dt - d['sunrise'])/3600.0 if factor < 1.0: factor = 1.0 - factor return factor #def estimate_fao56_hourly(self, day_of_year, temp_c, tdew, elevation, latitude, rh, wind_m_s, atmos_pres): """ Estimate fao56 from weather """ sha = pyeto.sunset_hour_angle(pyeto.deg2rad(latitude), pyeto.sol_dec(day_of_year)) daylight_hours = pyeto.daylight_hours(sha) sunshine_hours = 0.8 * daylight_hours ird = pyeto.inv_rel_dist_earth_sun(day_of_year) et_rad = pyeto.et_rad(pyeto.deg2rad(latitude), pyeto.sol_dec(day_of_year), sha, ird) sol_rad = pyeto.sol_rad_from_sun_hours(daylight_hours, sunshine_hours, et_rad) net_in_sol_rad = pyeto.net_in_sol_rad(sol_rad=sol_rad, albedo=0.23) cs_rad = pyeto.cs_rad(elevation, et_rad) avp = pyeto.avp_from_tdew(tdew) #not sure if I trust this net_out_lw_rad calculation here! net_out_lw_rad = pyeto.net_out_lw_rad(temp_c-1, temp_c, sol_rad, cs_rad, avp) net_rad = pyeto.net_rad(net_in_sol_rad, net_out_lw_rad) eto = pyeto.fao56_penman_monteith( net_rad=net_rad, t=pyeto.convert.celsius2kelvin(temp_c), ws=wind_m_s, svp=pyeto.svp_from_t(temp_c), avp=avp, delta_svp=pyeto.delta_svp(temp_c), psy=pyeto.psy_const(atmos_pres)) return eto #def calculate_fao56_hourly(self, d): day_of_year = datetime.datetime.now().timetuple().tm_yday T_hr = d['temp'] t_dew = float(d["dew_point"]) pressure = d['pressure'] RH_hr = d['humidity'] u_2 = d['wind_speed'] #print("CALCULATE_FAO56:") #print("T_hr: {}".format(T_hr)) #print("t_dew: {}".format(t_dew)) #print("RH_hr: {}".format(RH_hr)) #print("u_2: {}".format(u_2)) #print("pressure: {}".format(pressure)) fao56 = self.estimate_fao56_hourly(day_of_year, T_hr, t_dew, self.elevation, LAT, RH_hr, u_2, pressure) return fao56
def exec(self): log.info('[START] {}'.format("exec")) try: if (platform.system() == 'Windows'): # 옵션 설정 sysOpt = { # 시작/종료 시간 'srtDate': '2020-09-01', 'endDate': '2020-09-03' # 경도 최소/최대/간격 , 'lonMin': 0, 'lonMax': 360, 'lonInv': 0.5 # 위도 최소/최대/간격 , 'latMin': -90, 'latMax': 90, 'latInv': 0.5 } else: # 옵션 설정 sysOpt = { # 시작/종료 시간 # 'srtDate': globalVar['srtDate'] # , 'endDate': globalVar['endDate'] } # globalVar['outPath'] = 'F:/Global Temp/aski' modelList = ['MRI-ESM2-0'] for i, modelInfo in enumerate(modelList): log.info("[CHECK] modelInfo : {}".format(modelInfo)) inpFile = '{}/{}/{} ssp585 2015-2100_*.nc'.format( globalVar['inpPath'], serviceName, modelInfo) fileList = sorted(glob.glob(inpFile)) log.info("[CHECK] fileList : {}".format(fileList)) dsData = xr.open_mfdataset(fileList) dsData = dsData.sel(lon=slice(120, 150), time=slice('2015-01', '2015-12')) # dsData = dsData.sel(time = slice('2015-01', '2020-12')) # 월별 시간 변환 dsData['time'] = pd.to_datetime(pd.to_datetime( dsData['time'].values).strftime("%Y-%m"), format='%Y-%m') # 단위 설정 # 켈빈 to 섭씨 dsData['tasCel'] = dsData['tas'] - 273.15 dsData['tasminCel'] = dsData['tasmin'] - 273.15 dsData['tasmaxCel'] = dsData['tasmax'] - 273.15 dsData['tasminCel'].attrs['units'] = 'degC' dsData['tasmaxCel'].attrs['units'] = 'degC' dsData['tasCel'].attrs['units'] = 'degC' # 단위 환산을 위한 매월 마지막 날 계산 lon1D = dsData['lon'].values lat1D = dsData['lat'].values time1D = dsData['time'].values timeEndMonth = [] timeYear = dsData['time.year'].values timeMonth = dsData['time.month'].values for i in range(0, len(timeYear)): timeEndMonth.append( calendar.monthrange(timeYear[i], timeMonth[i])[1]) latRad1D = pyeto.deg2rad(dsData['lat']) dayOfYear1D = dsData['time.dayofyear'] latRad3D = np.tile( np.transpose(np.tile(latRad1D, (len(lon1D), 1))), (len(time1D), 1, 1)) dayOfYear3D = np.transpose( np.tile(dayOfYear1D, (len(lon1D), len(lat1D), 1))) timeEndMonth3D = np.transpose( np.tile(timeEndMonth, (len(lon1D), len(lat1D), 1))) tmpData = xr.Dataset( { 'timeEndMonth': (('time', 'lat', 'lon'), (timeEndMonth3D).reshape( len(time1D), len(lat1D), len(lon1D))), 'latRad': (('time', 'lat', 'lon'), (latRad3D).reshape( len(time1D), len(lat1D), len(lon1D))), 'dayOfYear': (('time', 'lat', 'lon'), (dayOfYear3D).reshape( len(time1D), len(lat1D), len(lon1D))) }, coords={ 'lat': lat1D, 'lon': lon1D, 'time': time1D }) # ******************************************************************************************** # FAO-56 Penman-Monteith 방법 # ******************************************************************************************** # https://pyeto.readthedocs.io/en/latest/fao56_penman_monteith.html 매뉴얼 참조 # 1 W/m2 = 1 J/m2를 기준으로 MJ/day 변환 dsData['rsdsMJ'] = dsData['rsds'] * 86400 / (10**6) dsData['tasKel'] = dsData['tas'] dsData['tasminKel'] = dsData['tasmin'] dsData['tasmaxKel'] = dsData['tasmax'] dsData['tasKel'].attrs['units'] = 'degK' dsData['tasminKel'].attrs['units'] = 'degK' dsData['tasmaxKel'].attrs['units'] = 'degK' # 섭씨 to 켈빈 # dsData['tasKel'] = dsData['tas'] + 273.15 # dsData['tasminKel'] = dsData['tasmin'] + 273.15 # dsData['tasmaxKel'] = dsData['tasmax'] + 273.15 dsData['svp'] = svp_from_t(dsData['tasCel']) dsData['svpMax'] = svp_from_t(dsData['tasmaxCel']) dsData['svpMin'] = svp_from_t(dsData['tasminCel']) tmpData['solDec'] = sol_dec(tmpData['dayOfYear']) tmpData['sha'] = sunset_hour_angle(tmpData['latRad'], tmpData['solDec']) tmpData['dayLightHour'] = daylight_hours(tmpData['latRad']) tmpData['ird'] = inv_rel_dist_earth_sun(tmpData['dayOfYear']) tmpData['etRad'] = et_rad(tmpData['latRad'], tmpData['solDec'], tmpData['sha'], tmpData['ird']) tmpData['csRad'] = pyeto.cs_rad(altitude=1.5, et_rad=tmpData['etRad']) dsData['deltaSvp'] = delta_svp(dsData['tasCel']) # 대기 온도 1.5 m 가정 psy = pyeto.psy_const(atmos_pres=pyeto.atm_pressure( altitude=15)) dsData['avp'] = pyeto.avp_from_rhmin_rhmax( dsData['svpMax'], dsData['svpMin'], dsData['hurs'].min(), dsData['hurs'].max()) niSwRad = pyeto.net_in_sol_rad(dsData['rsdsMJ'], albedo=0.23) niLwRad = net_out_lw_rad(dsData['tasminKel'], dsData['tasmaxKel'], dsData['rsdsMJ'], tmpData['csRad'], dsData['avp']) dsData['net_rad'] = pyeto.net_rad(ni_sw_rad=niSwRad, no_lw_rad=niLwRad) faoRes = pyeto.fao56_penman_monteith(dsData['net_rad'], dsData['tasKel'], dsData['sfcWind'], dsData['svp'], dsData['avp'], dsData['deltaSvp'], psy, shf=0) # ******************************************************************************************** # Hargreaves 방법 # ******************************************************************************************** # https://xclim.readthedocs.io/en/stable/indicators_api.html 매뉴얼 참조 harRes = xclim.indices.potential_evapotranspiration( dsData['tasminCel'], dsData['tasmaxCel'], dsData['tasCel'], dsData['lat'], method='hargreaves85') # 1 kg/m2/s = 86400 mm/day를 기준으로 mm/month 변환 harResL1 = harRes * 86400.0 * tmpData['timeEndMonth'] # https://pyeto.readthedocs.io/en/latest/thornthwaite.html 매뉴얼 참조 # harRes = pyeto.hargreaves(dsData['tasminCel'], dsData['tasmaxCel'], dsData['tasCel'], tmpData['etRad']) # harResL1 = harRes # ******************************************************************************************** # Thornthwaite 방법 # ******************************************************************************************** # https://xclim.readthedocs.io/en/stable/indicators_api.html 매뉴얼 참조 thwRes = xclim.indices.potential_evapotranspiration( dsData['tasminCel'], dsData['tasmaxCel'], dsData['tasCel'], dsData['lat'], method='thornthwaite48') # 1 kg/m2/s = 86400 mm/day를 기준으로 mm/month 변환 thwResL1 = thwRes * 86400.0 * tmpData['timeEndMonth'] # https://pyeto.readthedocs.io/en/latest/thornthwaite.html 매뉴얼 참조 # thwRes = pyeto.thornthwaite(dsData['tasCel'], tmpData['dayLightHour']) # thwResL1 = thwResL1 # ******************************************************************************************** # 데이터 병합 # ******************************************************************************************** data = xr.Dataset( { 'hargreaves': (('time', 'lat', 'lon'), (harResL1.values).reshape( len(time1D), len(lat1D), len(lon1D))), 'thornthwaite': (('time', 'lat', 'lon'), (thwResL1.values).reshape( len(time1D), len(lat1D), len(lon1D))), 'penman-monteith': (('time', 'lat', 'lon'), (faoRes.values).reshape( len(time1D), len(lat1D), len(lon1D))) }, coords={ 'lat': lat1D, 'lon': lon1D, 'time': time1D }) dataL1 = xr.merge([data, dsData]) # # NetCDF 파일 저장 saveFile = '{}/{}/{}_eto.nc'.format(globalVar['outPath'], serviceName, modelInfo) os.makedirs(os.path.dirname(saveFile), exist_ok=True) dataL1.to_netcdf(saveFile) log.info('[CHECK] saveFile : {}'.format(saveFile)) except Exception as e: log.error("Exception : {}".format(e)) raise e finally: log.info('[END] {}'.format("exec"))
# this data should be from nws. import pyeto latitude_deg = 38.01 latitude = pyeto.deg2rad(latitude_deg) day_of_year = 206 tmin = 37 tmax = 53 coastal = True altitude = 147 rh_min = 13 rh_max = 88 ws = 1.3 tmean = pyeto.daily_mean_t(tmin, tmax) atmos_pres = pyeto.atm_pressure(altitude) psy = pyeto.psy_const(atmos_pres) # Humidity svp_tmin = pyeto.svp_from_t(tmin) svp_tmax = pyeto.svp_from_t(tmax) delta_svp = pyeto.delta_svp(tmean) svp = pyeto.mean_svp(tmin, tmax) avp = pyeto.avp_from_rhmin_rhmax(svp_tmin, svp_tmax, rh_min, rh_max) # Radiation sol_dec = pyeto.sol_dec(day_of_year) sha = pyeto.sunset_hour_angle(latitude, sol_dec) ird = pyeto.inv_rel_dist_earth_sun(day_of_year) et_rad = pyeto.et_rad(latitude, sol_dec, sha, ird) cs_rad = pyeto.cs_rad(altitude, et_rad) sol_rad = pyeto.sol_rad_from_t(et_rad, cs_rad, tmin, tmax, coastal)
def get_data_from_WU(): ###array to store the reports wu_weather_reports = [] ## today and last 6 days definition day1 = now - datetime.timedelta(days=6) day2 = now - datetime.timedelta(days=5) day3 = now - datetime.timedelta(days=4) day4 = now - datetime.timedelta(days=3) day5 = now - datetime.timedelta(days=2) day6 = now - datetime.timedelta(days=1) day7 = now #### convert dates to WU required format days = { 'day1': day1.strftime('%Y%m%d'), 'day2': day2.strftime('%Y%m%d'), 'day3': day3.strftime('%Y%m%d'), 'day4': day4.strftime('%Y%m%d'), 'day5': day5.strftime('%Y%m%d'), 'day6': day6.strftime('%Y%m%d'), 'day7': day7.strftime('%Y%m%d') } ### make API wather hisotry call for each day for day in days: url = 'http://api.wunderground.com/api/7c2ab99a0ccee978/history_{0}/q/95316.json'.format(days[day]) headers = {'content-type': 'application/JSON; charset=utf8'} response = requests.get(url, headers=headers) data = json.loads(response.text) #ETo calculation for the day using FAO-56 Penman-Monteith method lat = pyeto.deg2rad(37.585652) altitude = 38 julian_day = datetime.datetime.strptime(days.get(day), '%Y%m%d').timetuple().tm_yday sol_dec = pyeto.sol_dec(julian_day) sha = pyeto.sunset_hour_angle(lat, sol_dec) ird = pyeto.inv_rel_dist_earth_sun(julian_day) ### net radiation calculator net_rad = pyeto.et_rad(lat, sol_dec, sha, ird) temp_c = float(data["history"]["observations"][1]["tempm"]) temp_k = float(data["history"]["observations"][1]["tempi"]) humidity = float(data["history"]["observations"][1]["hum"]) dew_point = float(data["history"]["observations"][1]["dewptm"]) ws = float(data["history"]["observations"][1]["wspdm"]) #actual and saturated vapour pressure in kPH svp = pyeto.svp_from_t(temp_c) avp = pyeto.avp_from_tdew(dew_point) delta_svp = pyeto.delta_svp(temp_c) atm_pressure = pyeto.atm_pressure(altitude) psy = pyeto.psy_const(atm_pressure) #### the ETo plugin retun results in mm, it was converted to inched ETo_in_mm = pyeto.fao56_penman_monteith(net_rad, temp_k, ws, svp, avp, delta_svp, psy, shf=0.0) ETo = ETo_in_mm * 0.039370 ## insert eto value to day weather report data["history"]["observations"][1].update({"ETo": "{0:.2f}".format(ETo)}) ###add report to report collector array wu_weather_reports.append(data["history"]["observations"][1]) #return all reports return wu_weather_reports
def test_psy_const(self): # Test based on example 2, p.63 of FAO paper psy = pyeto.psy_const(81.8) self.assertAlmostEqual(psy, 0.054, 3)