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"))
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) ni_sw_rad = pyeto.net_in_sol_rad(sol_rad) no_lw_rad = pyeto.net_out_lw_rad(pyeto.celsius2kelvin(tmin), pyeto.celsius2kelvin(tmax), sol_rad, cs_rad, avp) net_rad = pyeto.net_rad(ni_sw_rad, no_lw_rad) eto = pyeto.fao56_penman_monteith(net_rad, pyeto.celsius2kelvin(tmean), ws, svp, avp, delta_svp, psy) print eto
def test_avp_from_rhmin_rhmax(self): # Test based on example 5, p.72 of FAO paper avp = pyeto.avp_from_rhmin_rhmax(2.064, 3.168, 54, 82) self.assertAlmostEqual(avp, 1.70, 2)