def test_uncertainty(): sp = sample_sc_release(num_elements=1000, start_pos=(0.0, 0.0, 0.0)) u_sp = sample_sc_release(num_elements=1000, start_pos=(0.0, 0.0, 0.0), uncertain=True) mover = simple_mover.SimpleMover(velocity=(10.0, 10.0, 0.0)) delta = mover.get_move(sp, time_step=100, model_time=None) u_delta = mover.get_move(u_sp, time_step=100, model_time=None) # expected = np.zeros_like(delta) expected = proj.meters_to_lonlat((1000.0, 1000.0, 0.0), (0.0, 0.0, 0.0)) assert np.alltrue(delta == expected) # but uncertain spills should be different: assert not np.alltrue(u_delta == expected) # the mean should be close: # this is teh smallest tolerance that consitantly passed -- good enough? assert np.allclose(np.mean(delta, 0), np.mean(u_delta, 0), rtol=1.7e-1)
def test_render_beached_elements(): """ Should this test be in map_canvas? """ input_file = os.path.join(data_dir, r"MapBounds_2Spillable2Islands2Lakes.bna") r = Renderer(input_file, output_dir, image_size=(800, 600)) BB = r.map_BB (min_lon, min_lat) = BB[0] (max_lon, max_lat) = BB[1] N = 100 # create some random particle positions: lon = random.uniform(min_lon, max_lon, (N, )) lat = random.uniform(min_lat, max_lat, (N, )) # create a sc sc = sample_sc_release(num_elements=N) sc['positions'][:, 0] = lon sc['positions'][:, 1] = lat # make half of them on land sc['status_codes'][::2] = oil_status.on_land r.create_foreground_image() r.draw_elements(sc) # create an uncertainty sc lon = random.uniform(min_lon, max_lon, (N, )) lat = random.uniform(min_lat, max_lat, (N, )) sc = sample_sc_release(num_elements=N, uncertain=True) sc['positions'][:, 0] = lon sc['positions'][:, 1] = lat # make half of them on land sc['status_codes'][::2] = oil_status.on_land r.draw_elements(sc) # save the image r.save_foreground(os.path.join(output_dir, 'foreground2.png')) assert True
def test_some_cross_array(self): """ test a few LEs """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours # one left to right # one right to left # diagonal that doesn't hit # diagonal that does hit spill = sample_sc_release(4) spill['positions'] = np.array(((5.0, 5.0, 0.), (15.0, 5.0, 0.), (0., 0., 0.), (19.0, 0., 0.)), dtype=np.float64) spill['next_positions'] = np.array(((9.0, 5.0, 0.), (11.0, 5.0, 0.), (9.0, 9.0, 0.), (0., 9.0, 0.)), dtype=np.float64) gmap.beach_elements(spill) assert np.array_equal(spill['next_positions'], ((9.0, 5.0, 0.), (11.0, 5.0, 0.), (9.0, 9.0, 0.), (10.0, 4.0, 0.))) # just the beached ones assert np.array_equal((spill['last_water_positions'])[3:], ((11.0, 4.0, 0.), )) assert np.array_equal((spill['status_codes'])[3:], (oil_status.on_land, ))
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_mover(): """ tests the constant_wind_mover utility function """ with pytest.raises(Exception): # it should raise an InvalidUnitError, but I don't want to have to # import unit_conversion just for that... wm = constant_wind_mover(10, 45, units='some_random_string') wm = constant_wind_mover(10, 45, units='m/s') sc = sample_sc_release(1) print wm print repr(wm.wind) print wm.wind.get_timeseries() time_step = 1000 model_time = datetime(2013, 3, 1, 0) wm.prepare_for_model_step(sc, time_step, model_time) delta = wm.get_move(sc, time_step, model_time) print 'delta:', delta # 45 degree wind at the equator -- u,v should be the same assert delta[0][0] == delta[0][1]
def test_starts_on_land(self): """ try a single LE that starts on land it last water position should be the same point. """ gmap = RasterMap(refloat_halflife=6, raster=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) spill = sample_sc_release(1) spill['positions'] = np.array(((10.0, 5.0, 0.), ), dtype=np.float64) spill['last_water_positions'] = np.array(((0.0, 0.0, 0.), ), dtype=np.float64) spill['next_positions'] = np.array(((15.0, 5.0, 0.), ), dtype=np.float64) spill['status_codes'] = np.array((oil_status.in_water, ), dtype=status_code_type) gmap.beach_elements(spill) # next position gets set to land location assert np.array_equal(spill['next_positions'][0], (10.0, 5.0, 0.)) assert np.array_equal(spill['last_water_positions'][0], (10.0, 5.0, 0.)) assert spill['status_codes'][0] == oil_status.on_land
def test_land_cross(self): """ try a single LE that should be crossing land """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours spill = sample_sc_release(1) spill['positions'] = np.array(((5.0, 5.0, 0.), ), dtype=np.float64) spill['next_positions'] = np.array(((15.0, 5.0, 0.), ), dtype=np.float64) spill['status_codes'] = np.array((oil_status.in_water, ), dtype=status_code_type) gmap.beach_elements(spill) assert np.array_equal(spill['next_positions'][0], (10.0, 5.0, 0.)) assert np.array_equal(spill['last_water_positions'][0], (9.0, 5.0, 0.)) assert spill['status_codes'][0] == oil_status.on_land
def test_starts_on_land(self): """ try a single LE that starts on land it last water position should be the same point. """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours spill = sample_sc_release(1) spill['positions'] = np.array(((10.0, 5.0, 0.), ), dtype=np.float64) spill['last_water_positions'] = np.array(((0.0, 0.0, 0.), ), dtype=np.float64) spill['next_positions'] = np.array(((15.0, 5.0, 0.), ), dtype=np.float64) spill['status_codes'] = np.array((oil_status.in_water, ), dtype=status_code_type) gmap.beach_elements(spill) ## next position gets set to land location assert np.array_equal(spill['next_positions'][0], (10.0, 5.0, 0.)) assert np.array_equal(spill['last_water_positions'][0], (10.0, 5.0, 0.)) assert spill['status_codes'][0] == oil_status.on_land
def test_land_cross_array(self): """ test a few LEs """ gmap = RasterMap(refloat_halflife=6, raster=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # one left to right # one right to left # one diagonal upper left to lower right # one diagonal upper right to lower left spill = sample_sc_release(4) spill['positions'] = np.array( ((5.0, 5.0, 0.), (15.0, 5.0, 0.), (0., 0., 0.), (19.0, 0., 0.)), dtype=np.float64) spill['next_positions'] = np.array( ((15.0, 5.0, 0.), (5.0, 5.0, 0.), (10.0, 5.0, 0.), (0., 9.0, 0.)), dtype=np.float64) gmap.beach_elements(spill) assert np.array_equal(spill['next_positions'], ((10.0, 5.0, 0.), (10.0, 5.0, 0.), (10.0, 5.0, 0.), (10.0, 4.0, 0.))) assert np.array_equal(spill['last_water_positions'], ((9.0, 5.0, 0.), (11.0, 5.0, 0.), (9.0, 4.0, 0.), (11.0, 4.0, 0.))) assert np.alltrue(spill['status_codes'] == oil_status.on_land)
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_data_setting_new(): """ Can add a new item to data_arrays. This will automatically update SpillContainer's array_types dict No rewind necessary. Subsequent releases will initialize the newly added numpy array for newly released particles """ spill = point_line_release_spill(20, start_position, release_time, end_release_time=end_release_time) # release 10 particles time_step = (end_release_time - release_time) / 2 sc = sample_sc_release(time_step=time_step.seconds, spill=spill) released = sc.num_released new_arr = np.ones((sc.num_released, 3), dtype=np.float64) sc['new_name'] = new_arr assert 'new_name' in sc.data_arrays assert 'new_name' in sc.array_types assert sc['new_name'] is new_arr assert sc.array_types['new_name'].name == 'new_name' assert_dataarray_shape_size(sc) # now release remaining particles and check to see new_name is populated # with zeros - default initial_value sc.release_elements(time_step.seconds, spill.release.release_time + time_step) new_released = sc.num_released - released assert_dataarray_shape_size(sc) # shape is consistent for all arrays assert sc.num_released == spill.release.num_elements # release all elems assert np.all(sc['new_name'][-new_released:] == # initialized to 0! (0.0, 0.0, 0.0))
def test_land_cross_array(self): """ test a few LEs """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours # one left to right # one right to left # one diagonal upper left to lower right # one diagonal upper right to lower left spill = sample_sc_release(4) spill['positions'] = np.array(((5.0, 5.0, 0.), (15.0, 5.0, 0.), (0., 0., 0.), (19.0, 0., 0.)), dtype=np.float64) spill['next_positions'] = np.array(((15.0, 5.0, 0.), (5.0, 5.0, 0.), (10.0, 5.0, 0.), (0., 9.0, 0.)), dtype=np.float64) gmap.beach_elements(spill) assert np.array_equal(spill['next_positions'], ((10.0, 5.0, 0.), (10.0, 5.0, 0.), (10.0, 5.0, 0.), (10.0, 4.0, 0.))) assert np.array_equal(spill['last_water_positions'], ((9.0, 5.0, 0.), (11.0, 5.0, 0.), (9.0, 4.0, 0.), (11.0, 4.0, 0.))) assert np.alltrue(spill['status_codes'] == oil_status.on_land)
def test_data_access(): sc = sample_sc_release() sc['positions'] += (3.0, 3.0, 3.0) assert np.array_equal(sc['positions'], np.ones((sc.num_released, 3), dtype=world_point_type) * 3.0)
def test_data_access(): sc = sample_sc_release() sc['positions'] += (3.0, 3.0, 3.0) assert np.array_equal( sc['positions'], np.ones((sc.num_released, 3), dtype=world_point_type) * 3.0)
def test_prepare_for_model_step(self): """ Simply tests the method executes without exceptions """ pSpill = sample_sc_release(self.num_le, self.start_pos) self.mover.prepare_for_model_step(pSpill, self.time_step, self.model_time) assert True
def test_data_setting_wrong_shape_error(): """ Should get an error when trying to set the data to a different shape array """ sc = sample_sc_release() new_pos = np.ones((sc.num_released, 4), dtype=world_point_type) * 3.0 with raises(ValueError): sc['positions'] = new_pos
def test_data_setting_wrong_dtype_error(): """ Should get an error when trying to set the data to a different type array """ sc = sample_sc_release() new_pos = np.ones((sc.num_released, 3), dtype=np.int32) with raises(ValueError): sc['positions'] = new_pos
def test_data_setting_new_list(): """ Should be able to add a new data that's not a numpy array """ sc = sample_sc_release() new_arr = range(sc.num_released) sc['new_name'] = new_arr assert np.array_equal(sc['new_name'], new_arr) assert_dataarray_shape_size(sc)
def test_north(): sp = sample_sc_release(num_elements=10, start_pos=(20, 0.0, 0.0)) mover = simple_mover.SimpleMover(velocity=(0.0, 10, 0.0)) delta = mover.get_move(sp, time_step=100.0, model_time=None) # expected = np.zeros_like(delta) expected = proj.meters_to_lonlat((0.0, 1000.0, 0.0), (0.0, 0.0, 0.0)) assert np.alltrue(delta == expected)
def test_set_data_array(): """ add data to a data array in the spill container """ sc = sample_sc_release() sc['spill_num'] = np.ones(len(sc['spill_num']), dtype=id_type) * 4 assert np.all(sc['spill_num'] == 4) new_pos = np.ones((sc.num_released, 3), dtype=world_point_type) * 3.0 sc['positions'] = new_pos assert np.array_equal(sc['positions'], new_pos)
def test_uncertain_loop(): """ test one time step with uncertainty on the spill checks there is non-zero motion. """ pSpill = sample_sc_release(num_le, start_pos, rel_time, uncertain=True) cats = CatsMover(curr_file, tide=td) u_delta = _uncertain_loop(pSpill, cats) _assert_move(u_delta) return u_delta
def test_some_off_map(self): """ Test LEs that go off the map should get off_map flag - no longer setting to_be_removed flag. map simply sets the off_maps flag. """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours spill = sample_sc_release(8) spill['positions'] = np.array(( (45.0, 25.0, 0.), (45.0, 25.0, 0.), (45.0, -25.0, 0.), (45.0, -25.0, 0.), (-45.0, -25.0, 0.), (-45.0, -25.0, 0.), (-45.0, 25.0, 0.), (-45.0, 25.0, 0.), ), dtype=np.float64) spill['next_positions'] = np.array(( # off # still on # off # still on # off # still on # off # still on (55.0, 25.0, 0.), (49.0, 25.0, 0.), (45.0, -35.0, 0.), (45.0, -29.0, 0.), (-55.0, -25.0, 0.), (-49.0, -25.0, 0.), (-45.0, 35.0, 0.), (-45.0, 29.0, 0.), ), dtype=np.float64) gmap.beach_elements(spill) off = np.ones(4,) * oil_status.off_maps # off = np.ones(4) * oil_status.to_be_removed assert np.array_equal(spill['status_codes'][0::2], off) on = np.ones(4) * oil_status.in_water assert np.array_equal(spill['status_codes'][1::2], on)
def test_mixed_layer2(): """ tests the top layer elements should end up fairly evenly distributed by the end of along run """ D_mixed = 10.0 # cm^2/s mixed_layer_depth = 10.0 # m time_step = 60 total_time = 6000 num_elements = 1000 num_timesteps = total_time // time_step mv = RandomVerticalMover(vertical_diffusion_coef_above_ml=D_mixed, vertical_diffusion_coef_below_ml=0.0, mixed_layer_depth=mixed_layer_depth, ) # m sc = sample_sc_release(num_elements=num_elements, start_pos=(0.0, 0.0, 0.0), release_time=model_time, ) # re-set z positions: sc['positions'][:, 2] = 5.0 # middle of the layer # call get_move a bunch of times for i in range(num_timesteps): # print "positions:\n", sc['positions'] delta = mv.get_move(sc, time_step, model_time, ) # print "delta:\n", delta sc['positions'] += delta # print sc['positions'] # expected mean exp_mean = 5.0 # middle of layer # expected variance: exp_var = mixed_layer_depth**2 / 12.0 var = sc['positions'][:,2].var() print "expected_var:", exp_var, "var:", var assert np.allclose(exp_var, var, rtol=0.18)
def test_uncertain_loop(): """ test one time step with uncertainty on the spill checks there is non-zero motion. """ pSpill = sample_sc_release(num_le, start_pos, rel_time, uncertain=True) component = ComponentMover(curr1_file, curr2_file, wind=wnd) component.ref_point = (-75.262319, 39.142987) u_delta = _uncertain_loop(pSpill, component) _assert_move(u_delta) return u_delta
def test_uncertain_loop(uncertain_time_delay=0): """ test one time step with uncertainty on the spill checks there is non-zero motion. """ pSpill = sample_sc_release(num_le, start_pos, rel_time, uncertain=True) curr = GridCurrentMover(curr_file, topology_file) curr.uncertain_time_delay=uncertain_time_delay u_delta = _uncertain_loop(pSpill, curr) _assert_move(u_delta) return u_delta
def test_uncertain_loop(): """ test one time step with uncertainty on the spill checks there is non-zero motion. """ pSpill = sample_sc_release(num_le, start_pos, rel_time, uncertain=True) wind = GridWindMover(wind_file, topology_file) u_delta = _uncertain_loop(pSpill, wind) _assert_move(u_delta) # returned delta is used in test_certain_uncertain test return u_delta
def test_basic_move(): # initilizes to long, lat, z = 0.0, 0.0, 0.0 sp = sample_sc_release(num_elements=5) mover = simple_mover.SimpleMover(velocity=(1.0, 10.0, 0.0)) delta = mover.get_move(sp, time_step=100.0, model_time=None) print delta # expected = np.zeros_like(delta) expected = proj.meters_to_lonlat((100.0, 1000.0, 0.0), (0.0, 0.0, 0.0)) assert np.alltrue(delta == expected)
def test_mixed_layer(): """ tests the top layer elements should vertically spread according to the diffusion coef of the top layer this version uses a really thick mixed layer to stay away from boundary effects """ D_mixed = 10.0 # cm^2/s time_step = 60 total_time = 600 num_elements = 1000 num_timesteps = total_time // time_step mv = RandomVerticalMover(vertical_diffusion_coef_above_ml=D_mixed, mixed_layer_depth=1000, # HUGE to avoid surface effects. ) # m sc = sample_sc_release(num_elements=num_elements, start_pos=(0.0, 0.0, 0.0), release_time=model_time, ) # re-set z positions: sc['positions'][:, 2] = 500.0 # far from the top # call get_move a bunch of times for i in range(num_timesteps): # print "positions:\n", sc['positions'] delta = mv.get_move(sc, time_step, model_time, ) # print "delta:\n", delta sc['positions'] += delta # print sc['positions'] # expected variance: exp_var = 2 * num_timesteps*time_step * D_mixed # in cm^2? exp_var /= 10**4 # convert to m var = sc['positions'][:,2].var() print "expected_var:", exp_var, "var:", var assert np.allclose(exp_var, var, rtol = 0.1)
def test_loop(): """ test one time step with no uncertainty on the spill checks there is non-zero motion. also checks the motion is same for all LEs """ pSpill = sample_sc_release(num_le, start_pos, rel_time) cats = CatsMover(curr_file, tide=td) delta = _certain_loop(pSpill, cats) _assert_move(delta) assert np.all(delta[:, 0] == delta[0, 0]) # lat move matches for all LEs assert np.all(delta[:, 1] == delta[0, 1]) # long move matches for all LEs assert np.all(delta[:, 2] == 0) # 'z' is zeros return delta
def test_bottom_layer(): """ tests the bottom layer elements should vertically spread according to the diffusion coef of the bottom layer """ D_lower = .11 #m^2/s (or cm^2/s?) time_step = 60 total_time = 60000 num_elements = 100 num_timesteps = total_time // time_step mv = RandomVerticalMover(vertical_diffusion_coef_below_ml=D_lower) # m sc = sample_sc_release(num_elements=num_elements, start_pos=(0.0, 0.0, 0.0), release_time=model_time, ) # re-set z positions: sc['positions'][:, 2] = 1000.0 # far from the top # sc['positions'][ :num_elements/2 , 2] = 5.0 # near top # sc['positions'][ num_elements/2:, 2] = 50.0 # down deep # call get_move a bunch of times for i in range(num_timesteps): # print "positions:\n", sc['positions'] delta = mv.get_move(sc, time_step, model_time, ) # print "delta:\n", delta sc['positions'] += delta # print sc['positions'] # expected variance: exp_var = 2 * num_timesteps*time_step * D_lower # in cm^2? exp_var /= 10**4 # convert to m var = sc['positions'][:,2].var() print "expected_var:", exp_var, "var:", var assert np.allclose(exp_var, var, rtol=0.1)
def test_loop(): """ test one time step with no uncertainty on the spill checks there is non-zero motion. also checks the motion is same for all LEs """ pSpill = sample_sc_release(num_le, start_pos, rel_time) wind = GridWindMover(wind_file, topology_file) delta = _certain_loop(pSpill, wind) _assert_move(delta) #set windage to be constant or each particle has a different position, doesn't work with uncertainty on #assert np.all(delta[:, 0] == delta[0, 0]) # lat move matches for all LEs #assert np.all(delta[:, 1] == delta[0, 1]) # long move matches for all LEs # returned delta is used in test_certain_uncertain test return delta
def test_loop(): """ test one time step with no uncertainty on the spill checks there is non-zero motion. also checks the motion is same for all LEs """ pSpill = sample_sc_release(num_le, start_pos, rel_time) component = ComponentMover(curr1_file, curr2_file, wind=wnd, ref_point = (-75.262319, 39.142987)) component.ref_point = (-75.262319, 39.142987) delta = _certain_loop(pSpill, component) _assert_move(delta) assert np.all(delta[:, 0] == delta[0, 0]) # lat move matches for all LEs assert np.all(delta[:, 1] == delta[0, 1]) # long move matches for all LEs assert np.all(delta[:, 2] == 0) # 'z' is zeros return delta
def test_outside_raster(self): """ test LEs starting form outside the raster bounds """ gmap = RasterMap(refloat_halflife=6, bitmap_array=self.raster, map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30)), projection=NoProjection()) # hours # one left to right # one right to left # diagonal that doesn't hit # diagonal that does hit # spill = gnome.spill.Spill(num_LEs=4) spill = sample_sc_release(4) spill['positions'] = np.array(((30.0, 5.0, 0.), (-5.0, 5.0, 0.), (5.0, -5.0, 0.), (-5.0, -5.0, 0.)), dtype=np.float64) # outside right # outside left # outside top # outside upper left spill['next_positions'] = np.array(((15.0, 5.0, 0.), (5.0, 5.0, 0.), (5.0, 15.0, 0.), (25.0, 15.0, 0.)), dtype=np.float64) gmap.beach_elements(spill) assert np.array_equal(spill['next_positions'], ((15.0, 5.0, 0.), (5.0, 5.0, 0.), (5.0, 15.0, 0.), (10.0, 5.0, 0.))) # just the beached ones assert np.array_equal((spill['last_water_positions'])[3:], ((9.0, 4.0, 0.), )) assert np.array_equal((spill['status_codes'])[3:], (oil_status.on_land, ))
def test_test_spill_container(): sc = sample_sc_release() assert_sc_single_spill(sc)
class TestRefloat: """ only tests the refloat_elements interface and functionality for borderline cases like all elements in water, refloat_halflife = 0 A raster map with only water is used, but since there isn't a land check, this is irrelevant """ # make time_step = refloat_halflife so 50% probability of refloat time_step = 3600. # land/water irrelevant for this test map = RasterMap(refloat_halflife=time_step / 3600., raster=np.zeros((20, 12), dtype=np.uint8), projection=NoProjection(), map_bounds=((-50, -30), (-50, 30), (50, 30), (50, -30))) num_les = 1000 spill = sample_sc_release(num_les) orig_pos = np.random.uniform(0, num_les, spill['positions'].shape) last_water = (1., 2., 0.) spill['positions'][:] = orig_pos spill['last_water_positions'] += last_water def reset(self): self.spill['positions'][:] = self.orig_pos self.spill['last_water_positions'][:] = self.last_water self.map.refloat_halflife = self.time_step / 3600. def test_all_elementsinwater(self): """ all elements in water so do nothing """ self.reset() # reset _state self.spill['status_codes'][:] = oil_status.in_water self.map.refloat_elements(self.spill, self.time_step) assert np.all(self.spill['positions'] == self.orig_pos) assert np.all(self.spill['status_codes'] == oil_status.in_water) def test_refloat_halflife_0(self): """ refloat_halflife is 0 so refloat all elements on land """ self.reset() self.map.refloat_halflife = 0 self.spill['status_codes'][5:] = oil_status.on_land self.map.refloat_elements(self.spill, self.time_step) assert np.all((self.spill['positions'])[:5] == self.orig_pos[:5]) assert np.all((self.spill['positions'])[5:] == self.last_water) def test_refloat_halflife_negative(self): """ refloat_halflife is test_refloat_halflife_negative: this should mean totally sticky --no refloat """ self.reset() self.map.refloat_halflife = -1 self.spill['status_codes'][5:] = oil_status.on_land orig_status_codes = self.spill['status_codes'].copy() self.map.refloat_elements(self.spill, self.time_step) assert np.all((self.spill['positions']) == self.orig_pos) assert np.all(self.spill['status_codes'] == orig_status_codes) def test_refloat_some_onland(self): """ refloat elements on land based on probability """ self.reset() self.spill['status_codes'][:] = oil_status.in_water self.map.refloat_halflife = 3 * self.time_step / 3600. # say 500 out of 1000 are on_land, and we expect about 50% of these # to refloat # initial 25% LEs on_land, last 25% of LEs on_land init_ix = int(round(.25 * self.num_les)) last_ix = self.num_les - (int(round(.5 * self.num_les)) - init_ix) ix = range(init_ix) # choose first 25% of indices ix.extend(range(last_ix, self.num_les, 1)) # last 25% of indices ix = np.asarray(ix) self.spill['status_codes'][ix] = oil_status.on_land self.map.refloat_elements(self.spill, self.time_step) expected = (round( 1. - .5**(self.time_step / self.map.refloat_halflife * 3600.), 2) * 100) actual = (np.count_nonzero( self.spill['status_codes'][ix] == oil_status.in_water) / (self.num_les / 2) * 100) print('Expect {0}% refloat, actual refloated: {1}%'.format( expected, actual)) # ensure some of the elements that were on land are back on water assert np.count_nonzero( self.spill['status_codes'][ix] == oil_status.in_water) > 0 refloat_ix = ix[np.where( self.spill['status_codes'][ix] == oil_status.in_water)[0]] assert np.all(self.spill['positions'][refloat_ix] == self.last_water) # refloated elements assert np.all(self.spill['status_codes'][refloat_ix] == oil_status.in_water) # status is back in water # ensure elements that were in_water are not changed # these are original values that are not refloated mask = np.array([i not in refloat_ix for i in range(self.num_les)], dtype=bool) assert np.all( self.spill['positions'][mask, :] == self.orig_pos[mask, :])
def test_length(): sp = sample_sc_release() assert len(sp) == 10