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_spills_different_substance_release(self): ''' Test data structure gets correctly set/updated after release_elements is invoked ''' sc = SpillContainer() rel_time = datetime(2014, 1, 1, 12, 0, 0) end_time = rel_time + timedelta(hours=1) time_step = 900 splls0 = [point_line_release_spill(100, (1, 1, 1), rel_time, end_release_time=end_time, element_type=floating(substance=test_oil), amount=100, units='kg'), point_line_release_spill(50, (2, 2, 2), rel_time + timedelta(seconds=900), element_type=floating(substance=test_oil), amount=150, units='kg'), ] sc.spills += splls0 splls1 = point_line_release_spill(10, (0, 0, 0), rel_time, element_type=floating(substance=None)) with pytest.raises(ValueError): # when you add a spill with another substance, you should get an error. sc.spills += splls1
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_standard_density(): et = floating() dict_ = et.serialize() assert dict_['standard_density'] == 1000.0 et = floating(substance=oil) dict_ = et.serialize() assert dict_['standard_density'] == et.substance.density_at_temp(288.15)
def test_init_exceptions(): with raises(TypeError): Spill() 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_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_spills_with_and_not_with_substance2(self): ''' should not be able to add a None substance and an oil ''' sc = SpillContainer() spills = [Spill(Release(datetime.now(), 10), element_type=floating(substance=test_oil), name='spill0'), Spill(Release(datetime.now(), 10), element_type=floating(substance=None), name='spill1')] with pytest.raises(ValueError): sc.spills += spills
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')) ] with pytest.raises(ValueError): sc.spills += splls1
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_dispersion(oil, temp, num_elems, on): ''' Fuel Oil #6 does not exist... ''' et = floating(substance=oil) disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(disp.array_types, water, element_type=et)[:2] model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) if on: assert sc.mass_balance['natural_dispersion'] > 0 assert sc.mass_balance['sedimentation'] > 0 print "sc.mass_balance['natural_dispersion']" print sc.mass_balance['natural_dispersion'] print "sc.mass_balance['sedimentation']" print sc.mass_balance['sedimentation'] else: assert 'natural_dispersion' not in sc.mass_balance assert 'sedimentation' not in sc.mass_balance
def test_one_weather(self): ''' calls one weathering step and checks that we decayed at the expected rate. Needs more tests with varying half_lives ''' time_step = 15. * 60 hl = tuple([time_step] * subs.num_components) weatherer = HalfLifeWeatherer(half_lives=hl) sc = weathering_data_arrays(weatherer.array_types, Water(), time_step, element_type=floating(substance=subs))[0] print '\nsc["mass"]:\n', sc['mass'] orig_mc = np.copy(sc['mass_components']) model_time = rel_time weatherer.prepare_for_model_run(sc) weatherer.prepare_for_model_step(sc, time_step, model_time) weatherer.weather_elements(sc, time_step, model_time) weatherer.model_step_is_done() print '\nsc["mass"]:\n', sc['mass'] assert np.allclose(0.5 * orig_mc.sum(1), sc['mass']) assert np.allclose(0.5 * orig_mc, sc['mass_components'])
def weathering_data_arrays(n_arrays, water=None, time_step=15.*60, element_type=None, langmuir=False): ''' function to initialize data_arrays set by WeatheringData. Weatherer tests can use this function to release elements and initialize data without defining a model ''' if water is None: water = Water() rqd_weatherers = [WeatheringData(water), FayGravityViscous(water)] arrays = set() arrays.update(n_arrays) for wd in rqd_weatherers: arrays.update(wd.array_types) if element_type is None: element_type = floating(substance=test_oil) sc = sample_sc_release(num_elements=2, element_type=element_type, arr_types=arrays, time_step=time_step) for wd in rqd_weatherers: wd.prepare_for_model_run(sc) wd.initialize_data(sc, sc.num_released) return (sc, time_step, rqd_weatherers)
def weathering_data_arrays(n_arrays, water=None, time_step=15.*60, element_type=None, langmuir=False, num_elements=2): ''' function to initialize data_arrays set by WeatheringData. Weatherer tests can use this function to release elements and initialize data without defining a model ''' if water is None: water = Water() rqd_weatherers = [WeatheringData(water), FayGravityViscous(water)] arrays = set() arrays.update(n_arrays) for wd in rqd_weatherers: arrays.update(wd.array_types) if element_type is None: element_type = floating(substance=test_oil) sc = sample_sc_release(num_elements=num_elements, element_type=element_type, arr_types=arrays, time_step=time_step) for wd in rqd_weatherers: wd.prepare_for_model_run(sc) wd.initialize_data(sc, sc.num_released) return (sc, time_step, rqd_weatherers)
def test_two_substance_different(sample_model_fcn, s0=test_oil, s1="ARABIAN MEDIUM, EXXON"): ''' The model (SpillContainer) does not allow two different substances. Keeping this test in case we do want to extend it some day. only tests data arrays are correct and we don't end up with stale data in substance_data structure of spill container. It models each substance independently We don't accurately model two oils at present. This is a basic test, maybe a useful example when extending code to multiple oils. It is also useful for catching bugs when doing a refactor so leave it in. ''' model = sample_model_weathering(sample_model_fcn, s0) model.map = gnome.map.GnomeMap() # make it all water model.uncertain = False rel_time = model.spills[0].release_time model.duration = timedelta(days=1) et = floating(substance=s1) cs = point_line_release_spill(500, (0, 0, 0), rel_time, end_release_time=(rel_time + timedelta(hours=1)), element_type=et, amount=1, units='tonnes') with pytest.raises(ValueError): model.spills += cs
def model(sample_model, output_dir): model = sample_model_weathering(sample_model, test_oil) rel_start_pos = sample_model['release_start_pos'] rel_end_pos = sample_model['release_end_pos'] model.cache_enabled = True model.uncertain = True water, wind = Water(), constant_wind(1., 0) model.environment += [water, wind] model.weatherers += Evaporation(water, wind) et = floating(substance=model.spills[0].substance.name) N = 10 # a line of ten points line_pos = np.zeros((N, 3), dtype=np.float64) line_pos[:, 0] = np.linspace(rel_start_pos[0], rel_end_pos[0], N) line_pos[:, 1] = np.linspace(rel_start_pos[1], rel_end_pos[1], N) # print start_points model.spills += point_line_release_spill(1, start_position=rel_start_pos, release_time=model.start_time, end_position=rel_end_pos, element_type=et, amount=100, units='tons') model.outputters += TrajectoryGeoJsonOutput(output_dir=output_dir) model.rewind() return model
def test_dissolution_k_ow(oil, temp, num_elems, k_ow, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values ''' et = floating(substance=oil) diss = Dissolution(waves) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) diss.prepare_for_model_step(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) assert all(np.isclose(sc._data_arrays['partition_coeff'], k_ow))
def test_dispersion_not_active(oil, temp, num_elems): ''' Fuel Oil #6 does not exist... ''' disp = NaturalDispersion(waves, water) (sc, time_step) = \ weathering_data_arrays(disp.array_types, water, element_type=floating(substance=oil))[:2] sc.amount = 10000 model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.prepare_for_model_run(sc) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) new_model_time = (sc.spills[0].release_time + timedelta(seconds=3600)) disp.active_range = (new_model_time, InfDateTime('inf')) disp.prepare_for_model_step(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) disp.weather_elements(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0)
def test_one_weather(self): ''' calls one weathering step and checks that we decayed at the expected rate. Needs more tests with varying half_lives ''' time_step = 15.*60 hl = tuple([time_step] * subs.num_components) weatherer = HalfLifeWeatherer(half_lives=hl) sc = weathering_data_arrays(weatherer.array_types, Water(), time_step, element_type=floating(substance=subs))[0] print '\nsc["mass"]:\n', sc['mass'] orig_mc = np.copy(sc['mass_components']) model_time = rel_time weatherer.prepare_for_model_run(sc) weatherer.prepare_for_model_step(sc, time_step, model_time) weatherer.weather_elements(sc, time_step, model_time) weatherer.model_step_is_done() print '\nsc["mass"]:\n', sc['mass'] assert np.allclose(0.5 * orig_mc.sum(1), sc['mass']) assert np.allclose(0.5 * orig_mc, sc['mass_components'])
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 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('save') 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('save') #spill2 = spill.new_from_dict(dict_) spill2 = copy.deepcopy(spill) # IDs will not match! force this so our tests work spill2._id = spill.id # check here if equal spills didn't get created - fail this function assert spill == spill2 return (spill, spill2)
def test_dissolution(oil, temp, num_elems, on): ''' Fuel Oil #6 does not exist... ''' et = floating(substance=oil) diss = Dissolution(waves) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) diss.prepare_for_model_step(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) if on: print sc._data_arrays assert all(np.isclose(sc._data_arrays['partition_coeff'], 511.445)) assert sc.mass_balance['dissolution'] > 0 print "sc.mass_balance['dissolution']" print sc.mass_balance['dissolution'] else: assert 'dissolution' not in sc.mass_balance
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. """ 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('save') #spill2 = spill.new_from_dict(dict_) spill2 = copy.deepcopy(spill) # IDs will not match! force this so our tests work spill2._id = spill.id # check here if equal spills didn't get created - fail this function assert spill == spill2 return (spill, spill2)
def test_dispersion(oil, temp, num_elems, on): ''' Fuel Oil #6 does not exist... ''' et = floating(substance=oil) disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(disp.array_types, water, element_type=et)[:2] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) if on: # print "sc.mass_balance['natural_dispersion']" # print sc.mass_balance['natural_dispersion'] # print "sc.mass_balance['sedimentation']" # print sc.mass_balance['sedimentation'] assert sc.mass_balance['natural_dispersion'] > 0 assert sc.mass_balance['sedimentation'] > 0 else: assert 'natural_dispersion' not in sc.mass_balance assert 'sedimentation' not in sc.mass_balance
def test_dissolution_mass_balance(oil, temp, num_elems, expected_mb, on): ''' Fuel Oil #6 does not exist... ''' et = floating(substance=oil) diss = Dissolution(waves) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) diss.prepare_for_model_step(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) if on: assert np.isclose(sc.mass_balance['dissolution'], expected_mb) else: assert 'dissolution' not in sc.mass_balance
def test_bullwinkle(): ''' user set emulsion constant ''' et = floating(substance=test_oil) assert et.substance.bullwinkle == .303 et.substance.bullwinkle = .4 assert et.substance.bullwinkle == .4
def test_bulltime(): ''' user set time to start emulsification ''' et = floating(substance=test_oil) assert et.substance.bulltime == -999 et.substance.bulltime = 3600 assert et.substance.bulltime == 3600
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_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 assert len(sc.get_substances(complete=False)) == 0 # iterspillsbysubstance() iterates through all the spills associated # with each substance including the spills where substance is None assert len(sc.iterspillsbysubstance()) == 2
def test_spills_different_substance_release(self): ''' Test data structure gets correctly set/updated after release_elements is invoked ''' sc = SpillContainer() rel_time = datetime(2014, 1, 1, 12, 0, 0) end_time = rel_time + timedelta(hours=1) time_step = 900 splls0 = [ point_line_release_spill(100, (1, 1, 1), rel_time, end_release_time=end_time, element_type=floating(substance=test_oil), amount=100, units='kg'), point_line_release_spill(50, (2, 2, 2), rel_time + timedelta(seconds=900), element_type=floating(substance=test_oil), amount=150, units='kg'), ] sc.spills += splls0 splls1 = point_line_release_spill( 10, (0, 0, 0), rel_time, element_type=floating(substance=None)) sc.spills += splls1 at = {'density', 'mass_components'} sc.prepare_for_model_run(at) assert len(sc.get_substances()) == 2 print '\nElements released:' for ix in range(-1, 8): time = rel_time + timedelta(seconds=time_step) * ix num_rel = sc.release_elements(time_step, time) print num_rel for substance, data in sc.itersubstancedata(at): assert substance.name == test_oil idx = sc._substances_spills.substances.index(substance) mask = sc['substance'] == idx for array in at: assert array in data assert np.all(data[array] == sc[array][mask])
def test_spills_different_substance_release(self): ''' Test data structure gets correctly set/updated after release_elements is invoked ''' sc = SpillContainer() rel_time = datetime(2014, 1, 1, 12, 0, 0) end_time = rel_time + timedelta(hours=1) time_step = 900 splls0 = [point_line_release_spill(100, (1, 1, 1), rel_time, end_release_time=end_time, element_type=floating(substance=test_oil), amount=100, units='kg'), point_line_release_spill(50, (2, 2, 2), rel_time + timedelta(seconds=900), element_type=floating(substance=test_oil), amount=150, units='kg'), ] sc.spills += splls0 splls1 = point_line_release_spill(10, (0, 0, 0), rel_time, element_type=floating(substance=None)) sc.spills += splls1 at = {'density', 'mass_components'} sc.prepare_for_model_run(at) assert len(sc.get_substances()) == 2 print '\nElements released:' for ix in range(-1, 8): time = rel_time + timedelta(seconds=time_step) * ix num_rel = sc.release_elements(time_step, time) print num_rel for substance, data in sc.itersubstancedata(at): assert substance.name == test_oil idx = sc._substances_spills.substances.index(substance) mask = sc['substance'] == idx for array in at: assert array in data assert np.all(data[array] == sc[array][mask])
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 test_bullwinkle(): ''' user set emulsion constant ''' et = floating(substance=test_oil) assert np.isclose(et.substance.bullwinkle, 0.193724) et.substance.bullwinkle = .4 assert et.substance.bullwinkle == .4
def test_contains_object(sample_model_fcn): ''' Test that we can find all contained object types with a model. ''' model = sample_model_weathering(sample_model_fcn, test_oil) gnome_map = model.map = gnome.map.GnomeMap() # make it all water rel_time = model.spills[0].get('release_time') model.start_time = rel_time - timedelta(hours=1) model.duration = timedelta(days=1) water, wind = Water(), constant_wind(1., 0) model.environment += [water, wind] et = floating(substance=model.spills[0].get('substance').name) sp = point_line_release_spill(500, (0, 0, 0), rel_time + timedelta(hours=1), element_type=et, amount=100, units='tons') rel = sp.release initializers = et.initializers model.spills += sp movers = [m for m in model.movers] evaporation = Evaporation() skim_start = sp.get('release_time') + timedelta(hours=1) skimmer = Skimmer(.5*sp.amount, units=sp.units, efficiency=0.3, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) burn = burn_obj(sp) disp_start = skim_start + timedelta(hours=1) dispersion = ChemicalDispersion(0.1, active_start=disp_start, active_stop=disp_start + timedelta(hours=1) ) model.weatherers += [evaporation, dispersion, burn, skimmer] renderer = Renderer(images_dir='junk', size=(400, 300)) model.outputters += renderer for o in (gnome_map, sp, rel, et, water, wind, evaporation, dispersion, burn, skimmer, renderer): assert model.contains_object(o.id) for o in initializers: assert model.contains_object(o.id) for o in movers: assert model.contains_object(o.id)
def test_contains_object(sample_model_fcn): ''' Test that we can find all contained object types with a model. ''' model = sample_model_weathering(sample_model_fcn, test_oil) gnome_map = model.map = gnome.map.GnomeMap() # make it all water rel_time = model.spills[0].get('release_time') model.start_time = rel_time - timedelta(hours=1) model.duration = timedelta(days=1) water, wind = Water(), constant_wind(1., 0) model.environment += [water, wind] et = floating(substance=model.spills[0].get('substance').name) sp = point_line_release_spill(500, (0, 0, 0), rel_time + timedelta(hours=1), element_type=et, amount=100, units='tons') rel = sp.release initializers = et.initializers model.spills += sp movers = [m for m in model.movers] evaporation = Evaporation() skim_start = sp.get('release_time') + timedelta(hours=1) skimmer = Skimmer(.5 * sp.amount, units=sp.units, efficiency=0.3, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) burn = burn_obj(sp) disp_start = skim_start + timedelta(hours=1) dispersion = ChemicalDispersion(0.1, active_start=disp_start, active_stop=disp_start + timedelta(hours=1)) model.weatherers += [evaporation, dispersion, burn, skimmer] renderer = Renderer(images_dir='junk', size=(400, 300)) model.outputters += renderer for o in (gnome_map, sp, rel, et, water, wind, evaporation, dispersion, burn, skimmer, renderer): assert model.contains_object(o.id) for o in initializers: assert model.contains_object(o.id) for o in movers: assert model.contains_object(o.id)
def test_emulsification(oil, temp, num_elems, on): ''' Fuel Oil #6 does not emulsify fixme: this fails for ALASKA NORTH SLOPE - what is it supposed to test? ''' print oil, temp, num_elems, on emul = Emulsification(waves) emul.on = on (sc, time_step) = \ weathering_data_arrays(emul.array_types, water, element_type=floating(substance=oil))[:2] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) emul.prepare_for_model_run(sc) # also want a test for a user set value for bulltime or bullwinkle if oil == s_oils[0]: sc['frac_lost'][:] = .31 # sc['frac_lost'][:] = .35 print "sc['frac_lost'][:]" print sc['frac_lost'][:] emul.prepare_for_model_step(sc, time_step, model_time) emul.weather_elements(sc, time_step, model_time) print "sc['frac_water'][:]" print sc['frac_water'][:] if on: assert np.all(sc['frac_lost'] > 0) and np.all(sc['frac_lost'] < 1.0) assert np.all(sc['frac_water'] > 0) and np.all(sc['frac_water'] <= .9) else: assert np.all(sc['frac_water'] == 0) sc['frac_lost'][:] = .2 print "sc['frac_lost'][:]" print sc['frac_lost'][:] emul.prepare_for_model_step(sc, time_step, model_time) emul.weather_elements(sc, time_step, model_time) print "sc['frac_water'][:]" print sc['frac_water'][:] if on: assert np.all(sc['frac_lost'] > 0) and np.all(sc['frac_lost'] < 1.0) assert np.all(sc['frac_water'] > 0) and np.all(sc['frac_water'] <= .9) else: assert np.all(sc['frac_water'] == 0)
def test_bullwinkle(): ''' user set emulsion constant ''' et = floating(substance=test_oil) # our test_oil is the sample oile assert np.isclose(et.substance.bullwinkle, 0.1937235) et.substance.bullwinkle = .4 assert et.substance.bullwinkle == .4
def test_serialize_deserialize(): ''' serialize/deserialize for 'save' option is tested in test_save_load This tests serialize/deserilize with 'webapi' option ''' et = floating() n_et = ElementType.deserialize(et.serialize()) # for webapi, make new objects from nested objects before creating # new element_type # following is not a requirement for webapi, but it is infact the case assert n_et == et
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.uncertain_angle_scale = 0.2 # default is .4 w_mover.wind_scale = 2 model.movers += w_mover return model
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 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, 'WindSpeedDirSubset.nc')) topology_file = get_datafile( os.path.join(base_dir, '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.uncertain_angle_scale = 0.2 # default is .4 w_mover.wind_scale = 2 model.movers += w_mover return model
def test_serialize_deserialize(test_obj): """ serialize/deserialize for 'save' optio is tested in test_save_load This tests serialize/deserilize with 'webapi' option """ et = floating() dict_ = ElementType.deserialize(et.serialize("webapi")) # for webapi, make new objects from nested objects before creating # new element_type dict_["initializers"] = et.initializers n_et = ElementType.new_from_dict(dict_) # following is not a requirement for webapi, but it is infact the case assert n_et == et
def test_prepare_for_model_run(): 'test sort order for Dissolution weatherer' et = floating(substance='ABU SAFAH') diss = Dissolution(waves) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et)[:2] assert 'partition_coeff' in sc.data_arrays assert 'dissolution' not in sc.mass_balance diss.prepare_for_model_run(sc) assert 'dissolution' in sc.mass_balance
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 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(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.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_prepare_for_model_run(): 'test sort order for Dissolution weatherer' et = floating(substance='oil_bahia') diss = Dissolution(waves) # we don't want to query the oil database, but get the sample oil assert et.substance.record.id is None (sc, _time_step) = weathering_data_arrays(diss.array_types, water, element_type=et)[:2] assert 'partition_coeff' in sc.data_arrays assert 'dissolution' not in sc.mass_balance diss.prepare_for_model_run(sc) assert 'dissolution' in sc.mass_balance
def test_dissolution_droplet_size(oil, temp, num_elems, drop_size, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values ''' et = floating(substance=oil) disp = NaturalDispersion(waves, water) diss = Dissolution(waves, wind) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num_spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount, sc.spills[0].units model_time = (sc.spills[0] .release_time + timedelta(seconds=time_step)) print 'model_time = ', model_time print 'time_step = ', time_step # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None disp.on = on diss.on = on disp.prepare_for_model_run(sc) diss.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.initialize_data(sc, sc.num_released) for i in range(3): disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) print 'droplet_avg_size:', sc._data_arrays['droplet_avg_size'] assert np.allclose(sc._data_arrays['droplet_avg_size'], drop_size[i])
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 = constant_wind_mover(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.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_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 test_evaporation(oil, temp, num_elems, on): ''' still working on tests .. ''' et = floating(substance=oil) time_step = 15. * 60 evap = Evaporation(Water(), wind=constant_wind(1., 0)) evap.on = on sc = weathering_data_arrays(evap.array_types, evap.water, time_step, et)[0] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) evap.prepare_for_model_run(sc) evap.prepare_for_model_step(sc, time_step, model_time) init_mass = sc['mass_components'].copy() evap.weather_elements(sc, time_step, model_time) if on: assert np.all(sc['frac_lost'] > 0) and np.all(sc['frac_lost'] < 1.0) # all elements experience the same evaporation assert np.all(sc['frac_lost'][0] == sc['frac_lost']) for spill in sc.spills: mask = sc.get_spill_mask(spill) if on: assert np.all(sc['evap_decay_constant'][mask, :] < 0.0) else: assert np.all(sc['evap_decay_constant'][mask, :] == 0.0) print '\nevap_decay_const', sc['evap_decay_constant'] print 'frac_lost', sc['frac_lost'] if on: assert sc.mass_balance['evaporated'] > 0.0 print 'total evaporated', sc.mass_balance['evaporated'] else: assert 'evaporated' not in sc.mass_balance assert np.all(sc['mass_components'] == init_mass)
def test_dissolution_mass_balance(oil, temp, wind_speed, num_elems, expected_mb, on): ''' Test a single dissolution step. - for this, we need a dispersion weatherer to give us a droplet size distribution. Fuel Oil #6 does not exist... ''' et = floating(substance=oil) waves = build_waves_obj(wind_speed, 'knots', 270, temp) water = waves.water disp = NaturalDispersion(waves, water) diss = Dissolution(waves) all_array_types = diss.array_types.union(disp.array_types) (sc, time_step) = weathering_data_arrays(all_array_types, water, element_type=et, num_elements=num_elems, units='kg', amount_per_element=1.0)[:2] print 'time_step: {}'.format(time_step) print 'num spills:', len(sc.spills) print 'spill[0] amount: {} {}'.format(sc.spills[0].amount, sc.spills[0].units) print 'temperature = ', temp print 'wind = ', print '\n'.join([ '\t{} {}'.format(ts[1][0], waves.wind.units) for ts in waves.wind.timeseries ]) print # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None initial_amount = sc.spills[0].amount model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) if on: print('fraction dissolved: {}'.format(sc.mass_balance['dissolution'] / initial_amount)) print('fraction dissolved: {:.2%}'.format( sc.mass_balance['dissolution'] / initial_amount)) print sc.mass_balance['dissolution'], expected_mb assert np.isclose(sc.mass_balance['dissolution'], expected_mb, rtol=1e-4) else: assert 'dissolution' not in sc.mass_balance