def test_prepare_for_model_step(): """ explicitly test to make sure windages are being updated for persistence != 0 and windages are not being changed for persistance == -1 """ time_step = 15 * 60 # seconds model_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, (3., 6., 0.), model_time) sc['windage_persist'][:2] = -1 wind = Wind(timeseries=np.array((model_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(model_time) + time_step * ix) old_windages = np.copy(sc['windages']) wm.prepare_for_model_step(sc, time_step, curr_time) mask = [sc['windage_persist'] == -1] assert np.all(sc['windages'][mask] == old_windages[mask]) mask = [sc['windage_persist'] > 0] assert np.all(sc['windages'][mask] != old_windages[mask])
def test_constant_wind_after_model_time(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A constant wind should extrapolate if it is out of bounds, so prepare_for_model_step() should not fail. We are testing that the wind extrapolates properly, so the windages should be updated in the same way as the in-bounds test ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time wind = Wind(timeseries=np.array((wind_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) print 'curr_time = ', curr_time old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def test_variable_wind_after_model_time(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A variable wind should not extrapolate if it is out of bounds, so prepare_for_model_step() should fail with an exception in this case. ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time time_series = (np.zeros((3, ), dtype=datetime_value_2d) .view(dtype=np.recarray)) time_series.time = [sec_to_date(date_to_sec(wind_time) + self.time_step * i) for i in range(3)] time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.))) wind = Wind(timeseries=time_series.reshape(3), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) with raises(RuntimeError): wm.prepare_for_model_step(self.sc, self.time_step, curr_time)
def test_empty_init(): ''' wind=None ''' wm = WindMover() assert wm.make_default_refs _defaults(wm) assert wm.name == 'WindMover' print wm.validate()
def test_empty_init(): ''' wind=None ''' wm = WindMover() assert wm.make_default_refs _defaults(wm) assert wm.name == 'WindMover' print wm.validate()
def test_active(): """ test that mover must be both active and on to get movement """ time_step = 15 * 60 # seconds start_pos = (3., 6., 0.) rel_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, start_pos, rel_time) # value is given as (r,theta) time_val = np.zeros((1, ), dtype=datetime_value_2d) time_val['time'] = rel_time time_val['value'] = (2., 25.) wm = WindMover(Wind(timeseries=time_val, units='meter per second'), on=False) wm.prepare_for_model_run() wm.prepare_for_model_step(sc, time_step, rel_time) delta = wm.get_move(sc, time_step, rel_time) wm.model_step_is_done() assert wm.active is False assert np.all(delta == 0) # model_time + time_step = active_start
def test_exception_new_from_dict(): # WindMover does not modify Wind object! wm = WindMover(environment.Wind(filename=file_)) wm_state = wm.to_dict('create') wm_state.update({'wind': environment.Wind(filename=file_)}) with pytest.raises(ValueError): WindMover.new_from_dict(wm_state)
def test_serialize_deserialize(wind_circ): """ tests and illustrate the funcitonality of serialize/deserialize for WindMover. """ wind = Wind(filename=file_) wm = WindMover(wind) serial = wm.serialize() assert 'wind' in serial wm2 = wm.deserialize(serial) assert wm == wm2
def test_serialize_deserialize(wind_circ): """ tests and illustrate the funcitonality of serialize/deserialize for WindMover. """ wind = Wind(filename=file_) wm = WindMover(wind) serial = wm.serialize() assert 'wind' in serial wm2 = wm.deserialize(serial) assert wm == wm2
def test_active(): """ test that mover must be both active and on to get movement """ time_step = 15 * 60 # seconds start_pos = (3., 6., 0.) rel_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, start_pos, rel_time) # value is given as (r,theta) time_val = np.zeros((1, ), dtype=datetime_value_2d) time_val['time'] = np.datetime64(rel_time.isoformat()) time_val['value'] = (2., 25.) wm = WindMover(environment.Wind(timeseries=time_val, units='meter per second'), on=False) wm.prepare_for_model_run() wm.prepare_for_model_step(sc, time_step, rel_time) delta = wm.get_move(sc, time_step, rel_time) wm.model_step_is_done() assert wm.active == False assert np.all(delta == 0) # model_time + time_step = active_start
def test_serialize_deserialize(wind_circ): """ tests and illustrate the funcitonality of serialize/deserialize for WindMover. """ wind = Wind(filename=file_) wm = WindMover(wind) serial = wm.serialize('webapi') assert 'wind' in serial dict_ = wm.deserialize(serial) dict_['wind'] = wind_circ['wind'] wm.update_from_dict(dict_) assert wm.wind == wind_circ['wind']
def test_properties(wind_circ): """ test setting the properties of the object """ wm = WindMover(wind_circ['wind']) wm.uncertain_duration = 1 wm.uncertain_time_delay = 2 wm.uncertain_speed_scale = 3 wm.uncertain_angle_scale = 4 assert wm.uncertain_duration == 1 assert wm.uncertain_time_delay == 2 assert wm.uncertain_speed_scale == 3 assert wm.uncertain_angle_scale == 4
def test_data_start_stop(wind_circ): """ test data_start / stop properties """ wm = WindMover(wind_circ['wind']) assert wm.data_start == datetime(2012, 11, 6, 20, 10) assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'initializing the model' start_time = datetime(2012, 9, 15, 12, 0) mapfile = get_datafile(os.path.join(base_dir, './LongIslandSoundMap.BNA')) gnome_map = MapFromBNA(mapfile, refloat_halflife=6) # hours # # the image output renderer # global renderer # one hour timestep model = Model(start_time=start_time, duration=timedelta(hours=48), time_step=3600, map=gnome_map, uncertain=True, cache_enabled=True) netcdf_file = os.path.join(base_dir, 'script_long_island.nc') scripting.remove_netcdf(netcdf_file) print 'adding outputters' model.outputters += Renderer(mapfile, images_dir, size=(800, 600)) model.outputters += NetCDFOutput(netcdf_file, which_data='all') print 'adding a spill' spill = point_line_release_spill(num_elements=1000, start_position=(-72.419992, 41.202120, 0.0), release_time=start_time) model.spills += spill print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=500000, uncertain_factor=2) print 'adding a wind mover:' series = np.zeros((5, ), dtype=datetime_value_2d) series[0] = (start_time, (10, 45)) series[1] = (start_time + timedelta(hours=18), (10, 90)) series[2] = (start_time + timedelta(hours=30), (10, 135)) series[3] = (start_time + timedelta(hours=42), (10, 180)) series[4] = (start_time + timedelta(hours=54), (10, 225)) wind = Wind(timeseries=series, units='m/s') model.movers += WindMover(wind) print 'adding a cats mover:' curr_file = get_datafile(os.path.join(base_dir, r"./LI_tidesWAC.CUR")) tide_file = get_datafile(os.path.join(base_dir, r"./CLISShio.txt")) c_mover = CatsMover(curr_file, tide=Tide(tide_file)) model.movers += c_mover model.environment += c_mover.tide print 'viewport is:', [ o.viewport for o in model.outputters if isinstance(o, Renderer) ] return model
def setup_model(): print 'initializing the model' # start with default time,duration...this will be changed when model is run model = Model( ) #change to use all defaults and set time_step also in Setup_TAP!! mapfile = os.path.join(setup.MapFileDir, setup.MapFileName) print 'adding the map: ', mapfile model.map = MapFromBNA(mapfile, refloat_halflife=0.0) # seconds print 'adding a GridCurrentMover:' c_mover = GridCurrentMover(filename=setup.curr_fn, extrapolate=True) model.movers += c_mover print 'adding a WindMover:' w = Wind(filename=setup.wind_fn) w_mover = WindMover(w) # w_mover = GridWindMover(wind_file=setup.w_filelist) model.movers += w_mover if setup.diff_coef is not None: print 'adding a RandomMover:' random_mover = RandomMover(diffusion_coef=setup.diff_coef) #in cm/s model.movers += random_mover return model
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'creating the maps' mapfile = get_datafile(os.path.join(base_dir, 'LowerMississippiMap.bna')) gnome_map = MapFromBNA(mapfile, refloat_halflife=6) # hours print 'initializing the model' start_time = datetime(2012, 9, 15, 12, 0) # default to now, rounded to the nearest hour model = Model(time_step=600, start_time=start_time, duration=timedelta(days=1), map=gnome_map, uncertain=True) print 'adding outputters' model.outputters += Renderer(mapfile, images_dir, image_size=(800, 600)) netcdf_file = os.path.join(base_dir, 'script_lower_mississippi.nc') scripting.remove_netcdf(netcdf_file) model.outputters += NetCDFOutput(netcdf_file, which_data='all') print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=10000) print 'adding a wind mover:' series = np.zeros((5, ), dtype=datetime_value_2d) series[0] = (start_time, (2, 45)) series[1] = (start_time + timedelta(hours=18), (2, 90)) series[2] = (start_time + timedelta(hours=30), (2, 135)) series[3] = (start_time + timedelta(hours=42), (2, 180)) series[4] = (start_time + timedelta(hours=54), (2, 225)) w_mover = WindMover(Wind(timeseries=series, units='m/s')) model.movers += w_mover print 'adding a cats mover:' curr_file = get_datafile(os.path.join(base_dir, 'LMiss.CUR')) c_mover = CatsMover(curr_file) # but do need to scale (based on river stage) c_mover.scale = True c_mover.scale_refpoint = (-89.699944, 29.494558) # based on stage height 10ft (range is 0-18) c_mover.scale_value = 1.027154 model.movers += c_mover print 'adding a spill' spill = point_line_release_spill(num_elements=1000, start_position=(-89.699944, 29.494558, 0.0), release_time=start_time) model.spills += spill return model
def test_properties(wind_circ): """ test setting the properties of the object """ wm = WindMover(wind_circ['wind']) wm.uncertain_duration = 1 wm.uncertain_time_delay = 2 wm.uncertain_speed_scale = 3 wm.uncertain_angle_scale = 4 assert wm.uncertain_duration == 1 assert wm.uncertain_time_delay == 2 assert wm.uncertain_speed_scale == 3 assert wm.uncertain_angle_scale == 4 assert wm.data_start == datetime(2012, 11, 6, 20, 10) assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
def test_exceptions(): """ Test ValueError exception thrown if improper input arguments """ with raises(ReferencedObjectNotSet) as excinfo: wm = WindMover() wm.prepare_for_model_run() print excinfo.value.message with raises(TypeError): """ violates duck typing so may want to remove. Though current WindMover's backend cython object looks for C++ OSSM object which is embedded in Wind object which is why this check was enforced. Can be re-evaluated if there is a need. """ WindMover(wind=10)
def test_exceptions(): """ Test ValueError exception thrown if improper input arguments """ with raises(ReferencedObjectNotSet) as excinfo: wm = WindMover() wm.prepare_for_model_run() print excinfo.value.message with raises(TypeError): """ violates duck typing so may want to remove. Though current WindMover's backend cython object looks for C++ OSSM object which is embedded in Wind object which is why this check was enforced. Can be re-evaluated if there is a need. """ WindMover(wind=10)
def test_serialize_deserialize(wind_circ, do): """ tests and illustrates the funcitonality of serialize/deserialize for WindMover. """ wind = environment.Wind(filename=file_) wm = WindMover(wind) json_ = wm.serialize(do) if do == 'create': assert 'wind' not in json_ # reference to 'wind' object is made by the Model().save() function # by default 'wind' object is not serialized in 'create' mode # so for this test to work, add the 'wind' key, value back in before # constructing new WindMover. In the real use case, the model does this dict_ = wm.deserialize(json_) dict_['wind'] = wind wm2 = WindMover.new_from_dict(dict_) assert wm == wm2 else: assert 'wind' in json_ wind_update = wind_circ['wind'] json_['wind'] = wind_update.serialize(do) dict_ = wm.deserialize(json_) wm.from_dict(dict_) assert wm.wind == wind_update
def test_array_types(): """ Check the array_types property of WindMover contains array_types.WindMover """ # WindMover does not modify Wind object! wm = WindMover(Wind(filename=file_)) for t in ('windages', 'windage_range', 'windage_persist'): assert t in wm.array_types
def test_wind_mover(): """ use a wind_mover, about as simple as it comes """ # fake data arrays: num = 2 pos_dt = np.dtype([('lon', np.float), ('lat', np.float), ('depth', np.float)]) sc = SC({'positions': np.zeros((num,), dtype=pos_dt), 'status_codes': np.zeros((num,), dtype=np.int16), 'windages': np.zeros((num,)), }) # delta = np.zeros_like(sc['positions']) wind = wind_from_values([(datetime(2016, 5, 10, 12, 0), 5, 45), (datetime(2016, 5, 10, 12, 20), 6, 50), (datetime(2016, 5, 10, 12, 40), 7, 55), ]) wm = WindMover(wind) # in time span, this should work: wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 20)) # before timespan -- this should fail with pytest.raises(RuntimeError): wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) # after timespan -- this should fail with pytest.raises(RuntimeError): wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50)) # # test the message: # try: # wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) # except RuntimeError as err: try: wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) except RuntimeError as err: msg = err.args[0] assert "No available data" in msg assert "WindMover" in msg assert "2016-05-10 11:50:00" in msg assert "2016-05-10 12:00:00" in msg assert "2016-05-10 12:40:00" in msg
def test_new_from_dict(): """ Currently only checks that new object can be created from dict It does not check equality of objects """ wind = environment.Wind(filename=file_) wm = WindMover(wind) # WindMover does not modify Wind object! wm_state = wm.to_dict('create') # must create a Wind object and add this to wm_state dict wind2 = environment.Wind.new_from_dict(wind.to_dict('create')) wm_state.update({'wind': wind2}) wm2 = WindMover.new_from_dict(wm_state) assert wm is not wm2 assert wm.wind is not wm2.wind assert wm == wm2
def test_update_wind(wind_circ): """ Create a wind object and update it's timeseries. Make sure the internal C++ WindMover's properties have also changed """ o_wind = wind_circ['wind'] # original wind value wm = WindMover(o_wind) # define wind mover # update wind timeseries - default format is magnitude_direction t_dtv = np.zeros((3, ), dtype=datetime_value_2d).view(dtype=np.recarray) t_dtv.time = [datetime(2012, 11, 06, 20, 0 + i, 30) for i in range(3)]
def test_timeseries_init(wind_circ): """ test default properties of the object are initialized correctly """ wm = WindMover(wind_circ['wind']) _defaults(wm) assert not wm.make_default_refs cpp_timeseries = _get_timeseries_from_cpp(wm) assert np.all(cpp_timeseries['time'] == wind_circ['uv']['time']) assert np.allclose(cpp_timeseries['value'], wind_circ['uv']['value'], atol, rtol)
def test_callback_add_mover(): 'Test callback after add mover' units = 'meter per second' model = Model() model.start_time = datetime(2012, 1, 1, 0, 0) model.duration = timedelta(hours=10) model.time_step = timedelta(hours=1) # start_loc = (1.0, 2.0, 0.0) # random non-zero starting points # add Movers model.movers += SimpleMover(velocity=(1., -1., 0.)) series = np.array((model.start_time, (10, 45)), dtype=datetime_value_2d).reshape((1, )) model.movers += WindMover(Wind(timeseries=series, units=units)) # this should create a Wind object new_wind = Wind(timeseries=series, units=units) model.environment += new_wind assert new_wind in model.environment assert len(model.environment) == 2 tide_ = Tide(filename=testdata['CatsMover']['tide']) d_file = testdata['CatsMover']['curr'] model.movers += CatsMover(d_file, tide=tide_) model.movers += CatsMover(d_file) for mover in model.movers: assert mover.active_start == inf_datetime.InfDateTime('-inf') assert mover.active_stop == inf_datetime.InfDateTime('inf') if hasattr(mover, 'wind'): assert mover.wind in model.environment if hasattr(mover, 'tide'): if mover.tide is not None: assert mover.tide in model.environment # Add a mover with user defined active_start / active_stop values # - these should not be updated active_on = model.start_time + timedelta(hours=1) active_off = model.start_time + timedelta(hours=4) custom_mover = SimpleMover(velocity=(1., -1., 0.), active_start=active_on, active_stop=active_off) model.movers += custom_mover assert model.movers[custom_mover.id].active_start == active_on assert model.movers[custom_mover.id].active_stop == active_off
def test_prepare_for_model_step(): """ explicitly test to make sure windages are being updated for persistence != 0 and windages are not being changed for persistance == -1 """ time_step = 15 * 60 # seconds model_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, (3., 6., 0.), model_time) sc['windage_persist'][:2] = -1 wind = Wind(timeseries=np.array((model_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(model_time) + time_step * ix) old_windages = np.copy(sc['windages']) wm.prepare_for_model_step(sc, time_step, curr_time) mask = [sc['windage_persist'] == -1] assert np.all(sc['windages'][mask] == old_windages[mask]) mask = [sc['windage_persist'] > 0] assert np.all(sc['windages'][mask] != old_windages[mask])
def test_constant_wind_after_model_time(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A constant wind should extrapolate if it is out of bounds, so prepare_for_model_step() should not fail. We are testing that the wind extrapolates properly, so the windages should be updated in the same way as the in-bounds test ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time wind = Wind(timeseries=np.array((wind_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) print 'curr_time = ', curr_time old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def test_variable_wind_after_model_time(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A variable wind should not extrapolate if it is out of bounds, so prepare_for_model_step() should fail with an exception in this case. ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time time_series = (np.zeros((3, ), dtype=datetime_value_2d) .view(dtype=np.recarray)) time_series.time = [sec_to_date(date_to_sec(wind_time) + self.time_step * i) for i in range(3)] time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.))) wind = Wind(timeseries=time_series.reshape(3), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) with raises(RuntimeError): wm.prepare_for_model_step(self.sc, self.time_step, curr_time)
def test_new_from_dict(): """ Currently only checks that new object can be created from dict It does not check equality of objects """ wind = environment.Wind(filename=file_) wm = WindMover(wind) # WindMover does not modify Wind object! wm_state = wm.to_dict('create') # must create a Wind object and add this to wm_state dict wind2 = environment.Wind.new_from_dict(wind.to_dict('create')) wm_state.update({'wind': wind2}) wm2 = WindMover.new_from_dict(wm_state) # check serializable state is correct assert all([wm.__getattribute__(k) == wm2.__getattribute__(k) for k in WindMover.state.get_names('create') if k != 'wind_id' and k != 'obj_type']) assert wm.wind.id == wm2.wind.id
def test_save_load(save_ref, saveloc_): """ tests and illustrates the functionality of save/load for WindMover """ wind = Wind(filename=file_) wm = WindMover(wind) wm_fname = 'WindMover_save_test.json' refs = None if save_ref: w_fname = 'Wind.json' refs = References() refs.reference(wind, w_fname) wind.save(saveloc_, refs, w_fname) wm.save(saveloc_, references=refs, name=wm_fname) l_refs = References() obj = load(os.path.join(saveloc_, wm_fname), l_refs) assert (obj == wm and obj is not wm) assert (obj.wind == wind and obj.wind is not wind) shutil.rmtree(saveloc_) # clean-up
def test_save_load(save_ref, saveloc_): """ tests and illustrates the functionality of save/load for WindMover """ wind = Wind(filename=file_) wm = WindMover(wind) wm_fname = 'WindMover_save_test.json' refs = None if save_ref: w_fname = 'Wind.json' refs = References() refs.reference(wind, w_fname) wind.save(saveloc_, refs, w_fname) wm.save(saveloc_, references=refs, name=wm_fname) l_refs = References() obj = load(os.path.join(saveloc_, wm_fname), l_refs) assert (obj == wm and obj is not wm) assert (obj.wind == wind and obj.wind is not wind) shutil.rmtree(saveloc_) # clean-up
def test_variable_wind_after_model_time_with_extrapolation(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A variable wind can extrapolate if it is configured to do so, so prepare_for_model_step() should succeed in this case. We are testing that the wind extrapolates properly, so the windages should be updated in the same way as the in-bounds test ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time time_series = (np.zeros((3, ), dtype=datetime_value_2d) .view(dtype=np.recarray)) time_series.time = [sec_to_date(date_to_sec(wind_time) + self.time_step * i) for i in range(3)] time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.))) wind = Wind(timeseries=time_series.reshape(3), extrapolation_is_allowed=True, units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def test_exceptions(): """ Test ValueError exception thrown if improper input arguments """ with pytest.raises(TypeError): WindMover() with pytest.raises(ValueError): WindMover(environment.Wind(filename=file_), uncertain_angle_units='xyz') with pytest.raises(ValueError): wm = WindMover(environment.Wind(filename=file_)) wm.set_uncertain_angle(.4, 'xyz') with pytest.raises(TypeError): """ violates duck typing so may want to remove. Though current WindMover's backend cython object looks for C++ OSSM object which is embedded in environment.Wind object which is why this check was enforced. Can be re-evaluated if there is a need. """ WindMover(wind=10)
def test_windages_updated(self): ''' explicitly test to make sure: - windages are being updated for persistence != 0 and - windages are not being changed for persistance == -1 ''' wind = Wind(timeseries=np.array((self.model_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def make_model(images_dir=os.path.join(base_dir,"images")): print "initializing the model" start_time = datetime(2013, 7, 23, 0) model = Model(start_time = start_time, duration = timedelta(hours=47), # n+1 of data in file time_step = 900, # 4 hr in seconds uncertain = False, ) mapfile = os.path.join(base_dir, './coast.bna') print "adding the map" gnome_map = MapFromBNA(mapfile, refloat_halflife=6) # hours print "adding renderer" model.outputters += Renderer(mapfile, images_dir, size=(1800, 1600)) print "adding a wind mover from a time-series" ## this is wind wind_file=get_datafile(os.path.join(base_dir, 'wind.WND')) wind = Wind(filename=wind_file) w_mover = WindMover(wind) model.movers += w_mover print "adding a current mover:" ## this is currents curr_file = get_datafile(os.path.join(base_dir, 'current.txt')) model.movers += GridCurrentMover(curr_file) ## ## Add some spills (sources of elements) ## print "adding 13 points in a cluster that has some small initial separation as the source of spill" for i in range(len(coor)): aaa=utmToLatLng(14,coor[i][0],coor[i][1],northernHemisphere=True) model.spills += point_line_release_spill(num_elements=1, start_position = (aaa[1],aaa[0], 0.0), release_time = start_time, ) print "adding netcdf output" netcdf_output_file = os.path.join(base_dir,'GNOME_output.nc') scripting.remove_netcdf(netcdf_output_file) model.outputters += NetCDFOutput(netcdf_output_file, which_data='all') return model
def test_windage_index(): """ A very simple test to make sure windage is set for the correct sc if staggered release """ sc = SpillContainer() rel_time = datetime(2013, 1, 1, 0, 0) timestep = 30 for i in range(2): spill = point_line_release_spill(num_elements=5, start_position=(0., 0., 0.), release_time=rel_time + i * timedelta(hours=1), element_type=floating(windage_range=(i * .01 + .01, i * .01 + .01), windage_persist=900) ) sc.spills.add(spill) windage = {'windages': array_types.windages, 'windage_range': array_types.windage_range, 'windage_persist': array_types.windage_persist} sc.prepare_for_model_run(array_types=windage) sc.release_elements(timestep, rel_time) wm = WindMover(environment.ConstantWind(5, 0)) wm.prepare_for_model_step(sc, timestep, rel_time) wm.model_step_is_done() # need this to toggle _windage_is_set_flag def _check_index(sc): ''' internal function for doing the test after windage is set - called twice so made a function ''' # only 1st sc is released for sp in sc.spills: mask = sc.get_spill_mask(sp) if np.any(mask): assert np.all(sc['windages'][mask] == (sp.element_type.initializers["windages"]. windage_range[0])) # only 1st spill is released _check_index(sc) # 1st ASSERT sc.release_elements(timestep, rel_time + timedelta(hours=1)) wm.prepare_for_model_step(sc, timestep, rel_time) _check_index(sc) # 2nd ASSERT
def test_windage_index(): """ A very simple test to make sure windage is set for the correct sc if staggered release """ sc = SpillContainer() rel_time = datetime(2013, 1, 1, 0, 0) timestep = 30 for i in range(2): spill = point_line_release_spill( num_elements=5, start_position=(0., 0., 0.), release_time=rel_time + i * timedelta(hours=1), element_type=floating(windage_range=(i * .01 + .01, i * .01 + .01), windage_persist=900)) sc.spills.add(spill) windage = ['windages', 'windage_range', 'windage_persist'] sc.prepare_for_model_run(array_types=windage) sc.release_elements(timestep, rel_time) wm = WindMover(constant_wind(5, 0)) wm.prepare_for_model_step(sc, timestep, rel_time) wm.model_step_is_done() # need this to toggle _windage_is_set_flag def _check_index(sc): ''' internal function for doing the test after windage is set - called twice so made a function ''' # only 1st sc is released for sp in sc.spills: mask = sc.get_spill_mask(sp) if np.any(mask): assert np.all( sc['windages'][mask] == sp.get('windage_range')[0]) # only 1st spill is released _check_index(sc) # 1st ASSERT sc.release_elements(timestep, rel_time + timedelta(hours=1)) wm.prepare_for_model_step(sc, timestep, rel_time) _check_index(sc) # 2nd ASSERT
def test_properties(wind_circ): """ test setting the properties of the object """ wm = WindMover(wind_circ['wind']) wm.uncertain_duration = 1 wm.uncertain_time_delay = 2 wm.uncertain_speed_scale = 3 wm.set_uncertain_angle(4, 'deg') assert wm.uncertain_duration == 1 assert wm.uncertain_time_delay == 2 assert wm.uncertain_speed_scale == 3 assert wm.uncertain_angle_scale == 4 assert wm.uncertain_angle_units == 'deg' wm.set_uncertain_angle(.04, 'rad') assert wm.uncertain_angle_scale == 0.04 assert wm.uncertain_angle_units == 'rad'
def test_serialize_deserialize(wind_circ): """ tests and illustrate the funcitonality of serialize/deserialize for WindMover. """ wind = Wind(filename=file_) wm = WindMover(wind) serial = wm.serialize('webapi') assert 'wind' in serial dict_ = wm.deserialize(serial) dict_['wind'] = wind_circ['wind'] wm.update_from_dict(dict_) assert wm.wind == wind_circ['wind']
def test_properties(wind_circ): """ test setting the properties of the object """ wm = WindMover(wind_circ['wind']) wm.uncertain_duration = 1 wm.uncertain_time_delay = 2 wm.uncertain_speed_scale = 3 wm.uncertain_angle_scale = 4 assert wm.uncertain_duration == 1 assert wm.uncertain_time_delay == 2 assert wm.uncertain_speed_scale == 3 assert wm.uncertain_angle_scale == 4
def make_model(images_dir): print 'initializing the model' timestep = timedelta(minutes=15) # this is already default start_time = datetime(2012, 9, 15, 12, 0) model = Model(timestep, start_time) # timeseries for wind data. The value is interpolated if time is between # the given datapoints series = np.zeros((4, ), dtype=datetime_value_2d) series[:] = [(start_time, (5, 180)), (start_time + timedelta(hours=6), (10, 180)), (start_time + timedelta(hours=12), (12, 180)), (start_time + timedelta(hours=18), (8, 180))] wind = Wind(timeseries=series, units='m/s') model.environment += wind # include a wind mover and random diffusion print 'adding movers' model.movers += [WindMover(wind), RandomMover()] # add particles print 'adding particles' release = release_from_splot_data(start_time, 'GL.2013267._LE_WHOLELAKE.txt') model.spills += Spill(release) # output data as png images and in netcdf format print 'adding outputters' netcdf_file = os.path.join(base_dir, 'script_example.nc') # ignore renderer for now model.outputters += [ Renderer(images_dir=images_dir, size=(800, 800), projection_class=GeoProjection), NetCDFOutput(netcdf_file) ] print 'model complete' return model
def test_properties(wind_circ): """ test setting the properties of the object """ wm = WindMover(wind_circ['wind']) wm.uncertain_duration = 1 wm.uncertain_time_delay = 2 wm.uncertain_speed_scale = 3 wm.uncertain_angle_scale = 4 assert wm.uncertain_duration == 1 assert wm.uncertain_time_delay == 2 assert wm.uncertain_speed_scale == 3 assert wm.uncertain_angle_scale == 4 assert wm.data_start == datetime(2012, 11, 6, 20, 10) assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
def test_read_file_init(): """ initialize from a long wind file """ wind = Wind(filename=file_) wm = WindMover(wind) wind_ts = wind.get_wind_data(coord_sys='uv', units='meter per second') _defaults(wm) # check defaults set correctly assert not wm.make_default_refs cpp_timeseries = _get_timeseries_from_cpp(wm) _assert_timeseries_equivalence(cpp_timeseries, wind_ts) # make sure default units is correct and correctly called # NOTE: Following functionality is already tested in test_wind.py, # but what the heck - do it here too. wind_ts = wind.get_wind_data(coord_sys=ts_format.uv) cpp_timeseries['value'] = uc.convert('Velocity', 'meter per second', wind.units, cpp_timeseries['value']) _assert_timeseries_equivalence(cpp_timeseries, wind_ts)
def test_model_release_after_start(): ''' This runs the model for a simple spill, that starts after the model starts ''' units = 'meter per second' seconds_in_minute = 60 start_time = datetime(2013, 2, 22, 0) model = Model(time_step=30 * seconds_in_minute, start_time=start_time, duration=timedelta(hours=3)) # add a spill that starts after the run begins. release_time = start_time + timedelta(hours=1) model.spills += point_line_release_spill(num_elements=5, start_position=(0, 0, 0), release_time=release_time) # and another that starts later.. model.spills += point_line_release_spill(num_elements=4, start_position=(0, 0, 0), release_time=(start_time + timedelta(hours=2))) # Add a Wind mover: series = np.array((start_time, (10, 45)), dtype=datetime_value_2d).reshape( (1, )) model.movers += WindMover(Wind(timeseries=series, units=units)) for step in model: print 'running a step' assert step['step_num'] == model.current_time_step for sc in model.spills.items(): print 'num_LEs', len(sc['positions'])
def test_variable_wind_after_model_time_with_extrapolation(self): ''' test to make sure the wind mover is behaving properly with out-of-bounds winds. A variable wind can extrapolate if it is configured to do so, so prepare_for_model_step() should succeed in this case. We are testing that the wind extrapolates properly, so the windages should be updated in the same way as the in-bounds test ''' wind_time = datetime(2012, 8, 21, 13) # one day after model time time_series = (np.zeros((3, ), dtype=datetime_value_2d) .view(dtype=np.recarray)) time_series.time = [sec_to_date(date_to_sec(wind_time) + self.time_step * i) for i in range(3)] time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.))) wind = Wind(timeseries=time_series.reshape(3), extrapolation_is_allowed=True, units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def test_windages_updated(self): ''' explicitly test to make sure: - windages are being updated for persistence != 0 and - windages are not being changed for persistance == -1 ''' wind = Wind(timeseries=np.array((self.model_time, (2., 25.)), dtype=datetime_value_2d).reshape(1), units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) old_windages = np.copy(self.sc['windages']) wm.prepare_for_model_step(self.sc, self.time_step, curr_time) mask = self.sc['windage_persist'] == -1 assert np.all(self.sc['windages'][mask] == old_windages[mask]) mask = self.sc['windage_persist'] > 0 assert np.all(self.sc['windages'][mask] != old_windages[mask])
def make_model(images_dir=os.path.join(base_dir, 'images')): # create the maps: print 'creating the maps' mapfile = get_datafile(os.path.join(base_dir, 'SanJuanMap.bna')) gnome_map = MapFromBNA(mapfile, refloat_halflife=1, raster_size=1024 * 1024) renderer = Renderer(mapfile, images_dir, size=(800, 800), projection_class=GeoProjection) renderer.viewport = ((-66.24, 18.39), (-66.1, 18.55)) print 'initializing the model' start_time = datetime(2014, 9, 3, 13, 0) # 15 minutes in seconds # Default to now, rounded to the nearest hour model = Model(time_step=900, start_time=start_time, duration=timedelta(days=1), map=gnome_map, uncertain=False) print 'adding outputters' model.outputters += renderer netcdf_file = os.path.join(base_dir, 'script_san_juan.nc') scripting.remove_netcdf(netcdf_file) model.outputters += NetCDFOutput(netcdf_file, which_data='all') print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=100000) print 'adding a wind mover:' series = np.zeros((2, ), dtype=datetime_value_2d) series[0] = (start_time, (0, 270)) series[1] = (start_time + timedelta(hours=18), (0, 270)) wind = Wind(timeseries=series, units='m/s') w_mover = WindMover(wind) w_mover.extrapolate = True model.movers += w_mover print 'adding a cats shio mover:' # need to add the scale_factor for the tide heights file curr_file = get_datafile(os.path.join(base_dir, 'EbbTides.cur')) tide_file = get_datafile(os.path.join(base_dir, 'EbbTidesShioHt.txt')) c_mover = CatsMover(curr_file, tide=Tide(tide_file, scale_factor=.15)) # this is the value in the file (default) c_mover.scale_refpoint = (-66.116667, 18.458333) c_mover.scale = True c_mover.scale_value = 1.0 # c_mover.tide.scale_factor = 0.15 model.movers += c_mover print 'adding a cats mover:' curr_file = get_datafile(os.path.join(base_dir, 'Offshore.cur')) c_mover = CatsMover(curr_file) # this is the value in the file (default) # c_mover.scale_refpoint = (-66.082836, 18.469334) c_mover.scale_refpoint = (-66.084333333, 18.46966667) c_mover.scale = True c_mover.scale_value = 0.1 model.movers += c_mover print 'adding a spill' end_time = start_time + timedelta(hours=12) spill = point_line_release_spill(num_elements=1000, release_time=start_time, start_position=(-66.16374, 18.468054, 0.0), # start_position=(-66.129099, # 18.465332, 0.0), # end_release_time=end_time, ) model.spills += spill return model
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'initializing the model' start_time = datetime(2004, 12, 31, 13, 0) # 1 day of data in file # 1/2 hr in seconds model = Model(start_time=start_time, duration=timedelta(days=1), time_step=30 * 60, uncertain=True) mapfile = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.bna')) print 'adding the map' model.map = MapFromBNA(mapfile, refloat_halflife=1) # seconds # draw_ontop can be 'uncertain' or 'forecast' # 'forecast' LEs are in black, and 'uncertain' are in red # default is 'forecast' LEs draw on top renderer = Renderer(mapfile, images_dir, size=(800, 600), output_timestep=timedelta(hours=2), draw_ontop='forecast') # set the viewport to zoom in on the map: renderer.viewport = ((-76.5, 37.), (-75.8, 38.)) # add the raster map, so we can see it... # note: this is really slow, so only use for diagnostics # renderer.raster_map = model.map print 'adding outputters' model.outputters += renderer netcdf_file = os.path.join(base_dir, 'script_chesapeake_bay.nc') scripting.remove_netcdf(netcdf_file) model.outputters += NetCDFOutput(netcdf_file, which_data='all', output_timestep=timedelta(hours=2)) print 'adding a spill' # for now subsurface spill stays on initial layer # - will need diffusion and rise velocity # - wind doesn't act # - start_position = (-76.126872, 37.680952, 5.0), spill = point_line_release_spill(num_elements=1000, start_position=(-76.126872, 37.680952, 0.0), release_time=start_time) model.spills += spill print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=50000) print 'adding a wind mover:' series = np.zeros((2, ), dtype=datetime_value_2d) series[0] = (start_time, (30, 0)) series[1] = (start_time + timedelta(hours=23), (30, 0)) wind = Wind(timeseries=series, units='knot') # default is .4 radians w_mover = WindMover(wind, uncertain_angle_scale=0) w_mover.extrapolate=True model.movers += w_mover print 'adding a current mover:' curr_file = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.nc')) topology_file = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.dat')) # uncertain_time_delay in hours c_mover = GridCurrentMover(curr_file, topology_file, uncertain_time_delay=3) c_mover.uncertain_along = 0 # default is .5 # c_mover.uncertain_cross = 0 # default is .25 model.movers += c_mover return model
def test_timespan(): """ Ensure the active flag is being set correctly and checked, such that if active=False, the delta produced by get_move = 0 """ time_step = 15 * 60 # seconds start_pos = (3., 6., 0.) rel_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, start_pos, rel_time) # value is given as (r,theta) model_time = rel_time time_val = np.zeros((1, ), dtype=datetime_value_2d) time_val['time'] = rel_time time_val['value'] = (2., 25.) wm = WindMover(Wind(timeseries=time_val, units='meter per second'), active_start=model_time + timedelta(seconds=time_step)) wm.prepare_for_model_run() wm.prepare_for_model_step(sc, time_step, model_time) delta = wm.get_move(sc, time_step, model_time) wm.model_step_is_done() assert wm.active is False assert np.all(delta == 0) # model_time + time_step = active_start wm.active_start = model_time - timedelta(seconds=time_step / 2) wm.prepare_for_model_step(sc, time_step, model_time) delta = wm.get_move(sc, time_step, model_time) wm.model_step_is_done() assert wm.active is True print '''\ntest_timespan delta \n{0}'''.format(delta) assert np.all(delta[:, :2] != 0) # model_time + time_step > active_start
class TestWindMover: """ gnome.WindMover() test """ time_step = 15 * 60 # seconds model_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, (3., 6., 0.), model_time) time_val = np.array((model_time, (2., 25.)), dtype=datetime_value_2d).reshape(1) wind = Wind(timeseries=time_val, units='meter per second') wm = WindMover(wind) wm.prepare_for_model_run() def test_string_repr_no_errors(self): print print '======================' print 'repr(WindMover): ' print repr(self.wm) print print 'str(WindMover): ' print str(self.wm) assert True def test_get_move(self): """ Test the get_move(...) results in WindMover match the expected delta """ for ix in range(2): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step * ix) self.wm.prepare_for_model_step(self.sc, self.time_step, curr_time) delta = self.wm.get_move(self.sc, self.time_step, curr_time) actual = self._expected_move() # the results should be independent of model time tol = 1e-8 msg = ('{0} is not within a tolerance of ' '{1}'.format('WindMover.get_move()', tol)) np.testing.assert_allclose(delta, actual, tol, tol, msg, 0) assert self.wm.active ts = date_to_sec(curr_time) - date_to_sec(self.model_time) print ('Time step [sec]:\t{0}' 'C++ delta-move:\n{1}' 'Expected delta-move:\n{2}' ''.format(ts, delta, actual)) self.wm.model_step_is_done() def test_get_move_exceptions(self): curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step) tmp_windages = self.sc._data_arrays['windages'] del self.sc._data_arrays['windages'] with raises(KeyError): self.wm.get_move(self.sc, self.time_step, curr_time) self.sc._data_arrays['windages'] = tmp_windages def test_update_wind_vel(self): self.time_val['value'] = (1., 120.) # now given as (r, theta) self.wind.set_wind_data(self.time_val, units='meter per second') self.test_get_move() self.test_get_move_exceptions() def _expected_move(self): """ Put the expected move logic in separate (fixture) if it gets used multiple times """ uv = r_theta_to_uv_wind(self.time_val['value']) exp = np.zeros((self.sc.num_released, 3)) exp[:, 0] = self.sc['windages'] * uv[0, 0] * self.time_step exp[:, 1] = self.sc['windages'] * uv[0, 1] * self.time_step xform = FlatEarthProjection.meters_to_lonlat(exp, self.sc['positions']) return xform
def test_timespan(): """ Ensure the active flag is being set correctly and checked, such that if active=False, the delta produced by get_move = 0 """ time_step = 15 * 60 # seconds start_pos = (3., 6., 0.) rel_time = datetime(2012, 8, 20, 13) # yyyy/month/day/hr/min/sec sc = sample_sc_release(5, start_pos, rel_time) # value is given as (r,theta) model_time = rel_time time_val = np.zeros((1, ), dtype=datetime_value_2d) time_val['time'] = np.datetime64(rel_time.isoformat()) time_val['value'] = (2., 25.) wm = WindMover(environment.Wind(timeseries=time_val, units='meter per second'), active_start=model_time + timedelta(seconds=time_step)) wm.prepare_for_model_run() wm.prepare_for_model_step(sc, time_step, model_time) delta = wm.get_move(sc, time_step, model_time) wm.model_step_is_done() assert wm.active == False assert np.all(delta == 0) # model_time + time_step = active_start wm.active_start = model_time - timedelta(seconds=time_step / 2) wm.prepare_for_model_step(sc, time_step, model_time) delta = wm.get_move(sc, time_step, model_time) wm.model_step_is_done() assert wm.active == True print '''\ntest_timespan delta \n{0}'''.format(delta) assert np.all(delta[:, :2] != 0) # model_time + time_step > active_start
def make_model(uncertain=False, mode='gnome'): ''' Create a model from the data in sample_data/boston_data It contains: - the GeoProjection - wind mover - random mover - cats shio mover - cats ossm mover - plain cats mover ''' start_time = datetime(2013, 2, 13, 9, 0) model = Model(start_time=start_time, duration=timedelta(days=2), time_step=timedelta(minutes=30).total_seconds(), uncertain=uncertain, map=MapFromBNA(testdata['boston_data']['map'], refloat_halflife=1), mode=mode) print 'adding a spill' start_position = (144.664166, 13.441944, 0.0) end_release_time = start_time + timedelta(hours=6) spill_amount = 1000.0 spill_units = 'kg' model.spills += point_line_release_spill(num_elements=1000, start_position=start_position, release_time=start_time, end_release_time=end_release_time, amount=spill_amount, units=spill_units, substance=test_oil) spill = model.spills[-1] spill_volume = spill.get_mass() / spill.substance.density_at_temp() # need a scenario for SimpleMover # model.movers += SimpleMover(velocity=(1.0, -1.0, 0.0)) print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=100000) print 'adding a wind mover:' series = np.zeros((2, ), dtype=datetime_value_2d) series[0] = (start_time, (5, 180)) series[1] = (start_time + timedelta(hours=18), (5, 180)) w_mover = WindMover(Wind(timeseries=series, units='m/s')) model.movers += w_mover model.environment += w_mover.wind print 'adding a cats shio mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr2'], tide=Tide(testdata['boston_data']['cats_shio'])) # c_mover.scale_refpoint should automatically get set from tide object c_mover.scale = True # default value c_mover.scale_value = -1 # tide object automatically gets added by model model.movers += c_mover print 'adding a cats ossm mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr2'], tide=Tide(testdata['boston_data']['cats_ossm'])) c_mover.scale = True # but do need to scale (based on river stage) c_mover.scale_refpoint = (-70.65, 42.58333, 0.0) c_mover.scale_value = 1. print 'adding a cats mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr3']) c_mover.scale = True # but do need to scale (based on river stage) c_mover.scale_refpoint = (-70.78333, 42.39333, 0.0) # the scale factor is 0 if user inputs no sewage outfall effects c_mover.scale_value = .04 model.movers += c_mover # TODO: seg faulting for component mover - comment test for now # print "adding a component mover:" # comp_mover = ComponentMover(testdata['boston_data']['component_curr1'], # testdata['boston_data']['component_curr2'], # w_mover.wind) # TODO: callback did not work correctly below - fix! # comp_mover = ComponentMover(component_file1, # component_file2, # Wind(timeseries=series, units='m/s')) # comp_mover.ref_point = (-70.855, 42.275) # comp_mover.pat1_angle = 315 # comp_mover.pat1_speed = 19.44 # comp_mover.pat1_speed_units = 1 # comp_mover.pat1ScaleToValue = .138855 # comp_mover.pat2_angle = 225 # comp_mover.pat2_speed = 19.44 # comp_mover.pat2_speed_units = 1 # comp_mover.pat2ScaleToValue = .05121 # model.movers += comp_mover print 'adding a Weatherer' model.environment += Water(311.15) skim_start = start_time + timedelta(hours=3) model.weatherers += [ Evaporation(), Skimmer(spill_amount * .5, spill_units, efficiency=.3, active_range=(skim_start, skim_start + timedelta(hours=2))), Burn(0.2 * spill_volume, 1.0, (skim_start, InfDateTime('inf')), efficiency=0.9) ] model.outputters += \ CurrentJsonOutput(model.find_by_attr('_ref_as', 'current_movers', model.movers, allitems=True)) return model
def test_wind_mover(): ''' Use a wind_mover, about as simple as it comes - We are moving to a design where the environment objects contain the extrapolate flag instead of the movers. This flag is off by default. ''' # fake data arrays: num = 2 pos_dt = np.dtype([('lon', np.float), ('lat', np.float), ('depth', np.float)]) sc = SC({'positions': np.zeros((num,), dtype=pos_dt), 'status_codes': np.zeros((num,), dtype=np.int16), 'windages': np.zeros((num,)), }) wind = wind_from_values([(datetime(2016, 5, 10, 12, 0), 5, 45), (datetime(2016, 5, 10, 12, 20), 6, 50), (datetime(2016, 5, 10, 12, 40), 7, 55), ]) wm = WindMover(wind) # within the model's time span, this should work: wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 20)) # before time span -- this should fail with pytest.raises(RuntimeError): wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) # after time span -- this should fail with pytest.raises(RuntimeError): wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50)) # turn on extrapolation in the wind environment object wind.extrapolation_is_allowed = True # before timespan -- this should pass now wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) # after timespan -- this should pass now wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50)) # test the error message that we get when a RuntimeError is raised. with pytest.raises(RuntimeError): try: wind.extrapolation_is_allowed = False wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50)) except RuntimeError as err: msg = err.args[0] assert "No available data" in msg assert "WindMover" in msg assert "2016-05-10 11:50:00" in msg assert "2016-05-10 12:00:00" in msg assert "2016-05-10 12:40:00" in msg raise