Beispiel #1
0
def test_line_release_with_big_timestep():
    """
    a line release: where the timestep spans before to after the release time
    """
    release_time = datetime(2012, 1, 1)
    end_time = release_time + timedelta(seconds=100)
    time_step = timedelta(seconds=300)
    start_pos = np.array((0., 0., 0.))
    end_pos = np.array((1.0, 2.0, 0.))

    sp = PointLineSource(num_elements=10,
                         start_position=start_pos,
                         release_time=release_time,
                         end_position=end_pos,
                         end_release_time=end_time)

    num = sp.num_elements_to_release(release_time - timedelta(seconds=100),
                                     time_step.total_seconds())
    assert num == sp.num_elements

    data_arrays = mock_append_data_arrays(arr_types, num)
    sp.set_newparticle_values(num, release_time - timedelta(seconds=100),
                              time_step.total_seconds(), data_arrays)

    # all axes should release particles with same, evenly spaced delta_position
    for ix in range(3):
        assert np.allclose(data_arrays['positions'][:, ix],
                     np.linspace(start_pos[ix], end_pos[ix], sp.num_elements))
Beispiel #2
0
    def test_noparticles_model_run_after_release_time(self):
        """
        Tests that the spill doesn't release anything if the first call
        to release elements is after the release time.
        This so that if the user sets the model start time after the spill,
        they don't get anything.
        """
        sp = PointLineSource(num_elements=self.num_elements,
                start_position=self.start_position,
                release_time=self.release_time)

        # Test no particles released for following conditions
        #     current_time > spill's release_time
        #     current_time + timedelta > spill's release_time
        for rel_delay in range(1, 3):
            num = sp.num_elements_to_release(self.release_time
                                   + timedelta(hours=rel_delay),
                                   time_step=30 * 60)
            #assert num is None
            assert num == 0

        # rewind and it should work
        sp.rewind()
        data_arrays = self.release_and_assert(sp, self.release_time, 30 * 60,
                                {}, self.num_elements)
        assert np.alltrue(data_arrays['positions'] == self.start_position)
Beispiel #3
0
def test_line_release_with_one_element():
    """
    one element with a line release
    -- doesn't really make sense, but it shouldn't crash
    """
    release_time = datetime(2012, 1, 1)
    end_time = release_time + timedelta(seconds=100)
    time_step = timedelta(seconds=10)
    start_pos = np.array((0., 0., 0.))
    end_pos = np.array((1.0, 2.0, 0.))

    sp = PointLineSource(num_elements=1,
                                   start_position=start_pos,
                                   release_time=release_time,
                                   end_position=end_pos,
                                   end_release_time=end_time)

    num = sp.num_elements_to_release(release_time, time_step.total_seconds())
    data_arrays = mock_append_data_arrays(arr_types, num)

    assert num == 1

    sp.set_newparticle_values(num, release_time, time_step.total_seconds(),
                                      data_arrays)
    assert sp.num_released == 1
    assert np.array_equal(data_arrays['positions'], [start_pos])
Beispiel #4
0
    def test_cont_point_release(self):
        """
        Time varying release so release_time < end_release_time. It releases
        particles over 10 hours. start_position == end_position so it is still
        a point source

        It simulates how particles could be released by a Model with a variable
        timestep
        """
        sp = PointLineSource(num_elements=100,
                start_position=self.start_position,
                release_time=self.release_time,
                end_release_time=self.release_time
                + timedelta(hours=10))
        timestep = 3600  # one hour in seconds

        """
        Release elements incrementally to test continuous release

        4 times and timesteps over which elements are released. The timesteps
        are variable
        """
        # at exactly the release time -- ten get released at start_position
        # one hour into release -- ten more released
        # keep appending to data_arrays in same manner as SpillContainer would
        # 1-1/2 hours into release - 5 more
        # at end -- rest (75 particles) should be released
        data_arrays = {}
        delay_after_rel_time = [timedelta(hours=0),
                                timedelta(hours=1),
                                timedelta(hours=2),
                                timedelta(hours=10)]
        ts = [timestep, timestep, timestep / 2, timestep]
        exp_num_released = [10, 10, 5, 75]

        for ix in range(4):
            data_arrays = self.release_and_assert(sp,
                                self.release_time + delay_after_rel_time[ix],
                                ts[ix], data_arrays, exp_num_released[ix])
            assert np.alltrue(data_arrays['positions'] == self.start_position)

        assert sp.num_released == sp.num_elements

        # rewind and reset data arrays for new release
        sp.rewind()
        data_arrays = {}

        # 360 second time step: should release first LE
        # In 3600 sec, 10 particles are released so one particle every 360sec
        # release one particle each over (360, 720) seconds
        for ix in range(2):
            ts = ix * 360 + 360
            data_arrays = self.release_and_assert(sp, self.release_time, ts,
                                                  data_arrays, 1)
            assert np.alltrue(data_arrays['positions'] == self.start_position)
