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_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_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_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_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_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_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_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_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_range=(model_time + timedelta(seconds=time_step), InfDateTime('inf'))) 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_range = (model_time - timedelta(seconds=time_step / 2), InfDateTime('inf')) 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
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_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 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 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_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