From 7718971e829588de88cc0853563806d2dfcfcd7b Mon Sep 17 00:00:00 2001 From: Caitlin O'Connor Date: Wed, 29 Jul 2020 12:50:51 -0700 Subject: [PATCH 1/2] fixed biodegradation tests; updated other tests to use sample oils --- py_gnome/gnome/weatherers/bio_degradation.py | 34 +++------------- .../test_weatherers/test_bio_degradation.py | 39 +++++++------------ .../test_weatherers/test_dispersion.py | 4 +- .../test_weatherers/test_dissolution.py | 2 +- 4 files changed, 23 insertions(+), 56 deletions(-) diff --git a/py_gnome/gnome/weatherers/bio_degradation.py b/py_gnome/gnome/weatherers/bio_degradation.py index 49ccbb95c..0a7e2682a 100644 --- a/py_gnome/gnome/weatherers/bio_degradation.py +++ b/py_gnome/gnome/weatherers/bio_degradation.py @@ -202,11 +202,13 @@ def weather_elements(self, sc, time_step, model_time): continue # get the substance index - indx = sc._substances_spills.substances.index(substance) + #indx = sc._substances_spills.substances.index(substance) # get pseudocomponent boiling point and its type - assert 'boiling_point' in substance._sara.dtype.names - type_bp = substance._sara[['type','boiling_point']] + #assert 'boiling_point' in substance._sara.dtype.names + assert hasattr(substance,'boiling_point') + #type_bp = substance._sara[['type','boiling_point']] + type_bp = zip(substance.sara_type, substance.boiling_point) # get bio degradation rate coefficient array for this substance K_comp_rates = np.asarray(map(self.get_K_comp_rates, type_bp)) @@ -243,29 +245,3 @@ def weather_elements(self, sc, time_step, model_time): sc.update_from_fatedataview() - def serialize(self, json_='webapi'): - - toserial = self.to_serialize(json_) - schema = self.__class__._schema() - serial = schema.serialize(toserial) - - if json_ == 'webapi': - if self.waves: - serial['waves'] = self.waves.serialize(json_) - - return serial - - @classmethod - def deserialize(cls, json_): - - if not cls.is_sparse(json_): - schema = cls._schema() - dict_ = schema.deserialize(json_) - - if 'waves' in json_: - obj = json_['waves']['obj_type'] - dict_['waves'] = (eval(obj).deserialize(json_['waves'])) - - return dict_ - else: - return json_ diff --git a/py_gnome/tests/unit_tests/test_weatherers/test_bio_degradation.py b/py_gnome/tests/unit_tests/test_weatherers/test_bio_degradation.py index 2ea71f81b..6cf457096 100644 --- a/py_gnome/tests/unit_tests/test_weatherers/test_bio_degradation.py +++ b/py_gnome/tests/unit_tests/test_weatherers/test_bio_degradation.py @@ -21,17 +21,13 @@ Biodegradation, weatherer_sort) -from .conftest import weathering_data_arrays +from .conftest import weathering_data_arrays, test_oil from ..conftest import (sample_model_weathering2) from pprint import PrettyPrinter -pytestmark = pytest.mark.skipif(True, - reason="Biodeg tests all need to be updated") - - pp = PrettyPrinter(indent=2, width=120) wind = constant_wind(15., 270, 'knots') @@ -55,9 +51,10 @@ def test_sort_order(): waves = Waves(wind, Water()) bio_deg = Biodegradation(waves) - assert weatherer_sort(bio_deg) == 9 + assert weatherer_sort(bio_deg) == 11 +@pytest.mark.skipif(reason="serialization for weatherers overall needs review") def test_serialize_deseriailize(): 'test serialize/deserialize for webapi' @@ -83,12 +80,10 @@ def test_serialize_deseriailize(): def test_prepare_for_model_run(): - et = floating(substance='ABU SAFAH') bio_deg = Biodegradation(waves) (sc, time_step) = weathering_data_arrays(bio_deg.array_types, - water, - element_type=et)[:2] + water)[:2] assert 'bio_degradation' not in sc.mass_balance @@ -98,19 +93,17 @@ def test_prepare_for_model_run(): @pytest.mark.parametrize(('oil', 'temp', 'num_elems', 'expected_mb', 'on'), - [('ABU SAFAH', 311.15, 3, 0.0, True), - ('BAHIA', 311.15, 3, 0.0, True), - ('ALASKA NORTH SLOPE (MIDDLE PIPELINE)', 311.15, 3, - np.nan, False)]) + [('oil_ans_mp', 311.15, 3, 0.0, True), + #('ABU SAFAH', 311.15, 3, 0.0, True), + ('oil_bahia', 311.15, 3, 0.0, True), + ('oil_ans_mp', 311.15, 3, np.nan, False)]) def test_bio_degradation_mass_balance(oil, temp, num_elems, expected_mb, on): - et = floating(substance=oil) bio_deg = Biodegradation(waves) (sc, time_step) = weathering_data_arrays(bio_deg.array_types, water, - element_type=et, num_elements=num_elems)[:2] - model_time = (sc.spills[0].get('release_time') + + model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) bio_deg.on = on @@ -128,14 +121,12 @@ def test_bio_degradation_mass_balance(oil, temp, num_elems, expected_mb, on): @pytest.mark.parametrize(('oil', 'temp', 'expected_balance'), # TODO - expected ballance values: - [('ABU SAFAH', 288.7, -1), - ('ALASKA NORTH SLOPE (MIDDLE PIPELINE)', 288.7, - -1), - ('ALASKA NORTH SLOPE, OIL & GAS', 279.261, - -1), - ('BAHIA', 288.7, -1), - ] - ) + [(test_oil, 288.7, -1), + #('ABU SAFAH', 288.7, -1), + ('oil_ans_mp', 288.7, -1), + #('ALASKA NORTH SLOPE, OIL & GAS', 279.261, + #-1), + ('oil_bahia', 288.7, -1)]) def test_bio_degradation_full_run(sample_model_fcn2, oil, temp, expected_balance): ''' diff --git a/py_gnome/tests/unit_tests/test_weatherers/test_dispersion.py b/py_gnome/tests/unit_tests/test_weatherers/test_dispersion.py index 569dee1f5..f641041e9 100644 --- a/py_gnome/tests/unit_tests/test_weatherers/test_dispersion.py +++ b/py_gnome/tests/unit_tests/test_weatherers/test_dispersion.py @@ -100,12 +100,12 @@ def test_dispersion_not_active(oil, temp, num_elems): @pytest.mark.xfail # the test oils don't match the data base, using so tests don't depend on db @pytest.mark.parametrize(('oil', 'temp', 'dispersed'), - [('ABU SAFAH', 288.7, 63.076), + [('oil_bahia', 288.7, 133.784), + #('ABU SAFAH', 288.7, 63.076), # ('ALASKA NORTH SLOPE (MIDDLE PIPELINE)', ('oil_ans_mp', 288.7, 592.887), # ('BAHIA', 288.7, 14.472) - ('oil_bahia', 288.7, 133.784) ] ) def test_full_run(sample_model_fcn2, oil, temp, dispersed): diff --git a/py_gnome/tests/unit_tests/test_weatherers/test_dissolution.py b/py_gnome/tests/unit_tests/test_weatherers/test_dissolution.py index d6d39fa27..07e5f975c 100644 --- a/py_gnome/tests/unit_tests/test_weatherers/test_dissolution.py +++ b/py_gnome/tests/unit_tests/test_weatherers/test_dissolution.py @@ -353,7 +353,7 @@ def test_full_run(sample_model_fcn2, oil, temp, expected_balance): @pytest.mark.xfail @pytest.mark.parametrize(('oil', 'temp', 'expected_balance'), # [(_sample_oils['benzene'], 288.7, 2.98716) - [('benzene', 288.15, 9731.05479)]) + [('oil_benzene', 288.15, 9731.05479)]) def test_full_run_no_evap(sample_model_fcn2, oil, temp, expected_balance): ''' test dissolution outputs post step for a full run of model. Dump json From 93a179def48c86562de88cb7a450430d58e8215f Mon Sep 17 00:00:00 2001 From: Caitlin O'Connor Date: Mon, 3 Aug 2020 12:53:28 -0700 Subject: [PATCH 2/2] update to biodegradation to make yield rate a data array --- py_gnome/gnome/array_types.py | 2 ++ py_gnome/gnome/outputters/netcdf.py | 2 ++ py_gnome/gnome/weatherers/bio_degradation.py | 12 +++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/py_gnome/gnome/array_types.py b/py_gnome/gnome/array_types.py index c6bc5cd39..d680afad3 100644 --- a/py_gnome/gnome/array_types.py +++ b/py_gnome/gnome/array_types.py @@ -276,6 +276,8 @@ def split_element(self, num, value, l_frac=None): # fractional water content in emulsion 'frac_water': ((), np.float64, 'frac_water', 0), 'interfacial_area': ((), np.float64, 'interfacial_area', 0), + # internal factor for biodegradation + 'yield_factor': ((), np.float64, 'yield_factor', 0), # use negative as a not yet set flag 'bulltime': ((), np.float64, 'bulltime', -1.), 'frac_lost': ((), np.float64, 'frac_lost', 0), diff --git a/py_gnome/gnome/outputters/netcdf.py b/py_gnome/gnome/outputters/netcdf.py index 7358d961a..8eb7eb0b3 100644 --- a/py_gnome/gnome/outputters/netcdf.py +++ b/py_gnome/gnome/outputters/netcdf.py @@ -94,6 +94,7 @@ 'frac_coverage': {}, 'bulltime': {}, 'evap_decay_constant': {}, + 'yield_factor': {}, 'partition_coeff': {}, 'droplet_avg_size': {}, 'init_mass': {'long_name': 'initial mass', @@ -260,6 +261,7 @@ class NetCDFOutput(Outputter, OutputterFilenameMixin): 'bulltime', 'partition_coeff', 'evap_decay_constant', + 'yield_factor', ] _schema = NetCDFOutputSchema diff --git a/py_gnome/gnome/weatherers/bio_degradation.py b/py_gnome/gnome/weatherers/bio_degradation.py index 0a7e2682a..4d3e5c65c 100644 --- a/py_gnome/gnome/weatherers/bio_degradation.py +++ b/py_gnome/gnome/weatherers/bio_degradation.py @@ -56,6 +56,7 @@ def __init__(self, waves=None, **kwargs): 'mass_components': gat('mass_components'), 'droplet_avg_size': gat('droplet_avg_size'), 'positions': gat('positions'), + 'yield_factor': gat('yield_factor'), }) # @@ -217,19 +218,20 @@ def weather_elements(self, sc, time_step, model_time): # so we need recalculate ones for the time step interval K_comp_rates = K_comp_rates / (60 * 60 * 24) * time_step + self.previous_yield_factor = data['yield_factor'] # calculate yield factor (specific surace) if np.any(data['droplet_avg_size']): - yield_factor = 1.0 / (data['droplet_avg_size'] * data['density']) + data['yield_factor'] = 1.0 / (data['droplet_avg_size'] * data['density']) else: - yield_factor = 0.0 + data['yield_factor'] = 0.0 # calculate the mass over time step - bio_deg = self.bio_degradate_oil(K_comp_rates, data, yield_factor) + bio_deg = self.bio_degradate_oil(K_comp_rates, data, data['yield_factor']) # update yield factor for the next time step - self.prev_yield_factor = yield_factor + #self.prev_yield_factor = yield_factor - # calculate mass ballance for bio degradation process - mass loss + # calculate mass balance for bio degradation process - mass loss sc.mass_balance['bio_degradation'] += data['mass'].sum() - bio_deg.sum() # update masses