def _setup_ensemble(self): self.ensemble = [] for i in range(self.n_ensemble): p = copy.deepcopy(self.parameters) for par, distr in self.override_parameters.items(): p.set_override(par, distr[i]) member = Wofost71_WLP_FD(p, self.weather_db, self.agromanagement) self.ensemble.append(member)
def modelInit(cropdName, soilName, wav, co2, lat, long, agroName): wofism = Wofost71_WLP_FD( packTheParams(cropName=cropdName, soilName=soilName, siteWav=wav, siteCo2=co2), dailyweatherobservations(lat=lat, long=long), agromanagementLoader(name=agroName)) print("model initilized") return wofism
def run_wofost(parameters, agromanagement, wdp, potential=False): if potential: wofsim = Wofost71_PP(parameters, wdp, agromanagement) else: wofsim = Wofost71_WLP_FD(parameters, wdp, agromanagement) print(parameters) wofsim.run_till_terminate() df_results = pd.DataFrame(wofsim.get_output()) df_results = df_results.set_index("day") return df_results, wofsim
def run_simulation(self, crop_calendar): # import yaml # agromanagement = yaml.load(crop_calendar) agromanagement = yaml.safe_load(crop_calendar) wofost = Wofost71_WLP_FD(self.parameterprovider, self.weather, agromanagement) wofost.run_till_terminate() self.output = wofost.get_output() return self.output[-1]['TWSO']
def sensitivity_soil(soil_parameters): SMV, SMFCF, SM0, CRAIRC, K0 = soil_parameters soildata['SMV'] = SMV soildata['SMFCF'] = SMFCF soildata['SM0'] = SM0 soildata['CRAIRC'] = CRAIRC soildata['K0'] = K0 parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) wofsim = Wofost71_WLP_FD(parameters, wdp, agromanagement) wofsim.run_till_terminate() #df_results = pd.DataFrame(wofsim.get_output()) #df_results = df_results.set_index("day") #df_results.tail() summary_output = wofsim.get_summary_output() yield_list.append(summary_output[0]['TWSO'])
def run_simulation_manager(self, agromanagement): # from pcse.engine import Engine wofost = Wofost71_WLP_FD(self.parameterprovider, self.weather, agromanagement) # wofost = Engine(self.parameterprovider, self.weather, agromanagement, config=os.path.join(self.data_dir, "Wofost71_NPK_grol.conf")) wofost.run_till_terminate() water_losed_into_deep_horizont = wofost.get_terminal_output() sum_water = water_losed_into_deep_horizont[ 'PERCT'] + water_losed_into_deep_horizont['LOSST'] # for paper - estimate effictive irrigation self.effective_irrigation = water_losed_into_deep_horizont['RAINT'] self.total_ammount_of_losed_water = sum_water self.output = wofost.get_output() return self.output[-1]['TWSO']
def run_simulation(self): if not isinstance(self.weather_data, dict): print("Fetching NASA weather...") self.wdp = NASAPowerWeatherDataProvider(self.location.lat, self.location.lon) else: print("Weather data is cached...") if (self.location.lat != self.weather_data['latitude']) or (self.location.lon != self.weather_data['longitude']): print("Location changed, fetching NASA weather again") self.wdp = NASAPowerWeatherDataProvider(self.location.lat, self.location.lon) else: self.wdp = WeatherDataProvider() self.wdp.store = self.weather_data['store'] self.wdp.elevation = self.weather_data['elevation'] self.wdp.longitude = self.weather_data['longitude'] self.wdp.latitude = self.weather_data['latitude'] self.wdp.description = self.weather_data['description'] self.wdp.ETmodel = self.weather_data['ETmodel'] print(self.wdp) amgt = default_amgt soil = default_soil site = default_site crop = default_crop amgt[0][self.start_date] = amgt[0].pop(amgt[0].keys()[0]) amgt[0][self.start_date]['CropCalendar']['crop_start_date'] = self.sowing_date amgt[0][self.start_date]['CropCalendar']['crop_end_date'] = self.end_date parvalues = ParameterProvider(sitedata=site, soildata=soil, cropdata=crop) crop['TSUM1'] = self.tsum1 crop['TSUM2'] = self.tsum2 soil.update(self.soil_attributes) wofsim = Wofost71_WLP_FD(parvalues, self.wdp, agromanagement=amgt) wofsim.run_till_terminate() output = wofsim.get_output() results_dict = {} for a in output: results_dict[a.pop('day').isoformat()] = a self.simulation_dict = results_dict return results_dict
def init_model(self): print("packing all parameters...") parameters = ParameterProvider(cropdata=self.crop, soildata=self.soil, sitedata=self.site) print('create mode of {}') print('55', self.crop_name) print('56', self.argo_path) wofost = Wofost71_WLP_FD(parameters, self.weather, self.argo) print("runing model of {}") # wofost.run_till_terminate() wofost.run(260) print("save model out put as e csv file with name of {} ") model_out_put = wofost.get_output() df = pd.DataFrame(model_out_put) df.to_csv(f"{self.output_name}") return self.output_name
def run(crop: str, soil: str, agro: str, day: int, weather_filename: str, saved_name="output"): # load argo from directory agromanagement = YAMLAgroManagementReader(f"{base_dir}/{agro}") sitedata = WOFOST71SiteDataProvider(WAV=100, CO2=360) # load soil from directory soildata = CABOFileReader(f"{base_dir}/{soil}") # load crop from directory cropdata = CABOFileReader(f"{base_dir}/{crop}") # load weather data from directory wdp = CABOWeatherDataProvider(fname=weather_filename, fpath=base_dir) # packaing parameters parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) # create model wofost = Wofost71_WLP_FD(parameters, wdp, agromanagement) # run till [day] wofost.run(day) # save output az a csv in OUT directory model_out_put = wofost.get_output() df = pd.DataFrame(model_out_put) df.to_csv(f"{out_dir}/{saved_name}.csv")
def optimize_regional_yldgapf_dyn(NUTS_no_, detrend, crop_no_, selected_grid_cells_, selected_soil_types_, weather, inputdir, opti_years_, obs_type='yield', plot_rmse=False): #=============================================================================== import math from operator import itemgetter as operator_itemgetter from matplotlib import pyplot as plt from pcse.models import Wofost71_WLP_FD from pcse.base_classes import WeatherDataProvider from pcse.fileinput.cabo_weather import CABOWeatherDataProvider # aggregated yield method: # 2- we construct a 2D array with same dimensions as TSO_regional, # containing the observed yields row = [] # this list will become the row of the 2D array for y,year in enumerate(opti_years_): index_year = np.argmin(np.absolute(detrend[1]-year)) row = row + [detrend[0][index_year]] OBS = np.tile(row, (5,1)) # repeats the list as a row 3 times, to get a # 2D array # 3- we calculate all the individual yields from the selected grid cells x # soils combinations # NB: we explore the range of yldgapf between 0.1 and 1. f0 = 0. f2 = 0.5 f4 = 1. f_step = 0.25 # Until the precision of the yield gap factor is good enough (i.e. < 0.02) # we loop over it. We do 12 iterations in total with this method. iter_no = 0 RMSE_stored = list() while (f_step >= 0.02): iter_no = iter_no + 1 # sub-method: looping over the yield gap factors # we build a range of 3 yield gap factors to explore one low bound, one # high bound, one in the middle f_step = (f4 - f0)/4. f1 = f0 + f_step f3 = f2 + f_step f_range = [f0, f1, f2, f3, f4] RES = [] # list in which we will store the yields of the combinations counter=0 for grid, arable_land in selected_grid_cells_: frac_arable = arable_land / 625000000. # Retrieve the weather data of one grid cell (all years are in one # file) if (weather == 'CGMS'): filename = os.path.join(inputdir,'weather_objects/', 'weatherobject_g%d.pickle'%grid) weatherdata = WeatherDataProvider() weatherdata._load(filename) if (weather == 'ECMWF'): weatherdata = CABOWeatherDataProvider('%i'%grid,fpath=ECMWFdir) # Retrieve the soil data of one grid cell (all possible soil types) filename = os.path.join(inputdir,'soildata_objects/', 'soilobject_g%d.pickle'%grid) soil_iterator = pickle_load(open(filename,'rb')) for smu, stu_no, weight, soildata in selected_soil_types_[grid]: # TSO will store all the yields of one grid cell x soil # combination, for all years and all 3 yldgapf values TSO = np.zeros((len(f_range), len(opti_years_))) counter +=1 for y, year in enumerate(opti_years_): # Retrieve yearly data filename = os.path.join(inputdir, 'timerdata_objects/%i/c%i/'%(year,crop_no_), 'timerobject_g%d_c%d_y%d.pickle'\ %(grid,crop_no_,year)) timerdata = pickle_load(open(filename,'rb')) filename = os.path.join(inputdir, 'cropdata_objects/%i/c%i/'%(year,crop_no_), 'cropobject_g%d_c%d_y%d.pickle'\ %(grid,crop_no_,year)) cropdata = pickle_load(open(filename,'rb')) if str(grid).startswith('1'): dum = str(grid)[0:2] else: dum = str(grid)[0] filename = os.path.join(inputdir, 'sitedata_objects/%i/c%i/grid_%s/' %(year,crop_no_,dum), 'siteobject_g%d_c%d_y%d_s%d.pickle'\ %(grid,crop_no_,year,stu_no)) sitedata = pickle_load(open(filename,'rb')) for f,factor in enumerate(f_range): cropdata['YLDGAPF']=factor # run WOFOST wofost_object = Wofost71_WLP_FD(sitedata, timerdata, soildata, cropdata, weatherdata) wofost_object.run_till_terminate() # get the yield (in kgDM.ha-1) TSO[f,y] = wofost_object.get_variable('TWSO') #print grid, stu_no, year, counter, [y[0] for y in TSO], OBS[0] RES = RES + [(grid, stu_no, weight*frac_arable, TSO)] # 4- we aggregate the yield or harvest into the regional one with array # operations sum_weighted_vals = np.zeros((len(f_range), len(opti_years_))) # empty 2D array with same dimension as TSO sum_weights = 0. for grid, stu_no, weight, TSO in RES: # adding weighted 2D-arrays in the empty array sum_weighted_yields # NB: variable 'weight' is actually the cultivated area in m2 sum_weighted_vals = sum_weighted_vals + (weight/10000.)*TSO # computing the total sum of the cultivated area in ha sum_weights = sum_weights + (weight/10000.) if (obs_type == 'harvest'): TSO_regional = sum_weighted_vals / 1000000. # sum of the individual # harvests in 1000 tDM elif (obs_type == 'yield'): TSO_regional = sum_weighted_vals / sum_weights # weighted average of # all yields in kgDM/ha # 5- we compute the (sim-obs) differences. DIFF = TSO_regional - OBS if (TSO_regional[-1][0] <= 0.): print 'WARNING: no simulated crop growth. We set the optimum fgap to 1.' return 1. if (TSO_regional[-1] <= OBS[-1]): print 'WARNING: obs yield > sim yield. We set optimum to 1.' return 1. # 6- we calculate the RMSE (root mean squared error) of the 3 yldgapf # The RMSE of each yldgapf is based on N obs-sim differences for the N # years looped over RMSE = np.zeros(len(f_range)) for f,factor in enumerate(f_range): list_of_DIFF = [] for y, year in enumerate(opti_years_): list_of_DIFF = list_of_DIFF + [DIFF[f,y]] RMSE[f] = np.sqrt(np.mean( [ math.pow(j,2) for j in list_of_DIFF ] )) #print RMSE, f_range # We store the value of the RMSE for plotting purposes RMSE_stored = RMSE_stored + [(f_range[1], RMSE[1]), (f_range[3], RMSE[3])] if (iter_no == 1): RMSE_stored = RMSE_stored + [(f_range[0], RMSE[0]), (f_range[2], RMSE[2]), (f_range[4], RMSE[4])] # 7- We update the yldgapf range to explore for the next iteration. # For this we do a linear interpolation of RMSE between the 3 yldgapf # explored here, and the next range to explore is the one having the # smallest interpolated RMSE index_new_center = RMSE.argmin() # if the optimum is close to 1: if index_new_center == len(f_range)-1: f0 = f_range[index_new_center-2] f2 = f_range[index_new_center-1] f4 = f_range[index_new_center] # if the optimum is close to 0: elif index_new_center == 0: f0 = f_range[index_new_center] f2 = f_range[index_new_center+1] f4 = f_range[index_new_center+2] else: f0 = f_range[index_new_center-1] f2 = f_range[index_new_center] f4 = f_range[index_new_center+1] # when we are finished iterating on the yield gap factor range, we plot the # RMSE as a function of the yield gap factor if (plot_rmse == True): RMSE_stored = sorted(RMSE_stored, key=operator_itemgetter(0)) x,y = zip(*RMSE_stored) fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(5,5)) fig.subplots_adjust(0.15,0.16,0.95,0.96,0.4,0.) ax.plot(x, y, c='k', marker='o') ax.set_xlabel('yldgapf (-)') ax.set_ylabel('RMSE') fig.savefig('%s_opti_fgap.png'%NUTS_no_) #pickle_dump(RMSE_stored,open('%s_RMSE.pickle'%NUTS_no_,'wb')) # 8- when we are finished iterating on the yield gap factor range, we return # the optimum value. We look for the yldgapf with the lowest RMSE index_optimum = RMSE.argmin() optimum_yldgapf = f_range[index_optimum] print 'optimum found: %.2f +/- %.2f'%(optimum_yldgapf, f_step) # 10- we return the optimized YLDGAPF return optimum_yldgapf
number = fp.readline() # 第二行为生成参数个数 fp.readline() # 变量个数 fp.readline() # 0 此后开始读参数 fp2.write(str(number)) fp3.write(str(number)) for i in progressbar.ProgressBar()(range(int(number))): sim_paraments = list(map(float, fp.readline().split('\t')[:-1])) # 更改参数 for iterm, value in change_data.items(): parameters[iterm] = sim_paraments[value] parameters['SLATB'][1] = sim_paraments[3] parameters['SLATB'][3] = sim_paraments[4] parameters['SLATB'][5] = sim_paraments[5] wf = Wofost71_WLP_FD(parameters, weatherdataprovider, agromanagement) wf.run_till_terminate() summary_output = wf.get_summary_output() output = wf.get_output() date = pd.date_range(start=summary_output[0]['DOE'], end=summary_output[0]['DOM'], freq='D') df = pd.DataFrame(output).set_index("day") fp2.writelines(['RUN', ' ', str(i), '\n']) fp2.write(str(len(date))) fp2.write('\n') fp3.writelines([ str(summary_output[0]['TWSO']), '\t', str(summary_output[0]['TAGP']) ]) fp3.write('\n')
from pcse.fileinput import YAMLAgroManagementReader agromanagement = YAMLAgroManagementReader("sugarbeet_c.agro") print(agromanagement) #using modeul to read weather data from pcse.db import NASAPowerWeatherDataProvider wdp = NASAPowerWeatherDataProvider(latitude=52, longitude=5) print(wdp) #from pcse.fileinput import ExcelWeatherDataProvider #wdp = ExcelWeatherDataProvider ("weather04.xlsx") #print (wdp) #simulate the crop from pcse.models import Wofost71_WLP_FD wofsim = Wofost71_WLP_FD(parameters, wdp, agromanagement) wofsim.run_till_terminate() output = wofsim.get_output() len(output) varnames = ["day", "DVS", "TAGP", "LAI", "SM"] tmp = {} for var in varnames: tmp[var] = [t[var] for t in output] day = tmp.pop("day") fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) for var, ax in zip(["DVS", "TAGP", "LAI", "SM"], axes.flatten()): ax.plot_date(day, tmp[var], "b-") ax.set_title(var) fig.autofmt_xdate() fig.savefig("sugarbeet.png")
from pcse.fileinput import CABOFileReader soildata = CABOFileReader("soy.soil") #site parameters from pcse.util import WOFOST71SiteDataProvider sitedata = WOFOST71SiteDataProvider(WAV=100, CO2=360) #pack the different sets of parameters from pcse.base_classes import ParameterProvider parameters = ParameterProvider(cropdata=cropd, soildata=soildata, sitedata=sitedata) #cropdata = cropd #simulate the crop from pcse.models import Wofost71_WLP_FD wofsim = Wofost71_WLP_FD(parameters, wdp, agro) #from pcse.models import Wofost71_PP #wofsim = Wofost71_PP (parameters, wdp, agro) wofsim.run_till_terminate() output = wofsim.get_output() len(output) #save as xls file using pandas df = pd.DataFrame(output) df.to_excel( "/Users/Darren/Desktop/DIS_tools/Q3_wofost/crop_simulation/result0203/" + "soybean" + str(num) + ".xlsx") print("soybean" + str(num) + ".xlsx") """
wdp = NASAPowerWeatherDataProvider(latitude=52, longitude=5) # Read parameter values from the input files cropdata = CABOFileReader(os.path.join(data_dir, 'sug0601.crop')) soildata = CABOFileReader(os.path.join(data_dir, 'ec3.soil')) timerdata = PCSEFileReader(os.path.join(data_dir, 'sugarbeet_calendar.pcse')) sitedata = { 'SSMAX': 0., 'IFUNRN': 0, 'NOTINF': 0, 'SSI': 0, 'WAV': 100, 'SMLIM': 0.03 } # Start WOFOST wf = Wofost71_WLP_FD(sitedata, timerdata, soildata, cropdata, wdp) wf.run(days=400) print wf.get_variable("DOA") print wf.get_variable("DOH") print wf.get_variable("TAGP") print wf.get_variable("LAIMAX") # Get time-series output from WOFOST and take the selected variables output = wf.get_output() varnames = ["day", "DVS", "TAGP", "LAI", "SM"] tmp = {} for var in varnames: tmp[var] = [t[var] for t in output] day = tmp.pop("day")
def perform_yield_sim(crop_no, grid_no, year, fgap, selec_method, nsoils, force_forwardsim): #=============================================================================== # Temporarily add code directory to python path, to be able to import pcse # modules sys.path.insert(0, codedir) sys.path.insert(0, os.path.join(codedir, 'carbon_cycle')) #------------------------------------------------------------------------------- import glob from pcse.fileinput.cabo_weather import CABOWeatherDataProvider from maries_toolbox import select_soils from pcse.models import Wofost71_WLP_FD from pcse.exceptions import WeatherDataProviderError #------------------------------------------------------------------------------- # fixed settings for these point simulations: weather = 'ECMWF' #------------------------------------------------------------------------------- # skipping already performed forward runs if required by user outlist = glob.glob(os.path.join(forwardir, 'wofost_g%i*' % grid_no)) if (len(outlist) == nsoils and force_forwardsim == False): print " We have already done that forward run! Skipping." return None #------------------------------------------------------------------------------- # Retrieve the weather data of one grid cell if (weather == 'CGMS'): filename = os.path.join(CGMSdir, 'weatherobject_g%d.pickle' % grid_no) weatherdata = WeatherDataProvider() weatherdata._load(filename) if (weather == 'ECMWF'): weatherdata = CABOWeatherDataProvider('%i' % (grid_no), fpath=ECMWFdir) #print weatherdata(datetime.date(datetime(2006,4,1))) # Retrieve the soil data of one grid cell filename = os.path.join(CGMSdir, 'soildata_objects', 'soilobject_g%d.pickle' % grid_no) soil_iterator = pickle_load(open(filename, 'rb')) # Retrieve calendar data of one year for one grid cell filename = os.path.join( CGMSdir, 'timerdata_objects/%i/c%i/' % (year, crop_no), 'timerobject_g%d_c%d_y%d.pickle' % (grid_no, crop_no, year)) timerdata = pickle_load(open(filename, 'rb')) # Retrieve crop data of one year for one grid cell filename = os.path.join( CGMSdir, 'cropdata_objects/%i/c%i/' % (year, crop_no), 'cropobject_g%d_c%d_y%d.pickle' % (grid_no, crop_no, year)) cropdata = pickle_load(open(filename, 'rb')) # retrieve the fgap data of one year and one grid cell cropdata['YLDGAPF'] = fgap # Select soil types to loop over for the forward runs selected_soil_types = select_soils(crop_no, [grid_no], CGMSdir, method=selec_method, n=nsoils) for smu, stu_no, stu_area, soildata in selected_soil_types[grid_no]: resfile = os.path.join(forwardir, "wofost_g%i_s%i.txt" % (grid_no, stu_no)) # Retrieve the site data of one year, one grid cell, one soil type if str(grid_no).startswith('1'): dum = str(grid_no)[0:2] else: dum = str(grid_no)[0:1] filename = os.path.join( CGMSdir, 'sitedata_objects/%i/c%i/grid_%s' % (year, crop_no, dum), 'siteobject_g%d_c%d_y%d_s%d.pickle' % (grid_no, crop_no, year, stu_no)) sitedata = pickle_load(open(filename, 'rb')) # run WOFOST wofost_object = Wofost71_WLP_FD(sitedata, timerdata, soildata, cropdata, weatherdata) try: wofost_object.run_till_terminate() #will stop the run when DVS=2 except WeatherDataProviderError: print 'Error with the weather data' return None # get time series of the output and take the selected variables wofost_object.store_to_file(resfile) # get major summary output variables for each run # total dry weight of - dead and alive - storage organs (kg/ha) TSO = wofost_object.get_variable('TWSO') # total dry weight of - dead and alive - leaves (kg/ha) TLV = wofost_object.get_variable('TWLV') # total dry weight of - dead and alive - stems (kg/ha) TST = wofost_object.get_variable('TWST') # total dry weight of - dead and alive - roots (kg/ha) TRT = wofost_object.get_variable('TWRT') # maximum LAI MLAI = wofost_object.get_variable('LAIMAX') # rooting depth (cm) RD = wofost_object.get_variable('RD') # Total above ground dry matter (kg/ha) TAGP = wofost_object.get_variable('TAGP') #output_string = '%10.3f, %8i, %5i, %7i, %15.2f, %12.5f, %14.2f, ' #%(yldgapf, grid_no, year, stu_no, arable_area/10000.,stu_area/10000.,TSO) output_string = '%10.3f, %8i, %5i, %7i, %12.5f, %14.2f, '%(fgap, grid_no, year, stu_no, stu_area/10000., TSO) + \ '%14.2f, %14.2f, %14.2f, %14.2f, %13.2f, %15.2f'%(TLV, TST, TRT, MLAI, RD, TAGP) print output_string return None