def test_spills_with_and_notwith_substance(self): ''' datastructure only adds substance/spills if substance is not None deleting spill resets datastructure. - the spills in _substances_spills 'is' the same as the spills in sc.spills - same object ''' sc = SpillContainer() sc.spills += [ Spill(Release(datetime.now(), 10), element_type=floating(substance=None), name='spill0'), Spill(Release(datetime.now(), 10), element_type=floating(substance=test_oil), name='spill1') ] assert len(sc.get_substances()) == 2 sc.prepare_for_model_run() all_spills = list(chain.from_iterable(sc._substances_spills.spills)) assert len(all_spills) == len(sc.spills) for spill in all_spills: assert sc.spills[spill.id] is spill del sc.spills[-1] assert len(sc.get_substances()) == 1 assert len(sc.iterspillsbysubstance()) == 1
def test_num_elements_to_release(self, curr_time): rel = Release(self.rel_time, 0) rel.num_elements_to_release(curr_time, 900) if curr_time <= rel.release_time: assert not rel.start_time_invalid else: assert rel.start_time_invalid
def test_init_exceptions(): with raises(TypeError): Spill(Release(datetime.now()), amount=10) with raises(ValueError): Spill(Release(release_time=datetime.now()), element_type=floating(windage_range=(-1, 0))) with raises(ValueError): Spill(Release(release_time=datetime.now()), element_type=floating(windage_persist=0))
def test_total_mass(): ''' test total_mass attribute ''' sc = SpillContainer() sc.spills += [ Spill(Release(datetime.now(), 10), amount=100, units='kg'), Spill(Release(datetime.now(), 1000), amount=1234, units='kg'), Spill(Release(datetime.now(), 100)) ] assert sc.total_mass == 100 + 1234 sc.spills.clear() sc.spills += [Spill(Release(datetime.now(), 10))] assert sc.total_mass is None
def test_validate_model_spills_time_mismatch_warning(self): ''' test warning messages output for no spills and model start time mismatch with release time ''' model = Model(start_time=self.start_time) (msgs, isvalid) = model.check_inputs() print model.environment print msgs, isvalid assert len(msgs) == 1 and isvalid assert ('{0} contains no spills'.format(model.name) in msgs[0]) model.spills += Spill(Release(self.start_time + timedelta(hours=1), 1)) (msgs, isvalid) = model.check_inputs() assert len(msgs) == 1 and isvalid assert ('{} has release time after model start time'.format( model.spills[0].name) in msgs[0]) model.spills[0].release_time = self.start_time - timedelta(hours=1) (msgs, isvalid) = model.check_inputs() assert len(msgs) == 1 and not isvalid assert ('{} has release time before model start time'.format( model.spills[0].name) in msgs[0])
def test_spills_same_substance_init(self): sc = SpillContainer() et = floating(substance=test_oil) sp_add = [ point_line_release_spill(3, (1, 1, 1), datetime.now(), element_type=et), Spill(Release(datetime.now(), 10), amount=100, units='kg', element_type=floating(substance=test_oil)), Spill(Release(datetime.now(), 10), element_type=floating(substance=et.substance)) ] sc.spills += sp_add assert len(sc.get_substances()) == 1 sc.prepare_for_model_run() assert all([sp_add == spills for spills in sc.iterspillsbysubstance()])
def test_spills_different_substance_init(self): sc = SpillContainer() splls0 = [ point_line_release_spill( 3, (1, 1, 1), datetime.now(), element_type=floating(substance=test_oil)), Spill(Release(datetime.now(), 10), element_type=floating(substance=test_oil)), ] sc.spills += splls0 splls1 = [ Spill(Release(datetime.now(), 10), element_type=floating(substance='oil_crude')) ] sc.spills += splls1 assert (len(sc.get_substances()) == 2 and len(sc.iterspillsbysubstance()) == 2)
def make_model_incomplete_waves(self): ''' create a model with waves objects with no referenced wind, water. Include Spill so we don't get warnings for it ''' model = Model(start_time=self.start_time) model.spills += Spill(Release(self.start_time, 1)) waves = Waves() model.environment += waves return (model, waves)
def test_copy(): """ TODO: how should this work """ sp1 = Spill(Release(release_time=datetime.now().replace(microsecond=0))) sp2 = copy.copy(sp1) assert sp1 is not sp2 assert sp1.id != sp2.id # try deleting the copy, and see if any errors result del sp1 del sp2
def test_no_substance(self): ''' no substance means run trajectory without an OilProps object/without weathering is one reason to do this ''' sc = SpillContainer() sc.spills += [ Spill(Release(datetime.now(), 10), element_type=floating(substance=None), name='spill0'), Spill(Release(datetime.now(), 10), element_type=floating(substance=None), name='spill1') ] assert len(sc.itersubstancedata('mass')) == 0 assert len(sc.get_substances()) == 1 # iterspillsbysubstance() iterates through all the spills associated # with each substance including the spills where substance is None assert len(sc.iterspillsbysubstance()) == 1 assert len(sc.iterspillsbysubstance()) == 1
def test_rewind(self): rel = Release(self.rel_time, 10) rel.num_elements_to_release(self.rel_time, 900) assert not rel.start_time_invalid # change attribute manually for test rel.num_released = rel.num_elements rel.rewind() assert rel.start_time_invalid is None assert rel.num_released == 0
def test_deepcopy(): """ tests that a deepcopy results in a copy so objects are not the same todo: how should this work? """ sp1 = Spill(Release(release_time=datetime.now().replace(microsecond=0))) sp2 = copy.deepcopy(sp1) assert sp1 is not sp2 assert sp1.id != sp2.id # try deleting the copy, and see if any errors result del sp2 del sp1
def test_var_attr_spill_num(output_filename): ''' call prepare_for_model_run and ensure the spill_num attributes are written correctly. Just a simple test that creates two models and adds a spill to each. It then runs both models and checks that the correct spill_name exists in 'spills_map' attribute for NetCDF output variable 'spill_num' ''' def _make_run_model(spill, nc_name): 'internal function' release_time = spill.release.release_time m = Model(start_time=release_time) m.outputters += NetCDFOutput(nc_name) m.spills += spill _run_model(m) return m def _del_nc_file(nc_name): try: os.remove(nc_name) except: pass here = os.path.dirname(__file__) spills = [] model = [] nc_name = [] for ix in (0, 1): spills.append( Spill(Release(datetime.now()), name='m{0}_spill'.format(ix))) nc_name.append(os.path.join(here, 'temp_m{0}.nc'.format(ix))) _del_nc_file(nc_name[ix]) _make_run_model(spills[ix], nc_name[ix]) # open and check the correct spill_name exists in each netcdf file for ix, f_ in enumerate(nc_name): with nc.Dataset(f_) as data: assert (spills[ix].name in data.variables['spill_num'].spills_map) if ix == 0: assert (spills[1].name not in data.variables['spill_num'].spills_map) if ix == 1: assert (spills[0].name not in data.variables['spill_num'].spills_map) _del_nc_file(nc_name[ix])
def test_rewind(self): rel = Release(self.rel_time, 10) rel.num_elements_to_release(self.rel_time, 900) assert not rel.start_time_invalid # change attribute manually for test rel.num_released = rel.num_elements rel.rewind() assert rel.start_time_invalid assert rel.num_released == 0
def test_initialize_InitRiseVelFromDropletDist_weibull(): 'Test initialize data_arrays with Weibull dist' num_elems = 10 data_arrays = mock_append_data_arrays(rise_vel_diameter_array, num_elems) substance = get_oil_props(oil) spill = Spill(Release(datetime.now()), water=Water()) # (.001*.2) / (.693 ** (1 / 1.8)) - smaller droplet test case, in mm # so multiply by .001 dist = WeibullDistribution(alpha=1.8, lambda_=.000248) fcn = InitRiseVelFromDropletSizeFromDist(dist) fcn.initialize(num_elems, spill, data_arrays, substance) assert_dataarray_shape_size(rise_vel_array, data_arrays, num_elems) assert np.all(0 != data_arrays['rise_vel']) assert np.all(0 != data_arrays['droplet_diameter'])
def test_init(element_type, amount): ''' Test various initializations ''' spill = Spill(Release(release_time=datetime.now()), element_type=element_type, amount=amount, units='kg') if element_type is None: assert np.all(spill.windage_range == (0.01, 0.04)) assert spill.windage_persist == 900 # no need to test this in spill -- it shouldn't know about initializers # assert len(spill.initializers) == 1 # add windages # else: # assert len(spill.initializers) == 0 assert spill.release_duration == 0
def test_init(element_type, amount): ''' Test various initializtions ''' spill = Spill(Release(release_time=datetime.now()), element_type=element_type, amount=amount, units='kg') if element_type is None: assert np.all(spill.get('windage_range') == (0.01, 0.04)) assert (spill.get('windage_persist') == 900) assert len(spill.get('initializers')) == 1 # add windages else: assert len(spill.get('initializers')) == 0 assert spill.name == 'Spill' assert spill.get('release_duration') == 0
def test_SpillContainer_add_array_types(): ''' Test an array_type is dynamically added/subtracted from SpillContainer if it is contained in Initailizer's array_types property. For example: Add 'rise_vel' initializer, InitRiseVelFromDropletSizeFromDist()) is added to Spill's element_type object. Now, the array_types for this initailizer are 'rise_vel' and 'droplet_diameter'. Only if a RiseVelocityMover is added to the model in which case the Model provides 'rise_vel' as an array_type to the SpillContainer to append it to its own list, then the SpillContainer will also add the 'droplet_diameter' array_type that is additionally set by the Initializer but is not explicitly required by the Mover. ''' sc = SpillContainer() s = Spill(Release(datetime(2014, 1, 1, 12, 0), 0)) s.set_initializer( InitRiseVelFromDropletSizeFromDist(distribution=UniformDistribution())) sc.spills += s assert 'rise_vel' not in sc.array_types assert 'droplet_diameter' not in sc.array_types # Now say you added RiseVelocityMover and the Model collects ArrayTypes # from all movers and passes it into SpillContainer's prepare_for_model_run # sc.prepare_for_model_run(array_types={'rise_vel'}) assert 'rise_vel' in sc.array_types assert 'droplet_diameter' in sc.array_types # calling prepare_for_model_run without different array_types keeps the # previously added 'rise_vel' array_types - always rewind if you want to # clear out the state and reset array_types to original data sc.prepare_for_model_run() assert 'rise_vel' in sc.array_types assert 'droplet_diameter' in sc.array_types # Now let's rewind array_types and these extra properties should disappear # they are only added after the prepare_for_model_run step sc.rewind() sc.prepare_for_model_run() assert 'rise_vel' not in sc.array_types assert 'droplet_diameter' not in sc.array_types
def test_initialize_InitRiseVelFromDropletDist_weibull_with_min_max(): 'Test initialize data_arrays with Weibull dist' num_elems = 1000 data_arrays = mock_append_data_arrays(rise_vel_diameter_array, num_elems) substance = get_oil_props(oil) spill = Spill(Release(datetime.now()), water=Water()) # (.001*3.8) / (.693 ** (1 / 1.8)) - larger droplet test case, in mm # so multiply by .001 dist = WeibullDistribution(min_=0.002, max_=0.004, alpha=1.8, lambda_=.00456) fcn = InitRiseVelFromDropletSizeFromDist(dist) fcn.initialize(num_elems, spill, data_arrays, substance) # test for the larger droplet case above assert np.all(data_arrays['droplet_diameter'] >= .002) # test for the larger droplet case above assert np.all(data_arrays['droplet_diameter'] <= .004)
def test_amount_mass_vol(amount, units): ''' ensure mass is being returned correctly when 'amount' is initialized wtih 'mass' or 'volume' ''' spill = Spill(Release(datetime.now()), amount=amount, units=units, substance=test_oil) assert spill.amount == amount assert spill.units == units if units in Spill.valid_vol_units: exp_mass = (spill.get('substance').get_density() * uc.convert('Volume', units, 'm^3', spill.amount)) else: exp_mass = uc.convert('Mass', units, 'kg', spill.amount) assert spill.get_mass() == exp_mass exp_mass_g = exp_mass * 1000 assert spill.get_mass('g') == exp_mass_g
def test_amount_mass_vol(amount, units): ''' ensure mass is being returned correctly when 'amount' is initialized wtih 'mass' or 'volume' ''' water = Water() spill = Spill(Release(datetime.now()), amount=amount, units=units, substance=test_oil, water=water) assert spill.amount == amount assert spill.units == units if units in Spill.valid_vol_units: # use 15C (288.15K) for mass<=>volume conversion exp_mass = (spill.substance.density_at_temp(288.15) * uc.convert('Volume', units, 'm^3', spill.amount)) else: exp_mass = uc.convert('Mass', units, 'kg', spill.amount) assert spill.get_mass() == exp_mass exp_mass_g = exp_mass * 1000 assert spill.get_mass('g') == exp_mass_g
def test_init(self): rel = Release(self.rel_time, 0) assert rel.num_elements == 0 assert rel.release_time == self.rel_time assert rel.start_time_invalid is None assert rel.release_duration == 0
def test_init(): Release(release_time=datetime.now())
assert data_arrays[key].shape == (num_released, ) + val.shape """ Initializers - following are used for parameterizing tests """ fcn_list = ( InitWindages(), InitRiseVelFromDist(distribution=UniformDistribution()), InitRiseVelFromDist(distribution=NormalDistribution(mean=0, sigma=0.1)), InitRiseVelFromDist(distribution=LogNormalDistribution(mean=0, sigma=0.1)), InitRiseVelFromDist(distribution=WeibullDistribution( alpha=1.8, lambda_=(1 / (.693**(1 / 1.8))))), InitRiseVelFromDropletSizeFromDist(NormalDistribution(mean=0, sigma=0.1))) arrays_ = (windages, rise_vel_array, rise_vel_array, rise_vel_array, rise_vel_array, rise_vel_diameter_array) spill_list = (None, None, None, None, None, Spill(Release(datetime.now()))) @pytest.mark.parametrize(("fcn", "arr_types", "spill"), zip(fcn_list, arrays_, spill_list)) def test_correct_particles_set_by_initializers(fcn, arr_types, spill): ''' Tests that the correct elements (ones that were released last) are initialized ''' # let's only set the values for the last 10 elements # this is not how it would be used, but this is just to make sure # the values for the correct elements are set data_arrays = mock_append_data_arrays(arr_types, num_elems) data_arrays = mock_append_data_arrays(arr_types, num_elems, data_arrays) substance = get_oil_props(oil)
sigma=0.1)), InitRiseVelFromDist(distribution=LogNormalDistribution(mean=0, sigma=0.1)), InitRiseVelFromDist(distribution=WeibullDistribution(alpha=1.8, lambda_=(1 / (.693 ** (1 / 1.8))) )), InitRiseVelFromDropletSizeFromDist(NormalDistribution(mean=0, sigma=0.1)) ) arrays_ = (windages, rise_vel_array, rise_vel_array, rise_vel_array, rise_vel_array, rise_vel_diameter_array) spill_list = (None, None, None, None, None, Spill(Release(datetime.now()), water=Water())) @pytest.mark.parametrize(("fcn", "arr_types", "spill"), zip(fcn_list, arrays_, spill_list)) def test_correct_particles_set_by_initializers(fcn, arr_types, spill): ''' Tests that the correct elements (ones that were released last) are initialized ''' # let's only set the values for the last 10 elements # this is not how it would be used, but this is just to make sure # the values for the correct elements are set data_arrays = mock_append_data_arrays(arr_types, num_elems) data_arrays = mock_append_data_arrays(arr_types, num_elems, data_arrays) substance = get_oil_props(oil)