Beispiel #5
0
    def test_end_release_time(self):
        """
        if end_release_time = None, then automatically set it to release_time
        """
        sp = PointLineSource(num_elements=self.num_elements,
                start_position=self.start_position,
                release_time=self.release_time)

        sp.release_time = self.release_time + timedelta(hours=20)
        assert sp.release_time != sp.end_release_time

        sp.end_release_time = None
        assert sp.release_time == sp.end_release_time
Beispiel #6
0
    def test_end_position(self):
        """
        if end_position = None, then automatically set it to start_position
        """
        sp = PointLineSource(num_elements=self.num_elements,
                start_position=self.start_position,
                release_time=self.release_time)

        sp.start_position = (0, 0, 0)
        assert np.any(sp.start_position != sp.end_position)

        sp.end_position = None
        assert np.all(sp.start_position == sp.end_position)
Beispiel #7
0
    def test_cont_line_release_single_elem_over_multiple_timesteps(self,
                                                start_position, end_position):
        """
        testing a release that is releasing while moving over time
        - less than one elements is released per step. A single element is
          released over multiple time steps.

        Test it's right for the full release
        """
        sp = PointLineSource(num_elements=10,
                start_position=start_position,
                release_time=self.release_time,
                end_position=end_position,
                end_release_time=self.release_time + timedelta(minutes=50))

        # start before release
        time = self.release_time - timedelta(minutes=2)
        delta_t = timedelta(minutes=2)
        timestep = delta_t.total_seconds()
        data_arrays = {}

        # end after release
        while time < sp.end_release_time + delta_t:
            """
            keep releasing particles - no need to use self.release_and_assert
            since computing expected_number_of_particles_released is cumbersome
            Also, other tests verify that expected number of particles are
            being released - keep this easy to understand and follow
            """
            num = sp.num_elements_to_release(time, timestep)
            data_arrays = mock_append_data_arrays(arr_types, num, data_arrays)
            sp.set_newparticle_values(num, time, timestep, data_arrays)
            time += delta_t

        assert data_arrays['positions'].shape == (sp.num_elements, 3)
        assert np.array_equal(data_arrays['positions'][0], sp.start_position)
        assert np.array_equal(data_arrays['positions'][-1], sp.end_position)

        # the delta position is a constant and is given by
        # (sp.end_position-sp.start_position)/(sp.num_elements-1)
        delta_p = (sp.end_position - sp.start_position) / (sp.num_elements - 1)
        assert np.all(delta_p == sp.delta_pos)
        assert np.allclose(delta_p, np.diff(data_arrays['positions'], axis=0),
                           0, 1e-10)
Beispiel #8
0
def test_uncertain_copy():
    """
    only tests a few things...
    """

    spill = PointLineSource(
        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),
        windage_range=(.02, .03),
        windage_persist=-1,
        )

    u_spill = spill.uncertain_copy()

    assert u_spill is not spill
    assert np.array_equal(u_spill.start_position, spill.start_position)
    del spill
    del u_spill
def get_eq_spills():
    """
    returns a tuple of identical PointLineSource objects

    todo: The spill's element_type is forced to be ElementType() since
    it is not being persisted and the default (Floating()) uses randomly
    generated values for initial data array values and these will not match for
    the two spills. Fix this be persisting element_type attribute and making
    min and max windage_range equal so windages are the same.
    """

    num_elements = 10
    release_time = datetime(2000, 1, 1, 1)

    spill = PointLineSource(num_elements,
                            (28, -75, 0),
                            release_time,
                            element_type=elements.ElementType())
    spill2 = PointLineSource.new_from_dict(spill.to_dict('create'))
    spill2.element_type = elements.ElementType()

    return (spill, spill2)
