def set_up_wofost(crop_start_date, crop_end_date, meteo, crop, variety, soil, wav=100, co2=400, rdmsol=100.): cropdata = YAMLCropDataProvider(fpath="./WOFOST_crop_parameters") cropdata.set_active_crop(crop, variety) soildata = CABOFileReader(soil) soildata['RDMSOL'] = rdmsol sitedata = WOFOST71SiteDataProvider(WAV=wav, CO2=co2) parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) with open("temporal.amgt", 'w') as fp: fp.write( agromanagement_contents.format(year=crop_start_date.year, crop=crop, variety=variety, crop_start_date=crop_start_date, crop_end_date=crop_end_date)) agromanagement = YAMLAgroManagementReader("temporal.amgt") wdp = CABOWeatherDataProvider(meteo, fpath=f"./data/meteo/{meteo}/") return parameters, agromanagement, wdp
def main(): agro = make_agromanagement(2014) weather_data = ExcelWeatherDataProvider(config.weather_fname) cropd = PCSEFileReader(config.crop_fname) soild = PCSEFileReader(config.soil_fname) params = ParameterProvider(cropdata=cropd, soildata=soild, sitedata={}) model = CampbellDiazModel(params, weather_data, agro) model.run_till_terminate() output = model.get_output() df = pd.DataFrame(model.get_output()).set_index("day") # # Plot results fig, axes = plt.subplots(nrows=5, ncols=2, figsize=(10, 5)) for key, axis in zip(df.columns, axes.flatten()): df[key].plot(ax=axis, title=key) fig.autofmt_xdate() fig.savefig(os.path.join(this_dir, "output", "Campbell_soybean.png")) csv_fname = os.path.join(this_dir, "output", "Campbell_soybean.csv") df.to_csv(csv_fname, header=True) return model, output
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 init_wofost(): data_dir = os.path.join(os.getcwd(), '../simulation/default_data') crop_file_name = 'crop.cab' soil_file_name = 'soil.cab' site_file_name = 'site.cab' config_file_name = 'WLP_NPK.conf' soildata = CABOFileReader(os.path.join(data_dir, soil_file_name)) sitedata = CABOFileReader(os.path.join(data_dir, site_file_name)) cropdata = CABOFileReader(os.path.join(data_dir, crop_file_name)) config = os.path.join(data_dir, config_file_name) params = ParameterProvider(cropdata, sitedata, soildata) latitude, longitude = 51.97, 5.67 wdp = NASAPowerWeatherDataProvider(latitude, longitude) return params, wdp, config
def load_model(self): """ Function to load input soil, site and crop parameters data from yaml files """ crop = YAMLCropDataProvider() # soil = CABOFileReader(os.path.join(self.data_dir, "ec3.soil")) soil = CABOFileReader(os.path.join(self.data_dir, "wofost_npk.soil")) site = CABOFileReader(os.path.join(self.data_dir, "wofost_npk.site")) site['CO2'] = 360.0 # site = WOFOST71SiteDataProvider(WAV=100,CO2=360) #parameters for model self.parameterprovider = ParameterProvider(soildata=soil, cropdata=crop, sitedata=site)
def set_wofost_up(crop="maize", variety="Maize_VanHeemst_1988", meteo="Upper_East", soil="ec4.new", wav=60, co2=400, rdmsol=100): cropdata = YAMLCropDataProvider(fpath="./WOFOST_crop_parameters") cropdata.set_active_crop(crop, variety) soildata = CABOFileReader(soil) soildata["RDMSOL"] = rdmsol sitedata = WOFOST71SiteDataProvider(WAV=wav, CO2=co2) parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) agromanagement = YAMLAgroManagementReader("ghana_maize.amgt") wdp = CABOWeatherDataProvider(meteo, fpath=f"./data/meteo/{meteo}/") return parameters, agromanagement, wdp
os.path.join(para_dir, "NASA天气文件lat={0:.1f},lon={1:.1f}.xlsx".format(lat, lon))) cropdata = CABOFileReader(os.path.join(para_dir, 'WWH101.CAB')) soildata = CABOFileReader(os.path.join(para_dir, 'EC3.NEW')) sitedata = { 'SSMAX': 0., 'IFUNRN': 0, 'NOTINF': 0, 'SSI': 0, 'WAV': 20, 'SMLIM': 0.03, 'CO2': 360, 'RDMSOL': 120 } parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) agromanagement = YAMLAgroManagementReader( os.path.join(para_dir, 'wheat_none.agro')) # 创建文档储存模型数值结果 with open(os.path.join(para_dir, '总结果.txt'), 'w') as fp3: fp3.writelines(['2', '\n', 'TSOW', '\n', 'TAGP', '\n', 'time = no', '\n']) with open(os.path.join(para_dir, '按生育期结果.txt'), 'w') as fp2: fp2.writelines(['1', '\n', 'LAI', '\n', 'time = yes', '\n']) # 打开simlab输出的文档 with open(os.path.join(para_dir, 'PARA.sam'), 'r') as fp: fp.readline() # 第一行 number = fp.readline() # 第二行为生成参数个数 fp.readline() # 变量个数 fp.readline() # 0 此后开始读参数 fp2.write(str(number))
def initialize(self, config_file="gridded_wofost.yaml"): t1 = time.time() self.config = read_config_file(config_file) # Layer inputs for AgroManagement with rasterio.open(self.config.maps.AEZ_map.location) as ds: aez_map = ds.read(1) aez_map[aez_map < 0] = np.NaN check_grid_size(self.config, aez_map) with rasterio.open(self.config.maps.crop_rotation_map.location) as ds: crop_rotation_map = ds.read(1) crop_rotation_map[crop_rotation_map < 0] = np.NaN check_grid_size(self.config, crop_rotation_map) # Crop, site parameters and soil grid crop_parameters = YAMLCropDataProvider( fpath=self.config.crop_parameters.location) site_parameters = WOFOST71SiteDataProvider(WAV=10, CO2=360) with rasterio.open(self.config.maps.rooting_depth.location) as ds: rooting_depth = ds.read(1) rooting_depth[rooting_depth < 0] = np.NaN check_grid_size(self.config, rooting_depth) # Weather from WFLOW NetCDF files self.WFLOWWeatherDataProvider = WFLOWWeatherDataProvider(self.config) # initialize object grid for storing WOFOST results self.WOFOSTgrid = np.ndarray(shape=aez_map.shape, dtype=np.object) # WOFOST configuration p = Path(__file__) wofost_config = str(p.parent / "conf" / "Wofost71_PP.conf") nrows, ncols = aez_map.shape p_row = None print("Initializing: .", end="") for (row, col) in product(range(nrows), range(ncols)): if row != p_row: p_row = row if row % 10 == 0: print(f"{row/float(nrows)*100:.1f}%..", end="") if row == 15: break crop_rotation_type = crop_rotation_map[row, col] aez = aez_map[row, col] if crop_rotation_type not in self.config.maps.crop_rotation_map.relevant_crop_rotations: continue if aez not in self.config.maps.AEZ_map.relevant_AEZ: continue agro = read_agromanagement(self.config, aez, crop_rotation_type) soil_parameters = { "RDMSOL": rooting_depth[row, col], "SM0": 0.4, "SMFCF": 0.25, "SMW": 0.1, "CRAIRC": 0.04 } params = ParameterProvider(sitedata=site_parameters, cropdata=crop_parameters, soildata=soil_parameters) wofsim = GridAwareEngine( row=row, col=col, parameterprovider=params, weatherdataprovider=self.WFLOWWeatherDataProvider, agromanagement=agro, config=wofost_config) self._check_start_end_date(wofsim, row, col, aez, crop_rotation_type) self.WOFOSTgrid[row, col] = wofsim print(f"\nInitializing took {time.time() - t1} seconds")
def wofost_parameter_sweep_func(crop_start_date=dt.date(2011, 7, 1), crop_end_date=dt.datetime(2011, 11, 1), span=40.0, tdwi=20., tsum1=750., tsum2=859., tsumem=70, rgrlai=0.05, cvo=0.05, cvl=0.05, meteo="Upper_East", crop="maize", variety="Maize_VanHeemst_1988", soil="ec4.new", wav=100, co2=400, rdmsol=100., potential=False): cropdata = YAMLCropDataProvider(fpath="./WOFOST_crop_parameters") cropdata.set_active_crop(crop, variety) soildata = CABOFileReader(soil) soildata["RDMSOL"] = rdmsol sitedata = WOFOST71SiteDataProvider(WAV=wav, CO2=co2) parameters = ParameterProvider(cropdata=cropdata, soildata=soildata, sitedata=sitedata) for p, v in zip( ["SPAN", "TSUM1", "TSUM2", "TSUMEM", "TDWI", "RGRLAI", "CVO", "CVL"], [span, tsum1, tsum2, tsumem, tdwi, rgrlai, cvo, cvl]): parameters.set_override(p, v, check=True) with open("temporal.amgt", 'w') as fp: fp.write( agromanagement_contents.format(year=crop_start_date.year, crop=crop, variety=variety, crop_start_date=crop_start_date, crop_end_date=crop_end_date)) agromanagement = YAMLAgroManagementReader("temporal.amgt") wdp = CABOWeatherDataProvider(meteo, fpath=f"./data/meteo/{meteo}/") df_results, simulator = run_wofost(parameters, agromanagement, wdp, potential=potential) fig, axs = plt.subplots(nrows=5, ncols=2, sharex=True, squeeze=True, figsize=(16, 16)) axs = axs.flatten() for j, p in enumerate(WOFOST_PARAMETERS): axs[j].plot_date(df_results.index, df_results[p], '-') axs[j].set_ylabel(WOFOST_LABELS[p], fontsize=8) plt.gcf().autofmt_xdate() plt.gca().fmt_xdata = matplotlib.dates.DateFormatter('%Y-%m-%d') axs[8].set_xlabel("Time [d]") axs[9].set_xlabel("Time [d]") key = f"span_{span}-tdwi_{tdwi}-tsum1_{tsum1}-tsum2_{tsum2}-tsumem_{tsumem}" key += f"-rgrlai_{rgrlai}-wav_{wav}-cvo_{cvo}-cvl_{cvl}" if potential: key += "-POT.csv" else: key += "-LIM.csv" df_results.to_csv(key, encoding="utf-8", index=False)
def ensemble_wofost(lon=115.55, lat=38.05, start=dt.date(2008, 10, 12), end=None, en_size=3, prior_file=None, weather_type="NASA", weather_path=None, out_en_file=None, data_dir=None): """ This is a function to generate a emsemble of WOFOST paramters and corresponding output. you need to specify Longitude (lon), Latitude (lat), start time of crop (start), end time of crop (end, 270 days duration by default), emsemble size (en_size), configuration file for prior distributions of pramaters (prior_file), weather driver dataset type (weather_type), it's set to NASA Power dataset "NASA" by default, you could use ERA5 "ERA5" or ECMWF TIGGE "ITGEE" instead or use your own CABO file (%your_cabo_files_name%).) """ if data_dir is None: #home = os.path.dirname(os.path.realpath("__file__")) home = os.path.split(os.path.realpath(__file__))[ 0] #os.path.dirname(os.path.abspath(__file__)) data_dir = home + "/data/" #print(data_dir) if prior_file is None: prior_file = data_dir + "par_prior.csv" if out_en_file is None: out_en_file = "WOFOST_par_ensemble.npy" if lat < -90 or lat > 90: msg = "Latitude should be between -90 and 90 degrees." raise ValueError(msg) if lon < -180 or lon > 180: msg = "Longitude should be between -180 and 180 degrees." raise ValueError(msg) if end == None: end = start + dt.timedelta(days=270) if start >= end: msg = "Start time should be earlier than end time." raise ValueError(msg) if weather_type == "NASA": print("Downloading weather driver from NASA Power...") weather = NASAPowerWeatherDataProvider(latitude=lat, longitude=lon) elif weather_type[:3] == "ERA" or weather_type[:3] == "era": print("ERA5 reanalysis dataset used.") if weather_path is None or not os.path.isdir(weather_path): msg = "Please provide a valid path for weahter driver data." raise ValueError(msg) gen_era_cabo(lat, lon, start.year, end.year, inputfile=weather_path, data_dir=data_dir) size = 0.25 weather_name = "ERA_%5.2f_%5.2f" % (int( (lon + size / 2.) / size) * size, int( (lat + size / 2.) / size) * size) weather = CABOWeatherDataProvider(weather_name, fpath=weather_path) elif weather_type[:5].upper() == "TIGGE": print("TIGGE forecast from ECMWF used.") if weather_path is None or not os.path.isdir(weather_path): msg = "Please provide a valid path for weahter driver data." raise ValueError(msg) gen_tigge_cabo(lat, lon, start.year, end.year, inputfile=weather_path, data_dir=data_dir) size = 0.25 weather_name = "TIGGE_%5.2f_%5.2f" % (int( (lon + size / 2.) / size) * size, int( (lat + size / 2.) / size) * size) weather = CABOWeatherDataProvider(weather_name, fpath=weather_path) else: if weather_path == None: raise ValueError("Please provide your weather driver path!") weather = CABOWeatherDataProvider(weather_type, fpath=weather_path) sdoy = retrieve_pixel_value([lon, lat], data_dir + "mean_wheat_sdoy_china_kriging_int.tif") tsum1 = retrieve_pixel_value([lon, lat], data_dir + "mean_wheat_TSUM1_china_kriging.tif") tsum2 = retrieve_pixel_value([lon, lat], data_dir + "TSUM2_aver_0.1deg.tif") varnames = ["day", "TAGP", "LAI", "TWSO", "DVS"] tmp = {} cropfile = os.path.join(data_dir, 'WWH108.CAB') crop = CABOFileReader(cropfile) soilfile = os.path.join(data_dir, 'Hengshui.soil') soil = CABOFileReader(soilfile) site = WOFOST71SiteDataProvider(WAV=100, CO2=360) parameters = ParameterProvider(soildata=soil, cropdata=crop, sitedata=site) agromanagement_file = os.path.join(data_dir, 'shenzhou_wheat.amgt') agromanagement = YAMLAgroManagementReader(agromanagement_file) (key, value), = agromanagement[0].items() agromanagement[0][dt.datetime.strptime( "%d%03d" % (start.year, sdoy), "%Y%j").date()] = agromanagement[0].pop(key) value['CropCalendar']['crop_start_date'] = dt.datetime.strptime( "%d%03d" % (start.year, sdoy), "%Y%j").date() print("Crop is sowed at %s" % dt.datetime.strftime( value['CropCalendar']['crop_start_date'], "%Y-%m-%d")) value['CropCalendar']['crop_end_date'] = end prior_dist, prior_list, param_xvalue, param_type = define_prior_distributions( chunk=prior_file, tsum1=tsum1, tsum2=tsum2) z_start = np.empty((len(prior_list), en_size)) for i, param in enumerate(prior_list): z_start[i, :] = prior_dist[param].rvs(en_size) outdata = [] for i in range(en_size): theta_dict = dict(zip(prior_list, z_start[:, i])) cropdata = copy.deepcopy(crop) tb_x = {} tb_y = {} tb_t = {} tmp_dict = {} for par in theta_dict.keys(): try: if param_type[par] != 'S': tb_index = par.find("TB") if tb_index < 0: print(param_xvparam_typealue[par]) raise Exception("Are you sure %s is a table value?" % par) tb_name = par[:tb_index + 2] tmp_list = [param_xvalue[par], theta_dict[par]] if not tb_name in tb_x: tb_x[tb_name] = np.array([param_xvalue[par]]) tb_y[tb_name] = np.array([theta_dict[par]]) tb_t[tb_name] = param_type[par] else: tb_x[tb_name] = np.append(tb_x[tb_name], param_xvalue[par]) tb_y[tb_name] = np.append(tb_y[tb_name], theta_dict[par]) except KeyError: raise Exception( "There's something wrong with %s, please check it." % par) tmp_dict = {} for par in tb_x.keys(): # Table parameters s_i = np.argsort(tb_x[par]) s_x = tb_x[par][s_i] s_v = tb_y[par][s_i] par_tb = [] # print(par,tb_t[par],cropdata[par],s_x,s_v) if tb_t[par][1] == 'P': for i in range(len(tb_x[par])): if tb_t[par][0] == 'Y': # Partly change table Y values if s_x[i] in cropdata[par][::2]: # change old value c_i = cropdata[par][::2].index(s_x[i]) cropdata[par][c_i * 2] = s_v[i] else: # insert new value array_X = cropdata[par][::2] array_Y = cropdata[par][1:][::2] ins_i = bisect(array_X, s_x[i]) cropdata[par].insert(ins_i * 2, s_x[i]) cropdata[par].insert(ins_i * 2 + 1, s_v[i]) #print(cropdata[par]) else: # Partly change table X values if s_x[i] in cropdata[par][ 1:][::2]: # change old value c_i = cropdata[par][1:][::2].index(s_x[i]) cropdata[par][c_i * 2] = s_v[i] else: # insert new value array_X = cropdata[par][::2] array_Y = cropdata[par][1:][::2] ins_i = bisect(array_X, s_x[i]) cropdata[par].insert(ins_i * 2, s_x[i]) cropdata[par].insert(ins_i * 2 + 1, s_v[i]) #print(cropdata[par]) elif tb_t[par][1] == 'A': if tb_t[par][0] == 'Y': # Totally change table Y values for i in range(len(tb_x[par])): par_tb.append(s_x[i]) par_tb.append(s_v[i]) else: # Totally change table X values for i in range(len(tb_x[par])): par_tb.append(s_v[i]) par_tb.append(s_x[i]) tmp_dict[par] = par_tb #print(tmp_dict[par]) theta_dict.update(tmp_dict) else: raise Exception( "There's something wrong with %s, please check it." % par) ########################################################################## cropdata.update(theta_dict) parameters = ParameterProvider(cropdata=cropdata, soildata=soil, sitedata=site) wofwof = Wofost71_PP(parameters, weather, agromanagement) wofwof.run_till_terminate() output = wofwof.get_output() summary_output = wofwof.get_summary_output() msg = "Reached maturity at {DOM} with max LAI of {LAIMAX} "\ "and a yield of {TWSO} kg/ha." print(msg.format(**summary_output[0])) for var in varnames: tmp[var] = [t[var] for t in output] theta_dict["LAI"] = tmp["LAI"][-181:] theta_dict["day"] = tmp["day"][-181:] theta_dict["Yield"] = tmp["TWSO"][-1] outdata.append(theta_dict) np.save(out_en_file, outdata)
db_location = os.path.join(settings.PCSE_USER_HOME, "pcse.db") db_location = os.path.normpath(db_location) dsn = "sqlite:///" + db_location db_engine = sa.create_engine(dsn) db_metadata = sa.MetaData(db_engine) grid = 31031 crop = 1 year = 2000 # Get input parameters from database with warnings.catch_warnings(): warnings.simplefilter("ignore") sited = fetch_sitedata(db_metadata, grid, year) cropd = fetch_cropdata(db_metadata, grid, year, crop) soild = fetch_soildata(db_metadata, grid) parameters = ParameterProvider(sitedata=sited, cropdata=cropd, soildata=soild) # Get Agromanagement agromanagement = AgroManagementDataProvider(db_engine, grid, crop, year) start_date = list(agromanagement[0].keys())[0] end_date = start_date + dt.timedelta(days=365) weather = GridWeatherDataProvider(db_engine, grid_no=grid, start_date=start_date, end_date=end_date)