def test_is_supy_euqal_mode(self): df_state_init, df_forcing_tstep = sp.load_SampleData() df_forcing_part = df_forcing_tstep.iloc[:288 * 1] # single-step results df_output_s, df_state_s = sp.run_supy(df_forcing_part, df_state_init, save_state=True) df_res_s = (df_output_s.loc[:, [ "SUEWS", "DailyState", "snow", ]].fillna(-999.0).sort_index(axis=1).round(6).applymap( lambda x: -999.0 if np.abs(x) > 3e4 else x)) df_state_init, df_forcing_tstep = sp.load_SampleData() # multi-step results df_output_m, df_state_m = sp.run_supy(df_forcing_part, df_state_init, save_state=False) df_res_m = (df_output_m.loc[:, [ "SUEWS", "DailyState", "snow", ]].fillna(-999.0).sort_index(axis=1).round(6).applymap( lambda x: -999.0 if np.abs(x) > 3e4 else x)) # print(df_res_m.iloc[:3, 86], df_res_s.iloc[:3, 86]) pd.testing.assert_frame_equal( left=df_res_s, right=df_res_m, )
def test_is_supy_sim_save_multi_grid_par(self): n_grid = 4 df_state_init, df_forcing_tstep = sp.load_SampleData() df_state_init = pd.concat([df_state_init for x in range(n_grid)]) df_state_init.index = pd.RangeIndex(n_grid, name="grid") df_forcing_part = df_forcing_tstep.iloc[:] df_output, df_state = sp.run_supy(df_forcing_part, df_state_init) test_success_sim = np.all([ not df_output.empty, not df_state.empty, ]) with tempfile.TemporaryDirectory() as dir_temp: list_outfile = sp.save_supy( df_output, df_state, path_dir_save=dir_temp, site="pytest", logging_level=10, ) test_success_save = np.all( [isinstance(fn, Path) for fn in list_outfile]) self.assertTrue(test_success_sim and test_success_save)
def test_is_supy_running_multi_grid_par(self): df_state_init, df_forcing_tstep = sp.load_SampleData() df_state_init = pd.concat([df_state_init for x in range(6)]) df_forcing_part = df_forcing_tstep.iloc[:] t_start = time() df_output, df_state = sp.run_supy( df_forcing_part, df_state_init) t_end = time() # only print to screen on macOS due incompatibility on Windows if platform.system() == 'Darwin': capturedOutput = io.StringIO() # Create StringIO object sys.stdout = capturedOutput # and redirect stdout. # Call function. n_grid = df_state_init.index.size print(f'Running time: {t_end-t_start:.2f} s for {n_grid} grids') sys.stdout = sys.__stdout__ # Reset redirect. # Now works as before. print('Captured:\n', capturedOutput.getvalue()) test_non_empty = np.all( [ not df_output.empty, not df_state.empty, ] ) self.assertTrue(test_non_empty)
def test_is_supy_save_working(self): df_state_init, df_forcing_tstep = sp.load_SampleData() # df_state_init = pd.concat([df_state_init for x in range(6)]) df_forcing_part = df_forcing_tstep.iloc[:288*2] t_start = time() df_output, df_state = sp.run_supy( df_forcing_part, df_state_init) t_end = time() with tempfile.TemporaryDirectory() as dir_temp: list_outfile = sp.save_supy( df_output, df_state, path_dir_save=dir_temp) # only print to screen on macOS due incompatibility on Windows if platform.system() == 'Darwin': capturedOutput = io.StringIO() # Create StringIO object sys.stdout = capturedOutput # and redirect stdout. # Call function. n_grid = df_state_init.index.size print(f'Running time: {t_end-t_start:.2f} s for {n_grid} grids') sys.stdout = sys.__stdout__ # Reset redirect. # Now works as before. print('Captured:\n', capturedOutput.getvalue()) test_non_empty = np.all( [isinstance(fn, Path) for fn in list_outfile] ) self.assertTrue(test_non_empty)
def test_is_supy_running_single_step(self): df_state_init, df_forcing_tstep = sp.load_SampleData() df_forcing_part = df_forcing_tstep.iloc[: 288 * 1] df_output, df_state = sp.run_supy( df_forcing_part, df_state_init, save_state=True ) test_non_empty = np.all([not df_output.empty, not df_state.empty,]) self.assertTrue(test_non_empty)
def spinup_SUEWS(path_runcontrol, path_csv_phenol, first_day_str, veg_spin=0, veg_type=""): print("Initializing SUEWS variables.....") df_state_init = sp.init_supy(path_runcontrol) df_phenol = pd.read_csv(path_csv_phenol) if veg_spin == 1: print("Initializing for " + veg_type) df_state_init = modify_attr(df_state_init, df_phenol, veg_type) grid = df_state_init.index[0] df_forcing = sp.load_forcing_grid(path_runcontrol, grid) first_day = datetime.strptime(first_day_str, "%Y-%m-%d") print("Rotating the time based on the first day of " + first_day_str) first_part = df_forcing.loc[df_forcing[ df_forcing.index >= first_day].index] second_part = df_forcing.loc[df_forcing[df_forcing.index < first_day - pd.Timedelta("1 days")].index] second_part.index = second_part.index + pd.Timedelta("366 days") df_forcing_2 = first_part.append(second_part) df_forcing_2.iy = df_forcing_2.index.year df_forcing_2.index.freq = first_part.index.freq round_number = 0 error = 0.4 counter = 0 while error >= 0.1 or counter < 3: counter += 1 round_number = round_number + 1 print("Running SUEWS for round number " + str(round_number) + ".....") df_output, df_state_final = sp.run_supy(df_forcing_2, df_state_init, save_state=False) final_state = df_state_final[df_state_init.columns.levels[0]].iloc[1] df_state_init.iloc[0] = final_state soilstore_before = df_state_final.soilstore_id.iloc[0] soilstore_after = df_state_final.soilstore_id.iloc[1] diff_soil = sum(abs(soilstore_after - soilstore_before)) error = 100 * diff_soil / soilstore_before.mean() print(f"Change in soil store in % = {error:.2f}") print(f"SUEWS spinup is finished in {round_number} iterations.") return df_state_init
def spin_lai_albedo(maxalb, minalb, maxlai, minlai, baset, basete, first_day_str,path_runcontrol): df_state_init = sp.init_supy(path_runcontrol) grid = df_state_init.index[0] df_forcing = sp.load_forcing_grid(path_runcontrol, grid) df_state_init.loc[:, "albmax_evetr"] = maxalb[0] df_state_init.loc[:, "albmax_dectr"] = maxalb[1] df_state_init.loc[:, "albmax_grass"] = maxalb[2] df_state_init.loc[:, "albmin_evetr"] = minalb[0] df_state_init.loc[:, "albmin_dectr"] = minalb[1] df_state_init.loc[:, "albmin_grass"] = minalb[2] df_state_init.loc[:, "laimax"] = maxlai df_state_init.loc[:, "laimin"] = minlai df_state_init.loc[:, "baset"] = baset df_state_init.loc[:, "basete"] = basete first_day = datetime.strptime(first_day_str, "%Y-%m-%d") print("Rotating the time based on the first day of " + first_day_str) first_part = df_forcing.loc[df_forcing[df_forcing.index >= first_day].index] second_part = df_forcing.loc[ df_forcing[df_forcing.index < first_day - pd.Timedelta("1 days")].index ] second_part.index = second_part.index + pd.Timedelta("366 days") df_forcing_2 = first_part.append(second_part) df_forcing_2.iy = df_forcing_2.index.year df_forcing_2.index.freq = first_part.index.freq round_number = 0 print("getting initial lai and albedo for changed grids . . .") while round_number <= 4: round_number = round_number + 1 print("Running SUEWS for round number " + str(round_number) + ".....") df_output, df_state_final = sp.run_supy( df_forcing_2, df_state_init, save_state=False ) final_state = df_state_final[df_state_init.columns.levels[0]].iloc[1] df_state_init.iloc[0] = final_state # %% alb_init = df_state_final.loc[:, "alb"].iloc[1][2:5].values lai_init = df_state_final.loc[:, "lai_id"].iloc[1].values return alb_init, lai_init
def test_is_supy_running_multi_step(self): df_state_init, df_forcing_tstep = sp.load_SampleData() df_forcing_part = df_forcing_tstep.iloc[:] df_output, df_state = sp.run_supy( df_forcing_part, df_state_init, check_input=True ) # # only print to screen on macOS due incompatibility on Windows # if platform.system() == "Darwin": # # capturedOutput = io.StringIO() # Create StringIO object # # sys.stdout = capturedOutput # and redirect stdout. # # Call function. # print(f"Running time: {t_end-t_start:.2f} s") # # sys.stdout = sys.__stdout__ # Reset redirect. # # Now works as before. # # print("Captured:\n", capturedOutput.getvalue()) test_non_empty = np.all([not df_output.empty, not df_state.empty,]) self.assertTrue(test_non_empty)
except: pass # %% from urlpath import URL from pathlib import Path import numpy as np import pandas as pd import supy as sp import os os.getcwd() # %% sample run print("loading in", "gen_df_forcing", "...") df_state_init_sample, df_forcing_sample = sp.load_SampleData() df_output_sample, df_state_end_sample = sp.run_supy( df_forcing_sample.iloc[:10], df_state_init_sample) print("loading in", "gen_df_forcing", "...") # %% [markdown] # ## generate forcing related dataframe # %% # ### load `SUEWS_***.txt` related tables from nml_rst_proc import url_repo_base, url_repo_input url_repo_output = URL(url_repo_base) / "output_files" def gen_df_forcing( path_csv_in="SSss_YYYY_data_tt.csv", url_base=url_repo_input, ) -> pd.DataFrame:
#%% import supy as sp from pathlib import Path #%% path_runcontrol = Path('./run_preston') / 'RunControl_preston.nml' df_state_init = sp.init_supy(path_runcontrol) grid = df_state_init.index[0] df_forcing = sp.load_forcing_grid(path_runcontrol, grid) #%% df_output, df_state_final = sp.run_supy(df_forcing, df_state_init, save_state=False) df = df_output.loc[(98), 'SUEWS']
def gs_plot_test(g1, g2, g3, g4, g5, g6, g_max, s1, name, year, alpha=1, helen=0): path_runcontrol = Path('runs/run' + '/') / 'RunControl.nml' df_state_init = sp.init_supy(path_runcontrol) df_state_init, level = modify_attr(df_state_init, name) grid = df_state_init.index[0] df_forcing_run = sp.load_forcing_grid(path_runcontrol, grid) df_state_init.g1 = g1 * alpha df_state_init.g2 = g2 df_state_init.g3 = g3 df_state_init.g4 = g4 df_state_init.g5 = g5 df_state_init.g6 = g6 f_state_init = modify_attr_2(df_state_init, g_max, s1) df_output, df_state_final = sp.run_supy(df_forcing_run, df_state_init, save_state=False) df_obs = pd.read_csv('runs/run' + '/Input/' + 'kc' + '_2012_data_60.txt', sep=' ', parse_dates={'datetime': [0, 1, 2, 3]}, keep_date_col=True, date_parser=func_parse_date) df_obs = df_obs.set_index('datetime') fig, axs = plt.subplots(4, 1, figsize=(8, 15)) plt.subplots_adjust(hspace=.8) plt.rc('font', size=15) ax = axs[0] df_obs_temp = df_obs.replace(-999, np.nan) df = df_output.SUEWS.loc[grid, :] df = df.resample('1h', closed='left', label='right').mean() IQR_compare('qe', 'QE', df_obs_temp, df, ax) ax.legend() ax.set_title('QE (test data set-fitted g1-g6)') ax.set_ylabel('QE (W m$^{-2}$)') ax.set_xlabel('Time (UTC)') df = df_output.SUEWS.loc[grid, :] df = df.resample('1h', closed='left', label='right').mean() df_temp = df_obs_temp[df_obs_temp.qe < 700] plt.rc('font', size=15) data_for_plot = {'IQR': {'obs': df_obs_temp, 'model': df}} data_for_plot['obs_sim'] = { 'obs': df_temp, 'model': df.loc[df_temp.index, :] } if helen == 0: with open( 'outputs/surface_conductance/' + name + '-' + str(year) + '.pkl', 'wb') as f: pickle.dump(data_for_plot, f) elif helen == 1: with open( 'outputs/surface_conductance/' + name + '-' + str(year) + '-Helen.pkl', 'wb') as f: pickle.dump(data_for_plot, f) ax = axs[1] obs_sim('qe', 'QE', df_temp, df.loc[df_temp.index, :], ax) ax.set_ylabel('Model') ax.set_xlabel('Obs') ax.set_title('QE-test data-all season-MAE=' + str( np.round(np.mean(abs(df.loc[df_temp.index, :].QE - df_temp.qe)), 2))) ax = axs[2] df_output.SUEWS.QE.loc[grid, :].resample('1h', closed='left', label='right').mean().plot( ax=ax, label='model') ax.legend() ax = axs[3] df_obs[df_obs.qe > 0].qe.plot(ax=ax, label='obs') ax.legend()
try: os.chdir(os.path.join(os.getcwd(), 'docs/source/data-structure')) print(os.getcwd()) except: pass #%% [markdown] # # Key IO Data Structures in SuPy #%% [markdown] # ## Introduction #%% [markdown] # The Cell below demonstrates a minimal case of SuPy simulation with all key IO data structures included: #%% import supy as sp df_state_init, df_forcing = sp.load_SampleData() df_output, df_state_final = sp.run_supy(df_forcing.iloc[:288], df_state_init) #%% [markdown] # * Input: # * `df_state_init`: model initial states # * `df_forcing`: forcing data # * Output: # * `df_state_final`: model final states # * `df_output`: model output results #%% [markdown] # ## Input #%% [markdown] # ### `df_state_init`: model initial states #%%