def test_load_components(self): from pysd import read_vensim read_vensim(test_model) # set function for testing executed = [] def set_component(input_dict): executed.append(("SET", input_dict)) # create object components = Components(test_model_py, set_component) # main attributes of the class self.assertTrue(hasattr(components, "_components")) self.assertTrue(hasattr(components, "_set_components")) # check getting elements self.assertEqual(components.room_temperature(), 70) # check setting elements components.room_temperature = 5 self.assertIn(("SET", {"room_temperature": 5}), executed) def temperature(): return 34 components.teacup_temperature = temperature self.assertIn(("SET", {"teacup_temperature": temperature}), executed)
def test_read_vensim_split_model_subviews(self): import pysd from pysd.tools.benchmarking import assert_frames_close root_dir = os.path.join(_root, "more-tests/split_model/") model_name = "test_split_model_subviews" model_name_mdl = root_dir + model_name + ".mdl" model_split = pysd.read_vensim(root_dir + model_name + ".mdl", split_views=True, subview_sep=["."]) namespace_filename = "_namespace_" + model_name + ".json" subscript_filename = "_subscripts_" + model_name + ".json" dependencies_filename = "_dependencies_" + model_name + ".json" modules_dirname = "modules_" + model_name separator = "." command = f"{call} --translate --split-views "\ f"--subview-sep={separator} {model_name_mdl}" out = subprocess.run(split_bash(command), capture_output=True) self.assertEqual(out.returncode, 0) # check that the modules folders were created self.assertTrue(os.path.isdir(root_dir + modules_dirname + "/view_1")) # check creation of module files self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_1/" + "submodule_1.py")) self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_1/" + "submodule_2.py")) self.assertTrue( os.path.isfile(root_dir + modules_dirname + "/view_2.py")) # check that the results of the split model are the same than those # without splitting model_non_split = pysd.read_vensim(root_dir + model_name + ".mdl", split_views=False) result_split = model_split.run() result_non_split = model_non_split.run() # results of a split model are the same that those of the regular # model (un-split) assert_frames_close(result_split, result_non_split, atol=0, rtol=0) # remove newly created files os.remove(root_dir + model_name + ".py") os.remove(root_dir + namespace_filename) os.remove(root_dir + subscript_filename) os.remove(root_dir + dependencies_filename) # remove newly created modules folder shutil.rmtree(root_dir + modules_dirname)
def test_read_vensim_split_model(self, model_file, subview_sep, expected_files, modules, original_vars, py_vars, stateful_objs): # assert that the files don't exist in the temporary directory for file in expected_files: assert not file.is_file(), f"File {file} already exists..." # translate split model model_split = pysd.read_vensim(model_file, split_views=True, subview_sep=subview_sep) # assert that all the files have been created for file in expected_files: assert file.is_file(), f"File {file} has not been created..." # check the dictionaries assert isinstance(model_split.components._namespace, dict) assert isinstance(model_split.components._subscript_dict, dict) assert isinstance(model_split.components._dependencies, dict) assert isinstance(model_split.components._modules, dict) # assert taht main modules are dictionary keys for module in modules: assert module.split("/")[0]\ in model_split.components._modules.keys() # assert that original variables are in the namespace for var in original_vars: assert var in model_split.components._namespace.keys() # assert that the functions are not defined in the main file model_py_file = model_file.with_suffix(".py") with open(model_py_file, 'r') as file: file_content = file.read() for var in py_vars: assert "def %s()" % var not in file_content for var in stateful_objs: assert "%s = " % var not in file_content # translation without splitting model_non_split = pysd.read_vensim(model_file, split_views=False) # assert that the functions are defined in the main file with open(model_py_file, 'r') as file: file_content = file.read() for var in py_vars: assert "def %s()" % var in file_content for var in stateful_objs: assert "%s = " % var in file_content # check that both models give the same result assert_frames_close(model_split.run(), model_non_split.run(), atol=0, rtol=0)
def SD_ReadVensim(filename, AutoSelect=True): if filename.split(".")[-1] == ".py": SDmodel = pysd.load(filename) elif AutoSelect: if os.path.isfile(filename[0:-3] + "py"): SDmodel = pysd.load(filename[0:-3] + "py") print("Auto load existed py file.") else: SDmodel = pysd.read_vensim(filename) else: SDmodel = pysd.read_vensim(filename) return SDmodel
def test_no_crosstalk(self): """ Need to check that if we instantiate two copies of the same model, changes to one copy do not influence the other copy. """ # Todo: this test could be made more comprehensive import pysd model_1 = pysd.read_vensim('test-models/samples/teacup/teacup.mdl') model_2 = pysd.read_vensim('test-models/samples/SIR/SIR.mdl') model_1.components.initial_time = lambda: 10 self.assertNotEqual(model_2.components.initial_time, 10)
def __init__(símismo, archivo, nombre='mds'): ext = os.path.splitext(archivo)[1] if ext == '.mdl': símismo.tipo = '.mdl' símismo.mod = pysd.read_vensim(archivo) elif ext in ['.xmile', '.xml']: símismo.tipo = '.xmile' símismo.mod = pysd.read_xmile(archivo) elif ext == '.py': # Modelos PySD ya traducidos símismo.tipo = '.py' símismo.mod = pysd.load(archivo) else: raise ValueError( _('PySD no sabe leer modelos del formato "{}". Debes darle un modelo ".mdl" o ".xmile".' ).format(ext)) símismo.tipo_mod = None símismo._conv_nombres = {} símismo.tiempo_final = None símismo.cont_simul = False símismo.paso_act = 0 símismo.vars_para_cambiar = {} símismo._res_recién = None # pd.DataFrame super().__init__(archivo, nombre=nombre)
def test_set_initial_condition(self): import pysd model = pysd.read_vensim(test_model) initial_temp = model.components.teacup_temperature() initial_time = model.components.time() new_state = {'Teacup Temperature': 500} new_time = np.random.rand() model.set_initial_condition((new_time, new_state)) set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertNotEqual(set_temp, initial_temp) self.assertEqual(set_temp, 500) self.assertNotEqual(initial_time, new_time) self.assertEqual(new_time, set_time) model.set_initial_condition('original') set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertEqual(initial_temp, set_temp) self.assertEqual(initial_time, set_time)
def test_smooth(self): #re: https://github.com/JamesPHoughton/pysd/issues/18 model = pysd.read_vensim('tests/vensim/test_smooth.mdl') results = model.run( return_columns=['function_output', 'structure_output']) assert_series_equal(results['function_output'], results['structure_output'])
def test_no_param_list_no_bounds(self): model = pysd.read_vensim('test-models/samples/teacup/teacup.mdl') n_samples = 5 samples = pysd.testing.sample_pspace(model=model, samples=n_samples) self.assertSetEqual(set(samples.columns), {'Characteristic Time', 'Room Temperature'})
def ReuseRecycledrawfigs(data): fig, ax = plt.subplots() with open('neighhydro.csv', 'wb') as f: w = csv.DictWriter(f, data.keys()) w.writeheader() w.writerow(data) print data model = pysd.read_vensim ('IWRET_13.mdl') for k,v in data.items(): if v == 'on' or k=='undefined' or k=='formId': del data[k] modeldata=model.run(params=data, return_columns=['RH Total Water Harvested']) glist = ['RH Total Water Harvested','IA Runoff Daily','IA Runoff Total', 'GWS Tank Inflow','Water Reuse Daily','Result RR LCC', 'Result RR GHG Emissions','Result RR Energy'] dict_of_plots=list() x1 = range(7301) y1 = modeldata['LU Sum'] indata=pd.DataFrame(x1,y1) indata.plot(ax=ax) single_chart=dict() single_chart['id']="NeighHyd1" single_chart['json']=json.dumps(mpld3.fig_to_dict(fig)) dict_of_plots.append(single_chart) return render_template("results.html", dict_of_plots=dict_of_plots)#snippet=plot_snippet)
def test_multiple_load(self): """ Test that we can load and run multiple models at the same time, and that the models don't interact with each other. This can happen if we arent careful about class attributes vs instance attributes This test responds to issue: https://github.com/JamesPHoughton/pysd/issues/23 """ import pysd model_1 = pysd.read_vensim('test-models/samples/teacup/teacup.mdl') model_2 = pysd.read_vensim('test-models/samples/SIR/SIR.mdl') self.assertNotIn('teacup_temperature', dir(model_2.components))
def test_set_initial_condition_origin_short(self): import pysd model = pysd.read_vensim(test_model) initial_temp = model.components.teacup_temperature() initial_time = model.components.time() new_state = {'Teacup Temperature': 500} new_time = 10 model.set_initial_condition((new_time, new_state)) set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertNotEqual( set_temp, initial_temp, "Test definition is wrong, please change configuration") self.assertEqual(set_temp, 500) self.assertNotEqual( initial_time, new_time, "Test definition is wrong, please change configuration") self.assertEqual(new_time, set_time) model.set_initial_condition('o') set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertEqual(initial_temp, set_temp) self.assertEqual(initial_time, set_time)
def test_initial_conditions_subscripted_value_with_numpy(self): # test for backward compatibility to remove in the future import warnings import xarray as xr import pysd coords = { 'One Dimensional Subscript': ['Entry 1', 'Entry 2', 'Entry 3'], 'Second Dimension Subscript': ['Column 1', 'Column 2'] } dims = ['One Dimensional Subscript', 'Second Dimension Subscript'] output = xr.DataArray([[5, 3], [4, 8], [9, 3]], coords, dims) input_ = np.array([[5, 3], [4, 8], [9, 3]]) model = pysd.read_vensim(test_model_subs) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") res = model.run(initial_condition=(5, { 'initial_values': input_ }), return_columns=['Initial Values'], return_timestamps=list(range(5, 10))) self.assertTrue(output.equals(res['Initial Values'].iloc[0])) self.assertEqual(res.index[0], 5) self.assertEqual(len(w), 1) self.assertTrue('deprecated' in str(w[0].message))
def __init__(símismo, archivo, nombre='mds'): nmbr, ext = os.path.splitext(archivo) if ext == '.mdl': símismo.tipo = '.mdl' # Únicamente recrear el archivo .py si necesario if os.path.isfile(nmbr + '.py') and (os.path.getmtime(nmbr + '.py') > os.path.getmtime(archivo)): símismo.modelo = pysd.load(nmbr + '.py') else: símismo.modelo = pysd.read_vensim(archivo) elif ext in ['.xmile', '.xml']: símismo.tipo = '.xmile' símismo.modelo = pysd.read_xmile(archivo) elif ext == '.py': # Modelos PySD ya traducidos símismo.tipo = '.py' símismo.modelo = pysd.load(archivo) else: raise ValueError( _('PySD no sabe leer modelos del formato "{}". Debes darle un modelo ".mdl" o ".xmile".' ).format(ext)) símismo._conv_nombres = {} símismo.tiempo_final = None símismo.cont_simul = False símismo.paso_act = 0 símismo.vars_para_cambiar = {} símismo._res_recién = None # pd.DataFrame super().__init__(archivo, nombre=nombre)
def test_set_state_subscripted_value_with_constant(self): import xarray as xr import pysd coords = { 'One Dimensional Subscript': ['Entry 1', 'Entry 2', 'Entry 3'], 'Second Dimension Subscript': ['Column 1', 'Column 2'] } dims = ['One Dimensional Subscript', 'Second Dimension Subscript'] output_b = xr.DataArray([[0, 0], [0, 0], [0, 0]], coords, dims) new_time = np.random.rand() model = pysd.read_vensim(test_model_subs) initial_stock = model.components.stock_a() initial_time = model.components.time() # Test that we can set with real names model.set_state(new_time, {'Stock A': 500}) self.assertFalse(initial_stock.equals(output_b + 500)) self.assertTrue(model.components.stock_a().equals(output_b + 500)) # Test setting with pysafe names model.set_state(new_time + 1, {'stock_a': 202}) self.assertTrue(model.components.stock_a().equals(output_b + 202)) # Test setting with stateful object name model.set_state(new_time + 2, {'_integ_stock_a': 302}) self.assertTrue(model.components.stock_a().equals(output_b + 302))
def test_initial_conditions_tuple_pysafe_names(self): import pysd model = pysd.read_vensim(test_model) stocks = model.run(initial_condition=(3000, {'teacup_temperature': 33}), return_timestamps=list(range(3000, 3010))) self.assertEqual(stocks.index[0], 3000) self.assertEqual(stocks['Teacup Temperature'].iloc[0], 33)
def test_run_return_columns_pysafe_names(self): """Addresses https://github.com/JamesPHoughton/pysd/issues/26""" import pysd model = pysd.read_vensim(test_model) return_columns = ['room_temperature', 'teacup_temperature'] result = model.run(return_columns=return_columns) self.assertEqual(set(result.columns), set(return_columns))
def test_run_ignore_missing(self): import pysd from warnings import catch_warnings model_mdl = 'test-models/tests/get_with_missing_values_xlsx/'\ + 'test_get_with_missing_values_xlsx.mdl' model_py = 'test-models/tests/get_with_missing_values_xlsx/'\ + 'test_get_with_missing_values_xlsx.py' with catch_warnings(record=True) as ws: # warnings for missing values model = pysd.read_vensim(model_mdl, missing_values="ignore") self.assertTrue(all(["missing" not in str(w.message) for w in ws])) with catch_warnings(record=True) as ws: # warnings for missing values model.run() self.assertTrue(all(["missing" not in str(w.message) for w in ws])) with catch_warnings(record=True) as ws: # ignore warnings for missing values model = pysd.load(model_py) self.assertTrue(any(["missing" in str(w.message) for w in ws])) with catch_warnings(record=True) as ws: # ignore warnings for missing values model.run() self.assertTrue(any(["missing" in str(w.message) for w in ws])) with self.assertRaises(ValueError): # errors for missing values pysd.load(model_py, missing_values="raise")
def setUpClass(cls): cls.file_name = 'test_extremes_empty.xls' cls.model_file = 'test-models/tests/variable_ranges/test_variable_ranges.mdl' cls.model = pysd.read_vensim( 'test-models/tests/variable_ranges/test_variable_ranges.mdl') pysd.testing.create_static_test_matrix(cls.model, cls.file_name) cls.filled_file_name = 'test-models/tests/variable_ranges/test_extremes.xls'
def test_set_state_subscripted_value_with_xarray(self): import xarray as xr import pysd coords = { 'One Dimensional Subscript': ['Entry 1', 'Entry 2', 'Entry 3'], 'Second Dimension Subscript': ['Column 1', 'Column 2'] } dims = ['One Dimensional Subscript', 'Second Dimension Subscript'] output1 = xr.DataArray([[5, 3], [4, 8], [9, 3]], coords, dims) output2 = xr.DataArray([[53, 43], [84, 80], [29, 63]], coords, dims) output3 = xr.DataArray([[54, 32], [40, 87], [93, 93]], coords, dims) new_time = np.random.rand() model = pysd.read_vensim(test_model_subs) initial_stock = model.components.stock_a() # Test that we can set with real names model.set_state(new_time, {'Stock A': output1}) self.assertFalse(initial_stock.equals(output1)) self.assertTrue(model.components.stock_a().equals(output1)) # Test setting with pysafe names model.set_state(new_time + 1, {'stock_a': output2}) self.assertTrue(model.components.stock_a().equals(output2)) # Test setting with stateful object name model.set_state(new_time + 2, {'_integ_stock_a': output3}) self.assertTrue(model.components.stock_a().equals(output3))
def test_set_initial_condition_origin_short(self): import pysd model = pysd.read_vensim(test_model) initial_temp = model.components.teacup_temperature() initial_time = model.components.time() new_state = {'Teacup Temperature': 500} new_time = 10 model.set_initial_condition((new_time, new_state)) set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertNotEqual(set_temp, initial_temp, "Test definition is wrong, please change configuration") self.assertEqual(set_temp, 500) self.assertNotEqual(initial_time, new_time, "Test definition is wrong, please change configuration") self.assertEqual(new_time, set_time) model.set_initial_condition('o') set_temp = model.components.teacup_temperature() set_time = model.components.time() self.assertEqual(initial_temp, set_temp) self.assertEqual(initial_time, set_time)
def test_docs(self): """ Test that the model prints some documentation """ import pysd model = pysd.read_vensim(test_model) self.assertIsInstance(str(model), str) # tests string conversion of model doc = model.doc() self.assertIsInstance(doc, pd.DataFrame) self.assertSetEqual( { 'Characteristic Time', 'Teacup Temperature', 'FINAL TIME', 'Heat Loss to Room', 'INITIAL TIME', 'Room Temperature', 'SAVEPER', 'TIME STEP' }, set(doc['Real Name'].values)) self.assertEqual( doc[doc['Real Name'] == 'Heat Loss to Room']['Unit'].values[0], 'Degrees Fahrenheit/Minute') self.assertEqual( doc[doc['Real Name'] == 'Teacup Temperature']['Py Name'].values[0], 'teacup_temperature') self.assertEqual( doc[doc['Real Name'] == 'INITIAL TIME']['Comment'].values[0], 'The initial time for the simulation.') self.assertEqual( doc[doc['Real Name'] == 'Characteristic Time']['Type'].values[0], 'constant') self.assertEqual( doc[doc['Real Name'] == 'Teacup Temperature']['Lims'].values[0], '(32.0, 212.0)')
def test_delay_reinitializes(self): import pysd model = pysd.read_vensim( '../tests/test-models/tests/delays/test_delays.mdl') res1 = model.run() res2 = model.run() self.assertTrue(all(res1 == res2))
def test_set_subscripted_timeseries_parameter_with_partial_xarray(self): import xarray as xr import pysd coords = { 'One Dimensional Subscript': ['Entry 1', 'Entry 2', 'Entry 3'], 'Second Dimension Subscript': ['Column 1', 'Column 2'] } dims = ['One Dimensional Subscript', 'Second Dimension Subscript'] out_b = xr.DataArray([[0, 0], [0, 0], [0, 0]], coords, dims) input_val = xr.DataArray( [5, 3], {'Second Dimension Subscript': ['Column 1', 'Column 2']}, ['Second Dimension Subscript']) model = pysd.read_vensim(test_model_subs) timeseries = list(range(10)) val_series = [ input_val + rd for rd in np.random.rand(len(timeseries)).cumsum() ] temp_timeseries = pd.Series(index=timeseries, data=val_series) out_series = [out_b + val for val in val_series] model.set_components({ 'initial_values': temp_timeseries, 'final_time': 10 }) res = model.run(return_columns=['initial_values']) self.assertTrue( np.all([ r.equals(t) for r, t in zip(res['initial_values'].values, out_series) ]))
def test_set_subscripted_timeseries_parameter_with_xarray(self): import xarray as xr import pysd coords = { 'One Dimensional Subscript': ['Entry 1', 'Entry 2', 'Entry 3'], 'Second Dimension Subscript': ['Column 1', 'Column 2'] } dims = ['One Dimensional Subscript', 'Second Dimension Subscript'] init_val = xr.DataArray([[5, 3], [4, 8], [9, 3]], coords, dims) model = pysd.read_vensim(test_model_subs) timeseries = list(range(10)) temp_timeseries = pd.Series( index=timeseries, data=[ init_val + rd for rd in np.random.rand(len(timeseries)).cumsum() ]) res = model.run(params={ 'initial_values': temp_timeseries, 'final_time': 10 }, return_columns=['initial_values'], return_timestamps=timeseries) self.assertTrue( np.all([ r.equals(t) for r, t in zip(res['initial_values'].values, temp_timeseries.values) ]))
def runner(model_file): directory = os.path.dirname(model_file) # load model if model_file.endswith('.mdl') or model_file.endswith('.MDL'): model = pysd.read_vensim(model_file) elif model_file.endswith(".xmile"): model = pysd.read_xmile(model_file) else: raise AttributeError('Modelfile should be *.mdl or *.xmile') # load canonical output try: encoding = detect_encoding(directory + '/output.csv') canon = pd.read_csv(directory + '/output.csv', encoding=encoding, index_col='Time') except IOError: try: encoding = detect_encoding(directory + '/output.tab') canon = pd.read_table(directory + '/output.tab', encoding=encoding, index_col='Time') except IOError: raise IOError('Canonical output file not found') # run model output = model.run(return_columns=canon.columns) return output, canon
def runner(model_file): directory = os.path.dirname(model_file) # load model if model_file.endswith('.mdl'): model = pysd.read_vensim(model_file) elif model_file.endswith(".xmile"): model = pysd.read_xmile(model_file) else: raise AttributeError('Modelfile should be *.mdl or *.xmile') # load canonical output try: encoding = detect_encoding(directory + '/output.csv') canon = pd.read_csv(directory + '/output.csv', encoding=encoding, index_col='Time') except IOError: try: encoding = detect_encoding(directory + '/output.tab') canon = pd.read_table(directory + '/output.tab', encoding=encoding, index_col='Time') except IOError: raise IOError('Canonical output file not found') # run model output = model.run(return_columns=canon.columns) return output, canon
def test_replace_element(self): import pysd model = pysd.read_vensim(test_model) stocks1 = model.run() model.components.characteristic_time = lambda: 3 stocks2 = model.run() self.assertGreater(stocks1['Teacup Temperature'].loc[10], stocks2['Teacup Temperature'].loc[10])
def test_run_return_columns_original_names(self): """Addresses https://github.com/JamesPHoughton/pysd/issues/26 - Also checks that columns are returned in the correct order""" import pysd model = pysd.read_vensim(test_model) return_columns = ['Room Temperature', 'Teacup Temperature'] result = model.run(return_columns=return_columns) self.assertEqual(set(result.columns), set(return_columns))
def test_set_component_with_real_name(self): import pysd model = pysd.read_vensim(test_model) model.set_components({'Room Temperature': 20}) self.assertEqual(model.components.room_temperature(), 20) model.run(params={'Room Temperature': 70}) self.assertEqual(model.components.room_temperature(), 70)
def test_reset_state(self): import pysd import warnings model = pysd.read_vensim(test_model) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") model.reset_state() self.assertEqual(len(w), 1)
def test_run(self): import pysd model = pysd.read_vensim(test_model) stocks = model.run() self.assertTrue(isinstance(stocks, pd.DataFrame)) # return a dataframe self.assertTrue('Teacup Temperature' in stocks.columns.values) # contains correct column self.assertGreater(len(stocks), 3) # has multiple rows self.assertTrue(stocks.notnull().all().all()) # there are no null values in the set
def test_initial_conditions_current(self): import pysd model = pysd.read_vensim(test_model) stocks1 = model.run(return_timestamps=list(range(0, 31))) stocks2 = model.run(initial_condition='current', return_timestamps=list(range(30, 45))) self.assertEqual(stocks1['Teacup Temperature'].iloc[-1], stocks2['Teacup Temperature'].iloc[0])
def test_initial_conditions_tuple_original_names(self): """ Responds to https://github.com/JamesPHoughton/pysd/issues/77""" import pysd model = pysd.read_vensim(test_model) stocks = model.run(initial_condition=(3000, {'Teacup Temperature': 33}), return_timestamps=list(range(3000, 3010))) self.assertEqual(stocks.index[0], 3000) self.assertEqual(stocks['Teacup Temperature'].iloc[0], 33)
def test_set_constant_parameter(self): """ In response to: re: https://github.com/JamesPHoughton/pysd/issues/5""" import pysd model = pysd.read_vensim(test_model) model.set_components({'room_temperature': 20}) self.assertEqual(model.components.room_temperature(), 20) model.run(params={'room_temperature': 70}) self.assertEqual(model.components.room_temperature(), 70)
def test_set_components_with_function(self): def test_func(): return 5 import pysd model = pysd.read_vensim(test_model) model.set_components({'Room Temperature': test_func}) res = model.run(return_columns=['Room Temperature']) self.assertEqual(test_func(), res['Room Temperature'].iloc[0])
def test__integrate(self): import pysd # Todo: think through a stronger test here... model = pysd.read_vensim(test_model) res = model._integrate(time_steps=list(range(5)), capture_elements=['teacup_temperature'], return_timestamps=list(range(0, 5, 2))) self.assertIsInstance(res, list) self.assertIsInstance(res[0], dict)
def test_run_return_timestamps_past_final_time(self): """ If the user enters a timestamp that is longer than the euler timeseries that is defined by the normal model file, should extend the euler series to the largest timestamp""" import pysd model = pysd.read_vensim(test_model) return_timestamps = list(range(0, 100, 10)) stocks = model.run(return_timestamps=return_timestamps) self.assertSequenceEqual(return_timestamps, list(stocks.index))
def test_return_timestamps_with_range(self): """ Tests that return timestamps may receive a 'range'. It will be cast to a numpy array in the end... """ import pysd model = pysd.read_vensim(test_model) return_timestamps = range(0, 100, 10) stocks = model.run(return_timestamps=return_timestamps) self.assertSequenceEqual(return_timestamps, list(stocks.index))
def test_set_timeseries_parameter(self): import pysd model = pysd.read_vensim(test_model) timeseries = list(range(30)) temp_timeseries = pd.Series(index=timeseries, data=(50 + np.random.rand(len(timeseries)).cumsum())) res = model.run(params={'room_temperature': temp_timeseries}, return_columns=['room_temperature'], return_timestamps=timeseries) self.assertTrue((res['room_temperature'] == temp_timeseries).all())
def test_set_components_warnings(self): """Addresses https://github.com/JamesPHoughton/pysd/issues/80""" import pysd import warnings model = pysd.read_vensim(test_model) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") model.set_components({'Teacup Temperature': 20, 'Characteristic Time': 15}) # set stock value using params self.assertEqual(len(w), 1) self.assertTrue('Teacup Temperature' in str(w[0].message)) # check that warning references the stock
def test_docs(self): """ Test that the model prints some documentation """ import pysd model = pysd.read_vensim(test_model) self.assertIsInstance(str(model), str) # tests string conversion of model doc = model.doc() self.assertIsInstance(doc, pd.DataFrame) self.assertIn('Teacup Temperature', doc['Real Name'].values) self.assertIn('teacup_temperature', doc['Py Name'].values)
def test_initialize(self): import pysd model = pysd.read_vensim(test_model) initial_temp = model.components.teacup_temperature() model.run() final_temp = model.components.teacup_temperature() model.initialize() reset_temp = model.components.teacup_temperature() self.assertNotEqual(initial_temp, final_temp) self.assertEqual(initial_temp, reset_temp)
def test_run_return_timestamps(self): """Addresses https://github.com/JamesPHoughton/pysd/issues/17""" import pysd model = pysd.read_vensim(test_model) timestamps = np.random.rand(5).cumsum() stocks = model.run(return_timestamps=timestamps) self.assertTrue((stocks.index.values == timestamps).all()) stocks = model.run(return_timestamps=5) self.assertEqual(stocks.index[0], 5)
def setUpClass(cls): """ This model has a cosine function that has a period of 1. We can test that the timestep checker throws an error in this situation where the output will be strongly dependent on the timestep """ cls.model = pysd.read_vensim( 'test-models/tests/euler_step_vs_saveper/test_euler_step_vs_saveper.mdl')
def test__build_euler_timeseries(self): import pysd model = pysd.read_vensim(test_model) model.components.initial_time = lambda: 3 model.components.final_time = lambda: 10 model.components.time_step = lambda: 1 model.initialize() actual = list(model._build_euler_timeseries(return_timestamps=[10])) expected = range(3, 11, 1) self.assertSequenceEqual(actual, expected)
def test_no_crosstalk(self): """ Need to check that if we instantiate two copies of the same model, changes to one copy do not influence the other copy. Checks for issue: https://github.com/JamesPHoughton/pysd/issues/108 that time is not shared between the two models """ # Todo: this test could be made more comprehensive import pysd model_1 = pysd.read_vensim('test-models/samples/teacup/teacup.mdl') model_2 = pysd.read_vensim('test-models/samples/SIR/SIR.mdl') model_1.components.initial_time = lambda: 10 self.assertNotEqual(model_2.components.initial_time, 10) # check that the model time is not shared between the two objects model_1.run() self.assertNotEqual(model_1.time(), model_2.time())
def test_incomplete_model(self): import pysd import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") model = pysd.read_vensim( 'test-models/tests/incomplete_equations/test_incomplete_model.mdl') self.assertTrue(any([warn.category == SyntaxWarning for warn in w])) with warnings.catch_warnings(record=True) as w: model.run() self.assertEqual(len(w), 1)
def test_run_reload(self): """ Addresses https://github.com/JamesPHoughton/pysd/issues/99""" import pysd model = pysd.read_vensim(test_model) result0 = model.run() result1 = model.run(params={'Room Temperature': 1000}) result2 = model.run() result3 = model.run(reload=True) self.assertTrue((result0 == result3).all().all()) self.assertFalse((result0 == result1).all().all()) self.assertTrue((result1 == result2).all().all())