예제 #1
0
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])
예제 #2
0
    def test_constant_wind_after_model_time(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A constant wind should extrapolate if it is out of bounds,
            so prepare_for_model_step() should not fail.

            We are testing that the wind extrapolates properly, so the
            windages should be updated in the same way as the in-bounds test
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        wind = Wind(timeseries=np.array((wind_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(self.model_time) +
                                    self.time_step * ix)
            print 'curr_time = ', curr_time

            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #3
0
    def test_variable_wind_after_model_time(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A variable wind should not extrapolate if it is out of bounds,
            so prepare_for_model_step() should fail with an exception
            in this case.
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        time_series = (np.zeros((3, ), dtype=datetime_value_2d)
                       .view(dtype=np.recarray))
        time_series.time = [sec_to_date(date_to_sec(wind_time) +
                                        self.time_step * i)
                            for i in range(3)]
        time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.)))

        wind = Wind(timeseries=time_series.reshape(3),
                    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(self.model_time) +
                                    self.time_step * ix)

            with raises(RuntimeError):
                wm.prepare_for_model_step(self.sc, self.time_step, curr_time)
예제 #4
0
def test_empty_init():
    '''
    wind=None
    '''
    wm = WindMover()
    assert wm.make_default_refs
    _defaults(wm)
    assert wm.name == 'WindMover'
    print wm.validate()
예제 #5
0
def test_empty_init():
    '''
    wind=None
    '''
    wm = WindMover()
    assert wm.make_default_refs
    _defaults(wm)
    assert wm.name == 'WindMover'
    print wm.validate()
예제 #6
0
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'] = rel_time
    time_val['value'] = (2., 25.)

    wm = WindMover(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 is False
    assert np.all(delta == 0)  # model_time + time_step = active_start
예제 #7
0
def test_exception_new_from_dict():

    # WindMover does not modify Wind object!

    wm = WindMover(environment.Wind(filename=file_))

    wm_state = wm.to_dict('create')
    wm_state.update({'wind': environment.Wind(filename=file_)})

    with pytest.raises(ValueError):
        WindMover.new_from_dict(wm_state)
예제 #8
0
def test_serialize_deserialize(wind_circ):
    """
    tests and illustrate the funcitonality of serialize/deserialize for
    WindMover.
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    serial = wm.serialize()
    assert 'wind' in serial

    wm2 = wm.deserialize(serial)

    assert wm == wm2
예제 #9
0
def test_serialize_deserialize(wind_circ):
    """
    tests and illustrate the funcitonality of serialize/deserialize for
    WindMover.
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    serial = wm.serialize()
    assert 'wind' in serial

    wm2 = wm.deserialize(serial)

    assert wm == wm2
예제 #10
0
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
예제 #11
0
def test_serialize_deserialize(wind_circ):
    """
    tests and illustrate the funcitonality of serialize/deserialize for
    WindMover.
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    serial = wm.serialize('webapi')
    assert 'wind' in serial

    dict_ = wm.deserialize(serial)
    dict_['wind'] = wind_circ['wind']
    wm.update_from_dict(dict_)

    assert wm.wind == wind_circ['wind']
예제 #12
0
def test_properties(wind_circ):
    """
    test setting the properties of the object
    """
    wm = WindMover(wind_circ['wind'])

    wm.uncertain_duration = 1
    wm.uncertain_time_delay = 2
    wm.uncertain_speed_scale = 3
    wm.uncertain_angle_scale = 4

    assert wm.uncertain_duration == 1
    assert wm.uncertain_time_delay == 2
    assert wm.uncertain_speed_scale == 3
    assert wm.uncertain_angle_scale == 4
예제 #13
0
def test_data_start_stop(wind_circ):
    """
    test data_start / stop properties
    """
    wm = WindMover(wind_circ['wind'])
    assert wm.data_start == datetime(2012, 11, 6, 20, 10)
    assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
예제 #14
0
def make_model(images_dir=os.path.join(base_dir, 'images')):
    print 'initializing the model'

    start_time = datetime(2012, 9, 15, 12, 0)
    mapfile = get_datafile(os.path.join(base_dir, './LongIslandSoundMap.BNA'))

    gnome_map = MapFromBNA(mapfile, refloat_halflife=6)  # hours

    # # the image output renderer
    # global renderer

    # one hour timestep
    model = Model(start_time=start_time,
                  duration=timedelta(hours=48),
                  time_step=3600,
                  map=gnome_map,
                  uncertain=True,
                  cache_enabled=True)

    netcdf_file = os.path.join(base_dir, 'script_long_island.nc')
    scripting.remove_netcdf(netcdf_file)

    print 'adding outputters'
    model.outputters += Renderer(mapfile, images_dir, size=(800, 600))
    model.outputters += NetCDFOutput(netcdf_file, which_data='all')

    print 'adding a spill'
    spill = point_line_release_spill(num_elements=1000,
                                     start_position=(-72.419992, 41.202120,
                                                     0.0),
                                     release_time=start_time)
    model.spills += spill

    print 'adding a RandomMover:'
    model.movers += RandomMover(diffusion_coef=500000, uncertain_factor=2)

    print 'adding a wind mover:'
    series = np.zeros((5, ), dtype=datetime_value_2d)
    series[0] = (start_time, (10, 45))
    series[1] = (start_time + timedelta(hours=18), (10, 90))
    series[2] = (start_time + timedelta(hours=30), (10, 135))
    series[3] = (start_time + timedelta(hours=42), (10, 180))
    series[4] = (start_time + timedelta(hours=54), (10, 225))

    wind = Wind(timeseries=series, units='m/s')
    model.movers += WindMover(wind)

    print 'adding a cats mover:'
    curr_file = get_datafile(os.path.join(base_dir, r"./LI_tidesWAC.CUR"))
    tide_file = get_datafile(os.path.join(base_dir, r"./CLISShio.txt"))

    c_mover = CatsMover(curr_file, tide=Tide(tide_file))
    model.movers += c_mover
    model.environment += c_mover.tide

    print 'viewport is:', [
        o.viewport for o in model.outputters if isinstance(o, Renderer)
    ]

    return model
예제 #15
0
def setup_model():
    print 'initializing the model'
    # start with default time,duration...this will be changed when model is run
    model = Model(
    )  #change to use all defaults and set time_step also in Setup_TAP!!
    mapfile = os.path.join(setup.MapFileDir, setup.MapFileName)
    print 'adding the map: ', mapfile
    model.map = MapFromBNA(mapfile, refloat_halflife=0.0)  # seconds

    print 'adding a GridCurrentMover:'
    c_mover = GridCurrentMover(filename=setup.curr_fn, extrapolate=True)
    model.movers += c_mover

    print 'adding a WindMover:'
    w = Wind(filename=setup.wind_fn)
    w_mover = WindMover(w)
    # w_mover = GridWindMover(wind_file=setup.w_filelist)
    model.movers += w_mover

    if setup.diff_coef is not None:
        print 'adding a RandomMover:'
        random_mover = RandomMover(diffusion_coef=setup.diff_coef)  #in cm/s
        model.movers += random_mover

    return model
예제 #16
0
def make_model(images_dir=os.path.join(base_dir, 'images')):

    print 'creating the maps'
    mapfile = get_datafile(os.path.join(base_dir, 'LowerMississippiMap.bna'))
    gnome_map = MapFromBNA(mapfile, refloat_halflife=6)  # hours

    print 'initializing the model'
    start_time = datetime(2012, 9, 15, 12, 0)

    # default to now, rounded to the nearest hour
    model = Model(time_step=600,
                  start_time=start_time,
                  duration=timedelta(days=1),
                  map=gnome_map,
                  uncertain=True)

    print 'adding outputters'
    model.outputters += Renderer(mapfile, images_dir, image_size=(800, 600))

    netcdf_file = os.path.join(base_dir, 'script_lower_mississippi.nc')
    scripting.remove_netcdf(netcdf_file)
    model.outputters += NetCDFOutput(netcdf_file, which_data='all')

    print 'adding a RandomMover:'
    model.movers += RandomMover(diffusion_coef=10000)

    print 'adding a wind mover:'

    series = np.zeros((5, ), dtype=datetime_value_2d)
    series[0] = (start_time, (2, 45))
    series[1] = (start_time + timedelta(hours=18), (2, 90))
    series[2] = (start_time + timedelta(hours=30), (2, 135))
    series[3] = (start_time + timedelta(hours=42), (2, 180))
    series[4] = (start_time + timedelta(hours=54), (2, 225))

    w_mover = WindMover(Wind(timeseries=series, units='m/s'))
    model.movers += w_mover

    print 'adding a cats mover:'
    curr_file = get_datafile(os.path.join(base_dir, 'LMiss.CUR'))
    c_mover = CatsMover(curr_file)

    # but do need to scale (based on river stage)
    c_mover.scale = True
    c_mover.scale_refpoint = (-89.699944, 29.494558)

    # based on stage height 10ft (range is 0-18)
    c_mover.scale_value = 1.027154

    model.movers += c_mover

    print 'adding a spill'
    spill = point_line_release_spill(num_elements=1000,
                                     start_position=(-89.699944, 29.494558,
                                                     0.0),
                                     release_time=start_time)
    model.spills += spill

    return model
예제 #17
0
def test_properties(wind_circ):
    """
    test setting the properties of the object
    """
    wm = WindMover(wind_circ['wind'])

    wm.uncertain_duration = 1
    wm.uncertain_time_delay = 2
    wm.uncertain_speed_scale = 3
    wm.uncertain_angle_scale = 4

    assert wm.uncertain_duration == 1
    assert wm.uncertain_time_delay == 2
    assert wm.uncertain_speed_scale == 3
    assert wm.uncertain_angle_scale == 4
    assert wm.data_start == datetime(2012, 11, 6, 20, 10)
    assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
예제 #18
0
def test_exceptions():
    """
    Test ValueError exception thrown if improper input arguments
    """
    with raises(ReferencedObjectNotSet) as excinfo:
        wm = WindMover()
        wm.prepare_for_model_run()
    print excinfo.value.message

    with raises(TypeError):
        """
        violates duck typing so may want to remove. Though current WindMover's
        backend cython object looks for C++ OSSM object which is embedded in
        Wind object which is why this check was enforced. Can be
        re-evaluated if there is a need.
        """
        WindMover(wind=10)
예제 #19
0
def test_exceptions():
    """
    Test ValueError exception thrown if improper input arguments
    """
    with raises(ReferencedObjectNotSet) as excinfo:
        wm = WindMover()
        wm.prepare_for_model_run()
    print excinfo.value.message

    with raises(TypeError):
        """
        violates duck typing so may want to remove. Though current WindMover's
        backend cython object looks for C++ OSSM object which is embedded in
        Wind object which is why this check was enforced. Can be
        re-evaluated if there is a need.
        """
        WindMover(wind=10)
예제 #20
0
def test_serialize_deserialize(wind_circ, do):
    """
    tests and illustrates the funcitonality of serialize/deserialize for
    WindMover.
    """
    wind = environment.Wind(filename=file_)
    wm = WindMover(wind)
    json_ = wm.serialize(do)
    if do == 'create':
        assert 'wind' not in json_

        # reference to 'wind' object is made by the Model().save() function
        # by default 'wind' object is not serialized in 'create' mode
        # so for this test to work, add the 'wind' key, value back in before
        # constructing new WindMover. In the real use case, the model does this
        dict_ = wm.deserialize(json_)
        dict_['wind'] = wind
        wm2 = WindMover.new_from_dict(dict_)
        assert wm == wm2

    else:
        assert 'wind' in json_

        wind_update = wind_circ['wind']
        json_['wind'] = wind_update.serialize(do)
        dict_ = wm.deserialize(json_)
        wm.from_dict(dict_)

        assert wm.wind == wind_update
예제 #21
0
def test_array_types():
    """
    Check the array_types property of WindMover contains array_types.WindMover
    """
    # WindMover does not modify Wind object!
    wm = WindMover(Wind(filename=file_))

    for t in ('windages', 'windage_range', 'windage_persist'):
        assert t in wm.array_types
def test_wind_mover():
    """
    use a wind_mover, about as simple as it comes
    """

    # fake data arrays:
    num = 2
    pos_dt = np.dtype([('lon', np.float), ('lat', np.float), ('depth', np.float)])
    sc = SC({'positions': np.zeros((num,), dtype=pos_dt),
             'status_codes': np.zeros((num,), dtype=np.int16),
             'windages': np.zeros((num,)),
             })
#    delta = np.zeros_like(sc['positions'])

    wind = wind_from_values([(datetime(2016, 5, 10, 12, 0), 5, 45),
                             (datetime(2016, 5, 10, 12, 20), 6, 50),
                             (datetime(2016, 5, 10, 12, 40), 7, 55),
                             ])
    wm = WindMover(wind)
    # in time span, this should work:
    wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 20))

    # before timespan -- this should fail
    with pytest.raises(RuntimeError):
        wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))

    # after timespan -- this should fail
    with pytest.raises(RuntimeError):
        wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50))

    # # test the message:
    # try:
    #     wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))
    # except RuntimeError as err:

    try:
        wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))
    except RuntimeError as err:
        msg = err.args[0]
        assert "No available data" in msg
        assert "WindMover" in msg
        assert "2016-05-10 11:50:00" in msg
        assert "2016-05-10 12:00:00" in msg
        assert "2016-05-10 12:40:00" in msg
예제 #23
0
def test_new_from_dict():
    """
    Currently only checks that new object can be created from dict
    It does not check equality of objects
    """

    wind = environment.Wind(filename=file_)
    wm = WindMover(wind)  # WindMover does not modify Wind object!
    wm_state = wm.to_dict('create')

    # must create a Wind object and add this to wm_state dict

    wind2 = environment.Wind.new_from_dict(wind.to_dict('create'))
    wm_state.update({'wind': wind2})
    wm2 = WindMover.new_from_dict(wm_state)

    assert wm is not wm2
    assert wm.wind is not wm2.wind
    assert wm == wm2
예제 #24
0
def test_update_wind(wind_circ):
    """
    Create a wind object and update it's timeseries.
    Make sure the internal C++ WindMover's properties have also changed
    """
    o_wind = wind_circ['wind']  # original wind value
    wm = WindMover(o_wind)  # define wind mover

    # update wind timeseries - default format is magnitude_direction

    t_dtv = np.zeros((3, ), dtype=datetime_value_2d).view(dtype=np.recarray)
    t_dtv.time = [datetime(2012, 11, 06, 20, 0 + i, 30) for i in range(3)]
예제 #25
0
def test_timeseries_init(wind_circ):
    """
    test default properties of the object are initialized correctly
    """
    wm = WindMover(wind_circ['wind'])
    _defaults(wm)
    assert not wm.make_default_refs
    cpp_timeseries = _get_timeseries_from_cpp(wm)

    assert np.all(cpp_timeseries['time'] == wind_circ['uv']['time'])
    assert np.allclose(cpp_timeseries['value'], wind_circ['uv']['value'],
                       atol, rtol)
예제 #26
0
def test_callback_add_mover():
    'Test callback after add mover'
    units = 'meter per second'

    model = Model()
    model.start_time = datetime(2012, 1, 1, 0, 0)
    model.duration = timedelta(hours=10)
    model.time_step = timedelta(hours=1)

    # start_loc = (1.0, 2.0, 0.0)  # random non-zero starting points

    # add Movers
    model.movers += SimpleMover(velocity=(1., -1., 0.))
    series = np.array((model.start_time, (10, 45)),
                      dtype=datetime_value_2d).reshape((1, ))
    model.movers += WindMover(Wind(timeseries=series, units=units))

    # this should create a Wind object
    new_wind = Wind(timeseries=series, units=units)
    model.environment += new_wind
    assert new_wind in model.environment
    assert len(model.environment) == 2

    tide_ = Tide(filename=testdata['CatsMover']['tide'])

    d_file = testdata['CatsMover']['curr']
    model.movers += CatsMover(d_file, tide=tide_)

    model.movers += CatsMover(d_file)

    for mover in model.movers:
        assert mover.active_start == inf_datetime.InfDateTime('-inf')
        assert mover.active_stop == inf_datetime.InfDateTime('inf')

        if hasattr(mover, 'wind'):
            assert mover.wind in model.environment

        if hasattr(mover, 'tide'):
            if mover.tide is not None:
                assert mover.tide in model.environment

    # Add a mover with user defined active_start / active_stop values
    # - these should not be updated

    active_on = model.start_time + timedelta(hours=1)
    active_off = model.start_time + timedelta(hours=4)
    custom_mover = SimpleMover(velocity=(1., -1., 0.),
                               active_start=active_on,
                               active_stop=active_off)
    model.movers += custom_mover

    assert model.movers[custom_mover.id].active_start == active_on
    assert model.movers[custom_mover.id].active_stop == active_off
예제 #27
0
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])
예제 #28
0
    def test_constant_wind_after_model_time(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A constant wind should extrapolate if it is out of bounds,
            so prepare_for_model_step() should not fail.

            We are testing that the wind extrapolates properly, so the
            windages should be updated in the same way as the in-bounds test
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        wind = Wind(timeseries=np.array((wind_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(self.model_time) +
                                    self.time_step * ix)
            print 'curr_time = ', curr_time

            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #29
0
    def test_variable_wind_after_model_time(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A variable wind should not extrapolate if it is out of bounds,
            so prepare_for_model_step() should fail with an exception
            in this case.
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        time_series = (np.zeros((3, ), dtype=datetime_value_2d)
                       .view(dtype=np.recarray))
        time_series.time = [sec_to_date(date_to_sec(wind_time) +
                                        self.time_step * i)
                            for i in range(3)]
        time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.)))

        wind = Wind(timeseries=time_series.reshape(3),
                    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(self.model_time) +
                                    self.time_step * ix)

            with raises(RuntimeError):
                wm.prepare_for_model_step(self.sc, self.time_step, curr_time)
예제 #30
0
def test_new_from_dict():
    """
    Currently only checks that new object can be created from dict
    It does not check equality of objects
    """

    wind = environment.Wind(filename=file_)
    wm = WindMover(wind)  # WindMover does not modify Wind object!
    wm_state = wm.to_dict('create')

    # must create a Wind object and add this to wm_state dict

    wind2 = environment.Wind.new_from_dict(wind.to_dict('create'))
    wm_state.update({'wind': wind2})
    wm2 = WindMover.new_from_dict(wm_state)

    # check serializable state is correct

    assert all([wm.__getattribute__(k) == wm2.__getattribute__(k)
               for k in WindMover.state.get_names('create') if k
               != 'wind_id' and k != 'obj_type'])
    assert wm.wind.id == wm2.wind.id
예제 #31
0
def test_save_load(save_ref, saveloc_):
    """
    tests and illustrates the functionality of save/load for
    WindMover
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    wm_fname = 'WindMover_save_test.json'
    refs = None
    if save_ref:
        w_fname = 'Wind.json'
        refs = References()
        refs.reference(wind, w_fname)
        wind.save(saveloc_, refs, w_fname)

    wm.save(saveloc_, references=refs, name=wm_fname)

    l_refs = References()
    obj = load(os.path.join(saveloc_, wm_fname), l_refs)
    assert (obj == wm and obj is not wm)
    assert (obj.wind == wind and obj.wind is not wind)
    shutil.rmtree(saveloc_)  # clean-up
예제 #32
0
def test_save_load(save_ref, saveloc_):
    """
    tests and illustrates the functionality of save/load for
    WindMover
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    wm_fname = 'WindMover_save_test.json'
    refs = None
    if save_ref:
        w_fname = 'Wind.json'
        refs = References()
        refs.reference(wind, w_fname)
        wind.save(saveloc_, refs, w_fname)

    wm.save(saveloc_, references=refs, name=wm_fname)

    l_refs = References()
    obj = load(os.path.join(saveloc_, wm_fname), l_refs)
    assert (obj == wm and obj is not wm)
    assert (obj.wind == wind and obj.wind is not wind)
    shutil.rmtree(saveloc_)  # clean-up
예제 #33
0
    def test_variable_wind_after_model_time_with_extrapolation(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A variable wind can extrapolate if it is configured to do so,
            so prepare_for_model_step() should succeed in this case.

            We are testing that the wind extrapolates properly, so the
            windages should be updated in the same way as the in-bounds test
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        time_series = (np.zeros((3, ), dtype=datetime_value_2d)
                       .view(dtype=np.recarray))
        time_series.time = [sec_to_date(date_to_sec(wind_time) +
                                        self.time_step * i)
                            for i in range(3)]
        time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.)))

        wind = Wind(timeseries=time_series.reshape(3),
                    extrapolation_is_allowed=True,
                    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(self.model_time) +
                                    self.time_step * ix)

            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #34
0
def test_exceptions():
    """
    Test ValueError exception thrown if improper input arguments
    """
    with pytest.raises(TypeError):
        WindMover()

    with pytest.raises(ValueError):
        WindMover(environment.Wind(filename=file_),
                  uncertain_angle_units='xyz')

    with pytest.raises(ValueError):
        wm = WindMover(environment.Wind(filename=file_))
        wm.set_uncertain_angle(.4, 'xyz')

    with pytest.raises(TypeError):
        """
        violates duck typing so may want to remove. Though current WindMover's
        backend cython object looks for C++ OSSM object which is embedded in
        environment.Wind object which is why this check was enforced. Can be
        re-evaluated if there is a need.
        """
        WindMover(wind=10)
예제 #35
0
    def test_windages_updated(self):
        '''
            explicitly test to make sure:
            - windages are being updated for persistence != 0 and
            - windages are not being changed for persistance == -1
        '''
        wind = Wind(timeseries=np.array((self.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(self.model_time) +
                                    self.time_step * ix)
            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #36
0
def make_model(images_dir=os.path.join(base_dir,"images")):
    print "initializing the model"

    start_time = datetime(2013, 7, 23, 0)
    model = Model(start_time = start_time,
                              duration = timedelta(hours=47),	# n+1 of data in file
                              time_step = 900, # 4 hr in seconds
                              uncertain = False,
                              )
    
    mapfile = os.path.join(base_dir, './coast.bna')
    print "adding the map"
    gnome_map = MapFromBNA(mapfile, refloat_halflife=6)  # hours
    
    print "adding renderer" 
    model.outputters += Renderer(mapfile, images_dir, size=(1800, 1600))

    print "adding a wind mover from a time-series"
    ## this is wind
    wind_file=get_datafile(os.path.join(base_dir, 'wind.WND'))
    wind = Wind(filename=wind_file)
    w_mover = WindMover(wind)
    model.movers += w_mover
    
    print "adding a current mover:"
    ## this is currents
    curr_file = get_datafile(os.path.join(base_dir, 'current.txt'))
    model.movers += GridCurrentMover(curr_file)

    ##
    ## Add some spills (sources of elements)
    ##
    print "adding 13 points in a cluster that has some small initial separation as the source of spill"
    
    for i in range(len(coor)):
        
        aaa=utmToLatLng(14,coor[i][0],coor[i][1],northernHemisphere=True)
        model.spills += point_line_release_spill(num_elements=1,
                                                start_position = (aaa[1],aaa[0], 0.0),
                                                release_time = start_time,
                                                )

    print "adding netcdf output"
    netcdf_output_file = os.path.join(base_dir,'GNOME_output.nc')
    scripting.remove_netcdf(netcdf_output_file)
    model.outputters += NetCDFOutput(netcdf_output_file, which_data='all')

    return model
예제 #37
0
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
예제 #38
0
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 = 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.get('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
예제 #39
0
def test_properties(wind_circ):
    """
    test setting the properties of the object
    """
    wm = WindMover(wind_circ['wind'])

    wm.uncertain_duration = 1
    wm.uncertain_time_delay = 2
    wm.uncertain_speed_scale = 3
    wm.set_uncertain_angle(4, 'deg')

    assert wm.uncertain_duration == 1
    assert wm.uncertain_time_delay == 2
    assert wm.uncertain_speed_scale == 3
    assert wm.uncertain_angle_scale == 4
    assert wm.uncertain_angle_units == 'deg'

    wm.set_uncertain_angle(.04, 'rad')
    assert wm.uncertain_angle_scale == 0.04
    assert wm.uncertain_angle_units == 'rad'
예제 #40
0
def test_serialize_deserialize(wind_circ):
    """
    tests and illustrate the funcitonality of serialize/deserialize for
    WindMover.
    """
    wind = Wind(filename=file_)
    wm = WindMover(wind)
    serial = wm.serialize('webapi')
    assert 'wind' in serial

    dict_ = wm.deserialize(serial)
    dict_['wind'] = wind_circ['wind']
    wm.update_from_dict(dict_)

    assert wm.wind == wind_circ['wind']
예제 #41
0
def test_properties(wind_circ):
    """
    test setting the properties of the object
    """
    wm = WindMover(wind_circ['wind'])

    wm.uncertain_duration = 1
    wm.uncertain_time_delay = 2
    wm.uncertain_speed_scale = 3
    wm.uncertain_angle_scale = 4

    assert wm.uncertain_duration == 1
    assert wm.uncertain_time_delay == 2
    assert wm.uncertain_speed_scale == 3
    assert wm.uncertain_angle_scale == 4
예제 #42
0
def make_model(images_dir):
    print 'initializing the model'

    timestep = timedelta(minutes=15)  # this is already default
    start_time = datetime(2012, 9, 15, 12, 0)
    model = Model(timestep, start_time)

    # timeseries for wind data. The value is interpolated if time is between
    # the given datapoints
    series = np.zeros((4, ), dtype=datetime_value_2d)
    series[:] = [(start_time, (5, 180)),
                 (start_time + timedelta(hours=6), (10, 180)),
                 (start_time + timedelta(hours=12), (12, 180)),
                 (start_time + timedelta(hours=18), (8, 180))]
    wind = Wind(timeseries=series, units='m/s')
    model.environment += wind

    # include a wind mover and random diffusion
    print 'adding movers'
    model.movers += [WindMover(wind), RandomMover()]

    # add particles
    print 'adding particles'
    release = release_from_splot_data(start_time,
                                      'GL.2013267._LE_WHOLELAKE.txt')
    model.spills += Spill(release)

    # output data as png images and in netcdf format
    print 'adding outputters'
    netcdf_file = os.path.join(base_dir, 'script_example.nc')

    # ignore renderer for now
    model.outputters += [
        Renderer(images_dir=images_dir,
                 size=(800, 800),
                 projection_class=GeoProjection),
        NetCDFOutput(netcdf_file)
    ]

    print 'model complete'
    return model
예제 #43
0
def test_properties(wind_circ):
    """
    test setting the properties of the object
    """
    wm = WindMover(wind_circ['wind'])

    wm.uncertain_duration = 1
    wm.uncertain_time_delay = 2
    wm.uncertain_speed_scale = 3
    wm.uncertain_angle_scale = 4

    assert wm.uncertain_duration == 1
    assert wm.uncertain_time_delay == 2
    assert wm.uncertain_speed_scale == 3
    assert wm.uncertain_angle_scale == 4
    assert wm.data_start == datetime(2012, 11, 6, 20, 10)
    assert wm.data_stop == datetime(2012, 11, 6, 20, 15)
예제 #44
0
def test_read_file_init():
    """
    initialize from a long wind file
    """

    wind = Wind(filename=file_)
    wm = WindMover(wind)
    wind_ts = wind.get_wind_data(coord_sys='uv', units='meter per second')
    _defaults(wm)  # check defaults set correctly
    assert not wm.make_default_refs
    cpp_timeseries = _get_timeseries_from_cpp(wm)
    _assert_timeseries_equivalence(cpp_timeseries, wind_ts)

    # make sure default units is correct and correctly called
    # NOTE: Following functionality is already tested in test_wind.py,
    #       but what the heck - do it here too.

    wind_ts = wind.get_wind_data(coord_sys=ts_format.uv)
    cpp_timeseries['value'] = uc.convert('Velocity',
                                         'meter per second', wind.units,
                                         cpp_timeseries['value'])

    _assert_timeseries_equivalence(cpp_timeseries, wind_ts)
예제 #45
0
def test_model_release_after_start():
    '''
    This runs the model for a simple spill, that starts after the model starts
    '''
    units = 'meter per second'
    seconds_in_minute = 60
    start_time = datetime(2013, 2, 22, 0)

    model = Model(time_step=30 * seconds_in_minute,
                  start_time=start_time,
                  duration=timedelta(hours=3))

    # add a spill that starts after the run begins.
    release_time = start_time + timedelta(hours=1)
    model.spills += point_line_release_spill(num_elements=5,
                                             start_position=(0, 0, 0),
                                             release_time=release_time)

    # and another that starts later..

    model.spills += point_line_release_spill(num_elements=4,
                                             start_position=(0, 0, 0),
                                             release_time=(start_time +
                                                           timedelta(hours=2)))

    # Add a Wind mover:
    series = np.array((start_time, (10, 45)), dtype=datetime_value_2d).reshape(
        (1, ))
    model.movers += WindMover(Wind(timeseries=series, units=units))

    for step in model:
        print 'running a step'
        assert step['step_num'] == model.current_time_step

        for sc in model.spills.items():
            print 'num_LEs', len(sc['positions'])
예제 #46
0
    def test_variable_wind_after_model_time_with_extrapolation(self):
        '''
            test to make sure the wind mover is behaving properly with
            out-of-bounds winds.
            A variable wind can extrapolate if it is configured to do so,
            so prepare_for_model_step() should succeed in this case.

            We are testing that the wind extrapolates properly, so the
            windages should be updated in the same way as the in-bounds test
        '''
        wind_time = datetime(2012, 8, 21, 13)  # one day after model time

        time_series = (np.zeros((3, ), dtype=datetime_value_2d)
                       .view(dtype=np.recarray))
        time_series.time = [sec_to_date(date_to_sec(wind_time) +
                                        self.time_step * i)
                            for i in range(3)]
        time_series.value = np.array(((2., 25.), (2., 25.), (2., 25.)))

        wind = Wind(timeseries=time_series.reshape(3),
                    extrapolation_is_allowed=True,
                    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(self.model_time) +
                                    self.time_step * ix)

            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #47
0
    def test_windages_updated(self):
        '''
            explicitly test to make sure:
            - windages are being updated for persistence != 0 and
            - windages are not being changed for persistance == -1
        '''
        wind = Wind(timeseries=np.array((self.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(self.model_time) +
                                    self.time_step * ix)
            old_windages = np.copy(self.sc['windages'])
            wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            mask = self.sc['windage_persist'] == -1
            assert np.all(self.sc['windages'][mask] == old_windages[mask])

            mask = self.sc['windage_persist'] > 0
            assert np.all(self.sc['windages'][mask] != old_windages[mask])
예제 #48
0
def make_model(images_dir=os.path.join(base_dir, 'images')):

    # create the maps:

    print 'creating the maps'
    mapfile = get_datafile(os.path.join(base_dir, 'SanJuanMap.bna'))
    gnome_map = MapFromBNA(mapfile, refloat_halflife=1,
                           raster_size=1024 * 1024)

    renderer = Renderer(mapfile,
                        images_dir,
                        size=(800, 800),
                        projection_class=GeoProjection)

    renderer.viewport = ((-66.24, 18.39), (-66.1, 18.55))

    print 'initializing the model'
    start_time = datetime(2014, 9, 3, 13, 0)

    # 15 minutes in seconds
    # Default to now, rounded to the nearest hour
    model = Model(time_step=900, start_time=start_time,
                  duration=timedelta(days=1),
                  map=gnome_map, uncertain=False)

    print 'adding outputters'
    model.outputters += renderer

    netcdf_file = os.path.join(base_dir, 'script_san_juan.nc')
    scripting.remove_netcdf(netcdf_file)
    model.outputters += NetCDFOutput(netcdf_file, which_data='all')

    print 'adding a RandomMover:'
    model.movers += RandomMover(diffusion_coef=100000)

    print 'adding a wind mover:'

    series = np.zeros((2, ), dtype=datetime_value_2d)
    series[0] = (start_time, (0, 270))
    series[1] = (start_time + timedelta(hours=18), (0, 270))

    wind = Wind(timeseries=series, units='m/s')
    w_mover = WindMover(wind)
    w_mover.extrapolate = True
    model.movers += w_mover

    print 'adding a cats shio mover:'

    # need to add the scale_factor for the tide heights file
    curr_file = get_datafile(os.path.join(base_dir, 'EbbTides.cur'))
    tide_file = get_datafile(os.path.join(base_dir, 'EbbTidesShioHt.txt'))

    c_mover = CatsMover(curr_file, tide=Tide(tide_file, scale_factor=.15))

    # this is the value in the file (default)
    c_mover.scale_refpoint = (-66.116667, 18.458333)
    c_mover.scale = True
    c_mover.scale_value = 1.0
    # c_mover.tide.scale_factor = 0.15

    model.movers += c_mover

    print 'adding a cats mover:'

    curr_file = get_datafile(os.path.join(base_dir, 'Offshore.cur'))

    c_mover = CatsMover(curr_file)

    # this is the value in the file (default)
    # c_mover.scale_refpoint = (-66.082836, 18.469334)
    c_mover.scale_refpoint = (-66.084333333, 18.46966667)
    c_mover.scale = True
    c_mover.scale_value = 0.1

    model.movers += c_mover

    print 'adding a spill'

    end_time = start_time + timedelta(hours=12)
    spill = point_line_release_spill(num_elements=1000,
                                     release_time=start_time,
                                     start_position=(-66.16374,
                                                     18.468054, 0.0),
                                     # start_position=(-66.129099,
                                     #                 18.465332, 0.0),
                                     # end_release_time=end_time,
                                     )

    model.spills += spill

    return model
예제 #49
0
def make_model(images_dir=os.path.join(base_dir, 'images')):
    print 'initializing the model'

    start_time = datetime(2004, 12, 31, 13, 0)

    # 1 day of data in file
    # 1/2 hr in seconds
    model = Model(start_time=start_time,
                  duration=timedelta(days=1),
                  time_step=30 * 60,
                  uncertain=True)

    mapfile = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.bna'))

    print 'adding the map'
    model.map = MapFromBNA(mapfile, refloat_halflife=1)  # seconds

    # draw_ontop can be 'uncertain' or 'forecast'
    # 'forecast' LEs are in black, and 'uncertain' are in red
    # default is 'forecast' LEs draw on top
    renderer = Renderer(mapfile, images_dir, size=(800, 600),
                        output_timestep=timedelta(hours=2),
                        draw_ontop='forecast')
    # set the viewport to zoom in on the map:
    renderer.viewport = ((-76.5, 37.), (-75.8, 38.))
    # add the raster map, so we can see it...
    # note: this is really slow, so only use for diagnostics
    # renderer.raster_map = model.map

    print 'adding outputters'
    model.outputters += renderer

    netcdf_file = os.path.join(base_dir, 'script_chesapeake_bay.nc')
    scripting.remove_netcdf(netcdf_file)
    model.outputters += NetCDFOutput(netcdf_file, which_data='all',
                                     output_timestep=timedelta(hours=2))

    print 'adding a spill'
    # for now subsurface spill stays on initial layer
    # - will need diffusion and rise velocity
    # - wind doesn't act
    # - start_position = (-76.126872, 37.680952, 5.0),
    spill = point_line_release_spill(num_elements=1000,
                                     start_position=(-76.126872,
                                                     37.680952,
                                                     0.0),
                                     release_time=start_time)

    model.spills += spill

    print 'adding a RandomMover:'
    model.movers += RandomMover(diffusion_coef=50000)

    print 'adding a wind mover:'

    series = np.zeros((2, ), dtype=datetime_value_2d)
    series[0] = (start_time, (30, 0))
    series[1] = (start_time + timedelta(hours=23), (30, 0))

    wind = Wind(timeseries=series, units='knot')

    # default is .4 radians
    w_mover = WindMover(wind, uncertain_angle_scale=0)
    w_mover.extrapolate=True
    model.movers += w_mover

    print 'adding a current mover:'
    curr_file = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.nc'))
    topology_file = get_datafile(os.path.join(base_dir, 'ChesapeakeBay.dat'))

    # uncertain_time_delay in hours
    c_mover = GridCurrentMover(curr_file, topology_file,
                               uncertain_time_delay=3)
    c_mover.uncertain_along = 0  # default is .5
    # c_mover.uncertain_cross = 0  # default is .25

    model.movers += c_mover

    return model
예제 #50
0
def test_timespan():
    """
    Ensure the active flag is being set correctly and checked,
    such that if active=False, the delta produced by get_move = 0
    """
    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)
    model_time = rel_time
    time_val = np.zeros((1, ), dtype=datetime_value_2d)
    time_val['time'] = rel_time
    time_val['value'] = (2., 25.)

    wm = WindMover(Wind(timeseries=time_val,
                        units='meter per second'),
                   active_start=model_time + timedelta(seconds=time_step))

    wm.prepare_for_model_run()
    wm.prepare_for_model_step(sc, time_step, model_time)

    delta = wm.get_move(sc, time_step, model_time)
    wm.model_step_is_done()

    assert wm.active is False
    assert np.all(delta == 0)  # model_time + time_step = active_start

    wm.active_start = model_time - timedelta(seconds=time_step / 2)
    wm.prepare_for_model_step(sc, time_step, model_time)

    delta = wm.get_move(sc, time_step, model_time)
    wm.model_step_is_done()

    assert wm.active is True
    print '''\ntest_timespan delta \n{0}'''.format(delta)
    assert np.all(delta[:, :2] != 0)  # model_time + time_step > active_start
예제 #51
0
class TestWindMover:
    """
    gnome.WindMover() test
    """
    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)

    time_val = np.array((model_time, (2., 25.)),
                        dtype=datetime_value_2d).reshape(1)
    wind = Wind(timeseries=time_val, units='meter per second')
    wm = WindMover(wind)

    wm.prepare_for_model_run()

    def test_string_repr_no_errors(self):
        print
        print '======================'
        print 'repr(WindMover): '
        print repr(self.wm)
        print
        print 'str(WindMover): '
        print str(self.wm)
        assert True

    def test_get_move(self):
        """
        Test the get_move(...) results in WindMover match the expected delta
        """
        for ix in range(2):
            curr_time = sec_to_date(date_to_sec(self.model_time) +
                                    self.time_step * ix)
            self.wm.prepare_for_model_step(self.sc, self.time_step, curr_time)

            delta = self.wm.get_move(self.sc, self.time_step, curr_time)
            actual = self._expected_move()

            # the results should be independent of model time
            tol = 1e-8

            msg = ('{0} is not within a tolerance of '
                   '{1}'.format('WindMover.get_move()', tol))
            np.testing.assert_allclose(delta, actual, tol, tol, msg, 0)

            assert self.wm.active

            ts = date_to_sec(curr_time) - date_to_sec(self.model_time)
            print ('Time step [sec]:\t{0}'
                   'C++ delta-move:\n{1}'
                   'Expected delta-move:\n{2}'
                   ''.format(ts, delta, actual))

        self.wm.model_step_is_done()

    def test_get_move_exceptions(self):
        curr_time = sec_to_date(date_to_sec(self.model_time) + self.time_step)
        tmp_windages = self.sc._data_arrays['windages']
        del self.sc._data_arrays['windages']

        with raises(KeyError):
            self.wm.get_move(self.sc, self.time_step, curr_time)

        self.sc._data_arrays['windages'] = tmp_windages

    def test_update_wind_vel(self):
        self.time_val['value'] = (1., 120.)  # now given as (r, theta)
        self.wind.set_wind_data(self.time_val, units='meter per second')
        self.test_get_move()
        self.test_get_move_exceptions()

    def _expected_move(self):
        """
        Put the expected move logic in separate (fixture) if it gets used
        multiple times
        """
        uv = r_theta_to_uv_wind(self.time_val['value'])
        exp = np.zeros((self.sc.num_released, 3))
        exp[:, 0] = self.sc['windages'] * uv[0, 0] * self.time_step
        exp[:, 1] = self.sc['windages'] * uv[0, 1] * self.time_step

        xform = FlatEarthProjection.meters_to_lonlat(exp, self.sc['positions'])
        return xform
예제 #52
0
def test_timespan():
    """
    Ensure the active flag is being set correctly and checked,
    such that if active=False, the delta produced by get_move = 0
    """

    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)
    model_time = rel_time
    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'), active_start=model_time
                   + timedelta(seconds=time_step))

    wm.prepare_for_model_run()
    wm.prepare_for_model_step(sc, time_step, model_time)
    delta = wm.get_move(sc, time_step, model_time)
    wm.model_step_is_done()
    assert wm.active == False
    assert np.all(delta == 0)  # model_time + time_step = active_start

    wm.active_start = model_time - timedelta(seconds=time_step / 2)
    wm.prepare_for_model_step(sc, time_step, model_time)
    delta = wm.get_move(sc, time_step, model_time)
    wm.model_step_is_done()

    assert wm.active == True
    print '''\ntest_timespan delta \n{0}'''.format(delta)
    assert np.all(delta[:, :2] != 0)  # model_time + time_step > active_start
예제 #53
0
def make_model(uncertain=False, mode='gnome'):
    '''
    Create a model from the data in sample_data/boston_data
    It contains:
      - the GeoProjection
      - wind mover
      - random mover
      - cats shio mover
      - cats ossm mover
      - plain cats mover
    '''
    start_time = datetime(2013, 2, 13, 9, 0)
    model = Model(start_time=start_time,
                  duration=timedelta(days=2),
                  time_step=timedelta(minutes=30).total_seconds(),
                  uncertain=uncertain,
                  map=MapFromBNA(testdata['boston_data']['map'],
                                 refloat_halflife=1),
                  mode=mode)

    print 'adding a spill'
    start_position = (144.664166, 13.441944, 0.0)
    end_release_time = start_time + timedelta(hours=6)
    spill_amount = 1000.0
    spill_units = 'kg'
    model.spills += point_line_release_spill(num_elements=1000,
                                             start_position=start_position,
                                             release_time=start_time,
                                             end_release_time=end_release_time,
                                             amount=spill_amount,
                                             units=spill_units,
                                             substance=test_oil)
    spill = model.spills[-1]
    spill_volume = spill.get_mass() / spill.substance.density_at_temp()
    # need a scenario for SimpleMover
    # model.movers += SimpleMover(velocity=(1.0, -1.0, 0.0))

    print 'adding a RandomMover:'
    model.movers += RandomMover(diffusion_coef=100000)

    print 'adding a wind mover:'

    series = np.zeros((2, ), dtype=datetime_value_2d)
    series[0] = (start_time, (5, 180))
    series[1] = (start_time + timedelta(hours=18), (5, 180))

    w_mover = WindMover(Wind(timeseries=series, units='m/s'))

    model.movers += w_mover
    model.environment += w_mover.wind

    print 'adding a cats shio mover:'

    c_mover = CatsMover(testdata['boston_data']['cats_curr2'],
                        tide=Tide(testdata['boston_data']['cats_shio']))

    # c_mover.scale_refpoint should automatically get set from tide object
    c_mover.scale = True  # default value
    c_mover.scale_value = -1

    # tide object automatically gets added by model
    model.movers += c_mover

    print 'adding a cats ossm mover:'

    c_mover = CatsMover(testdata['boston_data']['cats_curr2'],
                        tide=Tide(testdata['boston_data']['cats_ossm']))

    c_mover.scale = True  # but do need to scale (based on river stage)
    c_mover.scale_refpoint = (-70.65, 42.58333, 0.0)
    c_mover.scale_value = 1.

    print 'adding a cats mover:'

    c_mover = CatsMover(testdata['boston_data']['cats_curr3'])
    c_mover.scale = True  # but do need to scale (based on river stage)
    c_mover.scale_refpoint = (-70.78333, 42.39333, 0.0)

    # the scale factor is 0 if user inputs no sewage outfall effects
    c_mover.scale_value = .04
    model.movers += c_mover

    # TODO: seg faulting for component mover - comment test for now
    # print "adding a component mover:"
    # comp_mover = ComponentMover(testdata['boston_data']['component_curr1'],
    #                             testdata['boston_data']['component_curr2'],
    #                             w_mover.wind)
    # TODO: callback did not work correctly below - fix!
    # comp_mover = ComponentMover(component_file1,
    #                             component_file2,
    #                             Wind(timeseries=series, units='m/s'))

    # comp_mover.ref_point = (-70.855, 42.275)
    # comp_mover.pat1_angle = 315
    # comp_mover.pat1_speed = 19.44
    # comp_mover.pat1_speed_units = 1
    # comp_mover.pat1ScaleToValue = .138855
    # comp_mover.pat2_angle = 225
    # comp_mover.pat2_speed = 19.44
    # comp_mover.pat2_speed_units = 1
    # comp_mover.pat2ScaleToValue = .05121

    # model.movers += comp_mover

    print 'adding a Weatherer'
    model.environment += Water(311.15)
    skim_start = start_time + timedelta(hours=3)
    model.weatherers += [
        Evaporation(),
        Skimmer(spill_amount * .5,
                spill_units,
                efficiency=.3,
                active_range=(skim_start, skim_start + timedelta(hours=2))),
        Burn(0.2 * spill_volume,
             1.0, (skim_start, InfDateTime('inf')),
             efficiency=0.9)
    ]

    model.outputters += \
        CurrentJsonOutput(model.find_by_attr('_ref_as', 'current_movers',
                                             model.movers, allitems=True))

    return model
def test_wind_mover():
    '''
        Use a wind_mover, about as simple as it comes
        - We are moving to a design where the environment objects contain the
          extrapolate flag instead of the movers.  This flag is off by default.
    '''

    # fake data arrays:
    num = 2

    pos_dt = np.dtype([('lon', np.float),
                       ('lat', np.float),
                       ('depth', np.float)])

    sc = SC({'positions': np.zeros((num,), dtype=pos_dt),
             'status_codes': np.zeros((num,), dtype=np.int16),
             'windages': np.zeros((num,)),
             })

    wind = wind_from_values([(datetime(2016, 5, 10, 12, 0), 5, 45),
                             (datetime(2016, 5, 10, 12, 20), 6, 50),
                             (datetime(2016, 5, 10, 12, 40), 7, 55),
                             ])
    wm = WindMover(wind)

    # within the model's time span, this should work:
    wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 20))

    # before time span -- this should fail
    with pytest.raises(RuntimeError):
        wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))

    # after time span -- this should fail
    with pytest.raises(RuntimeError):
        wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50))

    # turn on extrapolation in the wind environment object
    wind.extrapolation_is_allowed = True

    # before timespan -- this should pass now
    wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))

    # after timespan -- this should pass now
    wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 12, 50))

    # test the error message that we get when a RuntimeError is raised.
    with pytest.raises(RuntimeError):
        try:
            wind.extrapolation_is_allowed = False
            wm.prepare_for_model_step(sc, 600, datetime(2016, 5, 10, 11, 50))
        except RuntimeError as err:
            msg = err.args[0]
            assert "No available data" in msg
            assert "WindMover" in msg
            assert "2016-05-10 11:50:00" in msg
            assert "2016-05-10 12:00:00" in msg
            assert "2016-05-10 12:40:00" in msg
            raise