def test_init_exceptions(): with pytest.raises(TypeError): Spill() with pytest.raises(ValueError): Spill(Release(), element_type=floating(windage_range=(-1, 0))) with pytest.raises(ValueError): Spill(Release(), element_type=floating(windage_persist=0))
def get_eq_spills(): """ returns a tuple of identical point_line_release_spill objects Set the spill's element_type is to floating(windage_range=(0, 0)) since the default, floating(), uses randomly generated values for initial data array values and these will not match for the two spills. TODO: Currently does not persist the element_type object. spill.to_dict('create') does not persist this attribute - Fix this. """ num_elements = 10 release_time = datetime(2000, 1, 1, 1) spill = point_line_release_spill(num_elements, (28, -75, 0), release_time, element_type=floating(windage_range=(0, 0))) dict_ = spill.to_dict('create') spill2 = spill.new_from_dict(dict_) # check here if equal spills didn't get created - fail this function assert spill == spill2 return (spill, spill2)
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'initializing the model' start_time = datetime(2006, 3, 31, 20, 0) model = Model(start_time=start_time, duration=timedelta(days=3), time_step=30 * 60, uncertain=True) print 'adding the map' mapfile = get_datafile(os.path.join(base_dir, './coastSF.bna')) model.map = MapFromBNA(mapfile, refloat_halflife=1) # seconds renderer = Renderer(mapfile, images_dir, size=(800, 600), draw_ontop='forecast') renderer.viewport = ((-124.5, 37.), (-120.5, 39)) print 'adding outputters' model.outputters += renderer netcdf_file = os.path.join(base_dir, 'script_sf_bay.nc') scripting.remove_netcdf(netcdf_file) model.outputters += NetCDFOutput(netcdf_file, which_data='all') print 'adding a spill' spill = point_line_release_spill(num_elements=1000, start_position=(-123.57152, 37.369436, 0.0), release_time=start_time, element_type=floating(windage_range=(0.01, 0.04) ) ) model.spills += spill # print 'adding a RandomMover:' # r_mover = gnome.movers.RandomMover(diffusion_coef=50000) # model.movers += r_mover print 'adding a grid wind mover:' wind_file = get_datafile(os.path.join(base_dir, r"./WindSpeedDirSubset.nc") ) topology_file = get_datafile(os.path.join(base_dir, r"./WindSpeedDirSubsetTop.dat")) w_mover = GridWindMover(wind_file, topology_file) #w_mover.uncertain_time_delay = 6 #w_mover.uncertain_duration = 6 w_mover.uncertain_speed_scale = 1 w_mover.set_uncertain_angle(.2, 'rad') # default is .4 w_mover.wind_scale = 2 model.movers += w_mover 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 model(sample_model): """ Use fixture sample_model and add a few things to it for the test """ model = sample_model['model'] model.cache_enabled = True model.spills += point_line_release_spill(num_elements=5, start_position=sample_model['release_start_pos'], release_time=model.start_time, end_release_time=model.start_time + model.duration, element_type=floating(windage_persist=-1)) return model
def model(sample_model, request): """ Use fixture model_surface_release_spill and add a few things to it for the test """ model = sample_model['model'] model.cache_enabled = True model.spills += point_line_release_spill(num_elements=5, start_position=sample_model['release_start_pos'], release_time=model.start_time, end_release_time=model.start_time + model.duration, element_type=floating(windage_persist=-1)) model.movers += RandomMover(diffusion_coef=100000) model.outputters += NetCDFOutput(os.path.join(base_dir, u'sample_model.nc')) def cleanup(): 'cleanup outputters was added to sample_model and delete files' print '\nCleaning up %s' % model o_put = None for outputter in model.outputters: # there should only be 1! #if isinstance(outputter, NetCDFOutput): o_put = model.outputters[outputter.id] if hasattr(o_put, 'netcdf_filename'): if os.path.exists(o_put.netcdf_filename): os.remove(o_put.netcdf_filename) if (o_put._u_netcdf_filename is not None and os.path.exists(o_put._u_netcdf_filename)): os.remove(o_put._u_netcdf_filename) request.addfinalizer(cleanup) return model
def test_uncertain_copy(): """ only tests a few things... """ spill = point_line_release_spill( num_elements=100, start_position=(28, -78, 0.), release_time=datetime.now(), end_position=(29, -79, 0.), end_release_time=datetime.now() + timedelta(hours=24), element_type=floating(windage_range=(.02, .03), windage_persist=-1) ) u_spill = spill.uncertain_copy() assert u_spill is not spill assert np.array_equal(u_spill.release.start_position, spill.release.start_position) del spill del u_spill
def __init__( self, release, element_type=None, on=True, volume=None, volume_units='m^3', # Is this total mass of the spill? mass=None, mass_units='g', id=None, ): """ Base spill class. Spill used by a gnome model derive from this class :param num_elements: number of LEs - default is 0. :type num_elements: int Optional parameters (kwargs): :param on: Toggles the spill on/off (bool). Default is 'on'. :type on: bool :type id: str :param volume: oil spilled volume (used to compute mass per particle) Default is None. :type volume: float :param volume_units=m^3: volume units :type volume_units: str :param windage_range=(0.01, 0.04): the windage range of the elements default is (0.01, 0.04) from 1% to 4%. :type windage_range: tuple: (min, max) :param windage_persist=-1: Default is 900s, so windage is updated every 900 sec. -1 means the persistence is infinite so it is only set at the beginning of the run. :type windage_persist: integer seconds :param id: Unique Id identifying the newly created mover (a UUID as a string), used when loading from a persisted model :param element_type=None: list of various element_type that are released. These are spill specific properties of the elements. :type element_type: list of gnome.element_type.* objects """ #self.num_elements = num_elements self.release = release if element_type is None: element_type = elements.floating() self.element_type = element_type self.on = on # spill is active or not # mass/volume, type of oil spilled self._check_units(volume_units) self._volume_units = volume_units # user defined for display self._volume = volume if volume is not None: self._volume = unit_conversion.convert('Volume', volume_units, 'm^3', volume) self._check_units(mass_units, 'Mass') self._mass_units = mass_units # user defined for display self._mass = mass if mass is not None: self._mass = uc.convert('Mass', mass_units, 'g', mass) if mass is not None and volume is not None: raise ValueError("'mass' and 'volume' cannot both be set") #============================================================================== # if windage_range is not None: # if 'windages' not in self.element_type.initializers: # raise TypeError("'windage_range' cannot be set for specified" # " element_type: {0}".format(element_type)) # (self.element_type.initializers['windages']).windage_range = \ # windage_range # # if windage_persist is not None: # if 'windages' not in self.element_type.initializers: # raise TypeError("'windage_persist' cannot be set for specified" # " element_type: {0}".format(element_type)) # (self.element_type.initializers['windages']).windage_persist = \ # windage_persist #============================================================================== self._gnome_id = GnomeId(id)
fcn.initialize(num_elems, None, data_arrays) assert_dataarray_shape_size(rise_vel_array, data_arrays, num_elems) assert np.all(0 != data_arrays['rise_vel']) """ Element Types""" # additional array_types corresponding with ElementTypes for following test arr_types = {'windages': array_types.windages, 'windage_range': array_types.windage_range, 'windage_persist': array_types.windage_persist, 'mass': array_types.mass, 'rise_vel': array_types.rise_vel} inp_params = [((floating(), ElementType({'windages': InitWindages(), 'mass': InitMassFromVolume()})), arr_types), ((floating(), ElementType({'windages': InitWindages(), 'mass': InitMassFromTotalMass()})), arr_types), ((floating(), ElementType({'windages': InitWindages(), 'rise_vel': InitRiseVelFromDist()})), arr_types), ((floating(), ElementType({'mass': InitMassFromTotalMass(), 'rise_vel': InitRiseVelFromDist()})), arr_types), ((floating(), ElementType({'mass': InitMassFromVolume(), 'rise_vel': InitRiseVelFromDist()})), arr_types) ]
def test_linearity_of_wind_movers(wind_persist): ''' WindMover is defined as a linear operation - defining a model with a single WindMover with 15 knot wind is equivalent to defining a model with three WindMovers each with 5 knot wind. Or any number of WindMover's such that the sum of their magnitude is 15knots and the direction of wind is the same for both cases. Below is an example which defines two models and runs them. In model2, there are multiple winds defined so the windage parameter is reset 3 times for one timestep. Since windage range and persistence do not change, this only has the effect of doing the same computation 3 times. However, the results are the same. The mean and variance of the positions for both models are close. As windage_persist is decreased, the values become closer. Setting windage_persist=0 gives the large difference between them. ''' units = 'meter per second' start_time = datetime(2012, 1, 1, 0, 0) series1 = np.array((start_time, (15, 45)), dtype=datetime_value_2d).reshape((1, )) series2 = np.array((start_time, (6, 45)), dtype=datetime_value_2d).reshape((1, )) series3 = np.array((start_time, (3, 45)), dtype=datetime_value_2d).reshape((1, )) num_LEs = 1000 model1 = Model() model1.duration = timedelta(hours=1) model1.time_step = timedelta(hours=1) model1.start_time = start_time model1.spills += point_line_release_spill(num_elements=num_LEs, start_position=(1., 2., 0.), release_time=start_time, element_type=floating(windage_persist=wind_persist)) model1.movers += WindMover(Wind(timeseries=series1, units=units)) model2 = Model() model2.duration = timedelta(hours=10) model2.time_step = timedelta(hours=1) model2.start_time = start_time model2.spills += point_line_release_spill(num_elements=num_LEs, start_position=(1., 2., 0.), release_time=start_time, element_type=floating(windage_persist=wind_persist)) # todo: CHECK RANDOM SEED # model2.movers += WindMover(Wind(timeseries=series1, units=units)) model2.movers += WindMover(Wind(timeseries=series2, units=units)) model2.movers += WindMover(Wind(timeseries=series2, units=units)) model2.movers += WindMover(Wind(timeseries=series3, units=units)) while True: try: model1.next() except StopIteration: print 'Done model1 ..' break while True: try: model2.next() except StopIteration: print 'Done model2 ..' break # mean and variance at the end should be fairly close # look at the mean of the position vector. Assume m1 is truth # and m2 is approximation - look at the absolute error between # mean position of m2 in the 2 norm. # rel_mean_error =(np.linalg.norm(np.mean(model2.spills.LE('positions'), 0) # - np.mean(model1.spills.LE('positions'), 0))) # assert rel_mean_error <= 0.5 # Similarly look at absolute error in variance of position of m2 # in the 2 norm. rel_var_error = np.linalg.norm(np.var(model2.spills.LE('positions'), 0) - np.var(model1.spills.LE('positions'), 0)) assert rel_var_error <= 0.0015