def test_set_timeseries_parameter_lookup(self): timeseries = np.arange(30) data = np.round(50 + np.random.rand(len(timeseries)).cumsum(), 4) temp_timeseries = pd.Series(index=timeseries, data=data) timeseries_bash = "[[" + ",".join(timeseries.astype(str)) + "],["\ + ",".join(data.astype(str)) + "]]" command = f"{call} -o {out_tab_file} -r lookup_1d_time "\ f"-R {','.join(timeseries.astype(str))} "\ f" {test_model_look}"\ f" lookup_1d_time={timeseries_bash}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue((stocks["lookup_1d_time"] == temp_timeseries).all()) os.remove(out_tab_file) command = f"{call} -o {out_tab_file} -r lookup_2d_time "\ f"-R {','.join(timeseries.astype(str))}"\ f" {test_model_look}"\ f" lookup_2d_time={timeseries_bash}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue( (stocks["lookup_2d_time[Row1]"] == temp_timeseries).all()) self.assertTrue( (stocks["lookup_2d_time[Row2]"] == temp_timeseries).all()) os.remove(out_tab_file)
def test_different_frames_error(self): from pysd.tools.benchmarking import load_outputs, assert_frames_close with self.assertRaises(AssertionError) as err: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv"))) self.assertIn("Following columns are not close:\n\tTeacup Temperature", str(err.exception)) self.assertNotIn("Column 'Teacup Temperature' is not close.", str(err.exception)) self.assertNotIn("Actual values:\n\t", str(err.exception)) self.assertNotIn("Expected values:\n\t", str(err.exception)) with self.assertRaises(AssertionError) as err: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), verbose=True) self.assertIn("Following columns are not close:\n\tTeacup Temperature", str(err.exception)) self.assertIn("Column 'Teacup Temperature' is not close.", str(err.exception)) self.assertIn("Actual values:\n\t", str(err.exception)) self.assertIn("Expected values:\n\t", str(err.exception))
def test_model_arguments(self): # check initial time initial_time = 10 command = f"{call} -o {out_tab_file} -I {initial_time} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue(stocks.index.values[0] == initial_time) os.remove(out_tab_file) # check final time final_time = 20 command = f"{call} -o {out_tab_file} -F {final_time} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue(stocks.index.values[-1] == final_time) os.remove(out_tab_file) # check time step time_step = 10 command = f"{call} -o {out_tab_file} -T {time_step} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue((np.diff(stocks.index.values) == time_step).all()) self.assertTrue((stocks["SAVEPER"] == time_step).all().all()) self.assertTrue((stocks["TIME STEP"] == time_step).all().all()) os.remove(out_tab_file) # check saveper time_step = 5 saveper = 10 command = f"{call} -o {out_tab_file} -T {time_step} "\ f"-S {saveper} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue((np.diff(stocks.index.values) == saveper).all()) self.assertTrue((stocks["SAVEPER"] == saveper).all().all()) self.assertTrue((stocks["TIME STEP"] == time_step).all().all()) os.remove(out_tab_file) # check all initial_time = 15 time_step = 5 saveper = 10 final_time = 45 command = f"{call} -o {out_tab_file} --time-step={time_step} "\ f"--saveper={saveper} --initial-time={initial_time} "\ f"--final-time={final_time} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue((np.diff(stocks.index.values) == saveper).all()) self.assertTrue(stocks.index.values[0] == initial_time) self.assertTrue(stocks.index.values[-1] == final_time) os.remove(out_tab_file)
def test_different_frames_warning(self): from warnings import catch_warnings from pysd.tools.benchmarking import load_outputs, assert_frames_close with catch_warnings(record=True) as ws: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), assertion="warn") # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn( "Following columns are not close:\n\tTeacup Temperature", str(wu[0].message)) self.assertNotIn("Column 'Teacup Temperature' is not close.", str(wu[0].message)) self.assertNotIn("Actual values:\n\t", str(wu[0].message)) self.assertNotIn("Expected values:\n\t", str(wu[0].message)) with catch_warnings(record=True) as ws: assert_frames_close( load_outputs(os.path.join(_root, "data/out_teacup.csv")), load_outputs( os.path.join(_root, "data/out_teacup_modified.csv")), assertion="warn", verbose=True) # use only user warnings wu = [w for w in ws if issubclass(w.category, UserWarning)] self.assertEqual(len(wu), 1) self.assertIn( "Following columns are not close:\n\tTeacup Temperature", str(wu[0].message)) self.assertIn("Column 'Teacup Temperature' is not close.", str(wu[0].message)) self.assertIn("Actual values:\n\t", str(wu[0].message)) self.assertIn("Expected values:\n\t", str(wu[0].message))
def test_save_without_name(self): import re command = f"{call} {test_model}" command2 = f"{call} -o {out_tab_file} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stdout = out.stdout.decode(encoding_stdout) outputs = re.findall("(?<=Data saved in ').*(?=')", stdout)[0] out2 = subprocess.run(split_bash(command2), capture_output=True) self.assertEqual(out2.returncode, 0) out, out2 = load_outputs(outputs), load_outputs(out_tab_file) os.remove(outputs) os.remove(out_tab_file) self.assertTrue((out - out2 == 0).all().all())
def test_run_return_timestamps(self): timestamps =\ np.random.randint(1, 5, 5).cumsum().astype(float).astype(str) command = f"{call} -o {out_csv_file} -R {','.join(timestamps)} "\ f" {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_csv_file) self.assertTrue((stocks.index.values.astype(str) == timestamps).all()) os.remove(out_csv_file) command = f"{call} -o {out_csv_file} -R 5 {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_csv_file) self.assertTrue((stocks.index.values == [5])) os.remove(out_csv_file)
def test_set_constant_parameter(self): value = 20 command = f"{call} -o {out_tab_file} -r room_temperature "\ f" {test_model_xmile}"\ f" room_temperature={value}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) self.assertTrue((stocks["room_temperature"] == value).all()) os.remove(out_tab_file)
def test_run_model_with_data(self): data_file = os.path.join( _root, "test-models/tests/data_from_other_model/data.tab") model_file = os.path.join( _root, "test-models/tests/data_from_other_model/" + "test_data_from_other_model.mdl") command = f"{call} -o {out_tab_file} -D {data_file}"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_tab_file) canon = load_outputs( os.path.join(_root, "test-models/tests/data_from_other_model/output.tab")) assert_frames_close(stocks[canon.columns], canon) # invalid data file command = f"{call} -o {out_tab_file} -D my_file.txt"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertNotEqual(out.returncode, 0) stderr = out.stderr.decode(encoding_stderr) self.assertIn("PySD: error: when parsing my_file.txt", stderr) self.assertIn("The data file name must be .tab or .csv...", stderr) # not found data file command = f"{call} -o {out_tab_file} -D my_file.tab"\ f" {model_file}" out = subprocess.run(split_bash(command), capture_output=True) self.assertNotEqual(out.returncode, 0) stderr = out.stderr.decode(encoding_stderr) self.assertIn("PySD: error: when parsing my_file.tab", stderr) self.assertIn("The data file does not exist...", stderr)
def test_export_import(self): import pysd from pysd.tools.benchmarking import assert_frames_close exp_file = "teacup15.pic" model = pysd.read_vensim(test_model) stocks = model.run(return_timestamps=[0, 10, 20, 30]) self.assertTrue((stocks["INITIAL TIME"] == 0).all().all()) command = f"{call} -o {out_tab_file} -e {exp_file} -F 15 -R 0,10"\ f" {test_model}" command2 = f"{call} -o {out_tab_file} -i {exp_file} -R 20,30"\ f" {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks1 = load_outputs(out_tab_file) out = subprocess.run(split_bash(command2), capture_output=True) self.assertEqual(out.returncode, 0) stocks2 = load_outputs(out_tab_file) os.remove(exp_file) os.remove(out_tab_file) self.assertTrue((stocks1["INITIAL TIME"] == 0).all().all()) self.assertTrue((stocks1["FINAL TIME"] == 15).all().all()) self.assertTrue((stocks2["INITIAL TIME"] == 15).all().all()) stocks.drop("INITIAL TIME", axis=1, inplace=True) stocks1.drop("INITIAL TIME", axis=1, inplace=True) stocks2.drop("INITIAL TIME", axis=1, inplace=True) stocks.drop("FINAL TIME", axis=1, inplace=True) stocks1.drop("FINAL TIME", axis=1, inplace=True) stocks2.drop("FINAL TIME", axis=1, inplace=True) assert_frames_close(stocks1, stocks.loc[[0, 10]]) assert_frames_close(stocks2, stocks.loc[[20, 30]])
def test_run_return_columns(self): return_columns = ["Room Temperature", "Teacup Temperature"] command = f"{call} -o {out_csv_file} -r "\ f"'{', '.join(return_columns)}' "\ f" {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_csv_file) self.assertEqual(set(stocks.columns), set(return_columns)) os.remove(out_csv_file) # from txt txt_file = os.path.join(_root, "return_columns.txt") return_columns = ["Room Temperature", "Teacup Temperature"] with open(txt_file, "w") as file: file.write("\n".join(return_columns)) command = f"{call} -o {out_csv_file} -r {txt_file} {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_csv_file) self.assertEqual(set(stocks.columns), set(return_columns)) os.remove(txt_file) os.remove(out_csv_file) return_columns = ["room_temperature", "teacup_temperature"] command = f"{call} -o {out_csv_file} -r "\ f"'{', '.join(return_columns)}' "\ f" {test_model}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks = load_outputs(out_csv_file) self.assertEqual(set(stocks.columns), set(return_columns)) os.remove(out_csv_file)
def test_initial_conditions_tuple_pysafe_names(self): import pysd model = pysd.read_vensim(test_model) initial_time = 3000 return_timestamps = np.arange(initial_time, initial_time + 10) stocks = model.run(initial_condition=(initial_time, { "teacup_temperature": 33 }), return_timestamps=return_timestamps) command = f"{call} -o {out_tab_file} -I {initial_time} -R "\ f"'{', '.join(return_timestamps.astype(str))}'"\ f" {test_model.replace('.mdl', '.py')}"\ f" teacup_temperature:33" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) stocks2 = load_outputs(out_tab_file) assert_frames_close(stocks2, stocks) os.remove(out_tab_file)