Beispiel #10
0
def test_single_line(num_elements):
    """
    various numbers of elemenets over ten time steps, so release
    is less than one, one and more than one per time step.
    """
    print 'using num_elements:', num_elements
    release_time = datetime(2012, 1, 1)
    end_time = release_time + timedelta(seconds=100)
    time_step = timedelta(seconds=10)
    start_pos = np.array((0., 0., 0.))
    end_pos = np.array((1.0, 2.0, 0.))

    sp = PointLineSource(num_elements=num_elements,
                         start_position=start_pos,
                         release_time=release_time,
                         end_position=end_pos,
                         end_release_time=end_time)

    time = release_time
    data_arrays = {}
    while time <= end_time + time_step * 2:
        #data = sp.release_elements(time, time_step.total_seconds())
        num = sp.num_elements_to_release(time, time_step.total_seconds())
        data_arrays = mock_append_data_arrays(arr_types, num, data_arrays)
        if num > 0:
            sp.set_newparticle_values(num, time, time_step.total_seconds(),
                                      data_arrays)

        time += time_step

    assert len(data_arrays['positions']) == num_elements
    assert np.allclose(data_arrays['positions'][0], start_pos)
    assert np.allclose(data_arrays['positions'][-1], end_pos)

    # all axes should release particles with same, evenly spaced delta_position
    for ix in range(3):
        assert np.allclose(data_arrays['positions'][:, ix],
                     np.linspace(start_pos[ix], end_pos[ix], num_elements))
Beispiel #11
0
    def test_noparticles_model_run_before_release_time(self):
        """
        Tests that the spill doesn't release anything if the first call
        to num_elements_to_release is before the release_time + timestep.
        """

        sp = PointLineSource(num_elements=self.num_elements,
                start_position=self.start_position,
                release_time=self.release_time)
        print 'release_time:', self.release_time
        timestep = 360  # seconds

        # right before the release
        num = sp.num_elements_to_release(self.release_time -
                                         timedelta(seconds=360), timestep)
        #assert num is None
        assert num == 0

        # right after the release
        data_arrays = self.release_and_assert(sp, self.release_time -
                                timedelta(seconds=1),
                                timestep, {}, self.num_elements)
        assert np.alltrue(data_arrays['positions'] == self.start_position)
Beispiel #12
0
    def test_inst_point_release(self):
        """
        Test all particles for an instantaneous point release are released
        correctly.
        - also tests that once all particles have been released, no new
          particles are released in subsequent steps
        """
        sp = PointLineSource(num_elements=self.num_elements,
                start_position=self.start_position,
                release_time=self.release_time)
        timestep = 3600  # seconds

        # release all particles
        data_arrays = self.release_and_assert(sp, self.release_time,
                                timestep, {}, self.num_elements)
        assert np.alltrue(data_arrays['positions'] == self.start_position)

        # no more particles to release since all particles have been released
        num = sp.num_elements_to_release(self.release_time + timedelta(10),
                timestep)
        #assert num is None
        assert num == 0

        # reset and try again
        sp.rewind()
        assert sp.num_released == 0
        num = sp.num_elements_to_release(self.release_time - timedelta(10),
                                         timestep)
        #assert num is None
        assert num == 0
        assert sp.num_released == 0

        # release all particles
        data_arrays = self.release_and_assert(sp, self.release_time,
                                timestep, {}, self.num_elements)
        assert np.alltrue(data_arrays['positions'] == self.start_position)
def test_eq_spill_container_pair(uncertain):
    """
    SpillContainerPair inherits from SpillContainer so it should
    compute __eq__ and __ne__ in the same way - test it here

    Incomplete - this doesn't currently work!
    Test fails if uncertainty is on whether particles are released or not
    This is because 'id' of uncertain spills do not match and one should not
    expect them to match.

    todo: remove 'id' property as a check for equality. This requires changes
          in persisting logic. Update persistence then revisit this test
          and simplify it
    """
    (sp1, sp2) = get_eq_spills()

    # windages array will not match after elements are released so lets not
    # add any more types to data_arrays for this test. Just look at base
    # array_types for SpillContainer's and ensure the data matches for them
    sp1.element_type = elements.ElementType()
    sp2.element_type = elements.ElementType()

    scp1 = SpillContainerPair(uncertain)  # uncertainty is on
    scp1.add(sp1)

    scp2 = SpillContainerPair(uncertain)
    if uncertain:
        u_sp1 = [scp1.items()[1].spills[spill.id] for spill in
                 scp1.items()[1].spills][0]

        u_sp2 = PointLineSource.new_from_dict(u_sp1.to_dict('create'))

        scp2.add((sp2, u_sp2))
    else:
        scp2.add(sp2)

    for sc in zip(scp1.items(), scp2.items()):
        sc[0].prepare_for_model_run()
        sc[0].release_elements(360, sp1.release_time)
        sc[1].prepare_for_model_run()
        sc[1].release_elements(360, sp2.release_time)

    assert scp1 == scp2