Exemplo n.º 1
0
def test_eql_harmonic_small_data_cartesian():
    """
    Check predictions against synthetic data using few data points for speed
    Use Cartesian coordinates.
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region, shape=(6, 6), extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13, region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region, shape=(20, 20), extra_coords=0)
    # Get synthetic data
    data = point_mass_gravity(coordinates, points, masses, field="g_z")

    # The interpolation should be perfect on the data points
    eql = EQLHarmonic(relative_depth=500)
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Check that the proper source locations were set
    tmp = [i.ravel() for i in coordinates]
    npt.assert_allclose(tmp[:2], eql.points_[:2], rtol=1e-5)
    npt.assert_allclose(tmp[2] - 500, eql.points_[2], rtol=1e-5)

    # Gridding at higher altitude should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region=region, shape=(20, 20), extra_coords=20)
    true = point_mass_gravity(grid, points, masses, field="g_z")
    npt.assert_allclose(true, eql.predict(grid), rtol=0.05)
Exemplo n.º 2
0
def test_eql_harmonic_cartesian_parallel():
    """
    Check predictions when parallel is enabled and disabled
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(40, 40),
                                      extra_coords=0)
    # Get synthetic data
    data = point_mass_gravity(coordinates, points, masses, field="g_z")

    # The predictions should be equal whether are run in parallel or in serial
    eql_serial = EQLHarmonic(parallel=False)
    eql_serial.fit(coordinates, data)
    eql_parallel = EQLHarmonic(parallel=True)
    eql_parallel.fit(coordinates, data)

    upward = 0
    shape = (60, 60)
    grid_serial = eql_serial.grid(upward, shape=shape, region=region)
    grid_parallel = eql_parallel.grid(upward, shape=shape, region=region)
    npt.assert_allclose(grid_serial.scalars, grid_parallel.scalars, rtol=1e-7)
Exemplo n.º 3
0
def test_eql_harmonic_custom_points_cartesian():
    """
    Check that passing in custom points works and actually uses the points
    Use Cartesian coordinates.
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region, shape=(6, 6), extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13, region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region, shape=(20, 20), extra_coords=0)
    # Get synthetic data
    data = point_mass_gravity(coordinates, points, masses, field="g_z")

    # The interpolation should be perfect on the data points
    src_points = tuple(
        i.ravel()
        for i in vd.grid_coordinates(region=region, shape=(20, 20), extra_coords=-550)
    )
    eql = EQLHarmonic(points=src_points)
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Check that the proper source locations were set
    npt.assert_allclose(src_points, eql.points_, rtol=1e-5)

    # Gridding at higher altitude should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region=region, shape=(20, 20), extra_coords=20)
    true = point_mass_gravity(grid, points, masses, field="g_z")
    npt.assert_allclose(true, eql.predict(grid), rtol=0.05)
def test_same_windows_data_and_sources():
    """
    Check if it creates the same windows for data and sources
    """
    spacing = 1
    # Create data points on a large region
    region = (1, 3, 1, 3)
    coordinates = vd.grid_coordinates(region=region,
                                      spacing=spacing,
                                      extra_coords=0)
    # Create source points on a subregion
    sources_region = (1, 2, 1, 3)
    points = vd.grid_coordinates(region=sources_region,
                                 spacing=spacing,
                                 extra_coords=-10)
    # Create EQLHarmonicBoost
    # I use no shuffle so I can compare the windows with expected values
    eql = EQLHarmonicBoost(window_size=spacing, shuffle=False)
    # Make EQL believe that it has already created the points
    eql.points_ = points
    # Create windows for data points and sources
    source_windows, data_windows = eql._create_rolling_windows(coordinates)
    # Check number of windows
    assert len(source_windows) == 9
    assert len(data_windows) == 9
    # Define expected number of points inside each window for data and sources
    expected_data_windows = np.array([[4, 2, 4], [2, 1, 2], [4, 2, 4]]).ravel()
    expected_source_windows = np.array([[4, 2, 2], [2, 1, 1], [4, 2,
                                                               2]]).ravel()
    # Check if the windows were created correctly
    for i, window in enumerate(data_windows):
        assert len(window) == expected_data_windows[i]
    for i, window in enumerate(source_windows):
        assert len(window) == expected_source_windows[i]
def test_eql_boost_large_region():
    """
    Check if EQLHarmonicBoost works on a large region

    The iterative process ignores the effect of sources on far observation
    points. If the region is very large, this error should be diminished.
    """
    # Define a squared region
    region = (-1000e3, 1000e3, -1000e3, 1000e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(40, 40),
                                      extra_coords=0)
    # Get synthetic data
    data = hm.point_mass_gravity(coordinates, points, masses, field="g_z")

    # The interpolation should be sufficiently accurate on the data points
    eql = EQLHarmonicBoost(window_size=100e3)
    eql.fit(coordinates, data)
    assert mean_squared_error(
        data, eql.predict(coordinates)) < 1e-5 * vd.maxabs(data)

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region=region, shape=(60, 60), extra_coords=0)
    true = hm.point_mass_gravity(grid, points, masses, field="g_z")
    assert mean_squared_error(true, eql.predict(grid)) < 1e-3 * vd.maxabs(data)
def test_eql_boost_random_state():
    """
    Check if EQLHarmonicBoost produces same result by setting random_state
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(20, 20),
                                      extra_coords=0)
    # Get synthetic data
    data = hm.point_mass_gravity(coordinates, points, masses, field="g_z")

    # Initialize two EQLHarmonicBoost with the same random_state
    eql_a = EQLHarmonicBoost(window_size=500, random_state=0)
    eql_a.fit(coordinates, data)
    eql_b = EQLHarmonicBoost(window_size=500, random_state=0)
    eql_b.fit(coordinates, data)

    # Check if fitted coefficients are the same
    npt.assert_allclose(eql_a.coefs_, eql_b.coefs_)
Exemplo n.º 7
0
def test_eql_harmonic_spherical():
    """
    Check that predictions are reasonable when interpolating from one grid to
    a denser grid. Use spherical coordiantes.
    """
    region = (-70, -60, -40, -30)
    radius = 6400e3
    # Build synthetic point masses
    points = vd.grid_coordinates(
        region=region, shape=(6, 6), extra_coords=radius - 500e3
    )
    masses = vd.datasets.CheckerBoard(amplitude=1e13, region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(
        region=region, shape=(40, 40), extra_coords=radius
    )
    # Get synthetic data
    data = point_mass_gravity(
        coordinates, points, masses, field="g_z", coordinate_system="spherical"
    )

    # The interpolation should be perfect on the data points
    eql = EQLHarmonicSpherical(relative_depth=500e3)
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region=region, shape=(60, 60), extra_coords=radius)
    true = point_mass_gravity(
        grid, points, masses, field="g_z", coordinate_system="spherical"
    )
    npt.assert_allclose(true, eql.predict(grid), rtol=1e-3)
def test_eql_boost_warm_start():
    """
    Check if EQLHarmonicBoost can be fitted with warm_start
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(20, 20),
                                      extra_coords=0)
    # Get synthetic data
    data = hm.point_mass_gravity(coordinates, points, masses, field="g_z")

    # Check if refitting with warm_start=True changes its coefficients
    eql = EQLHarmonicBoost(window_size=500, warm_start=True)
    eql.fit(coordinates, data)
    coefs = eql.coefs_.copy()
    eql.fit(coordinates, data)
    assert not np.allclose(coefs, eql.coefs_)

    # Check if refitting with warm_start=False doesn't change its coefficients
    # (need to set random_state, otherwise coefficients might be different due
    # to another random shuffling of the windows).
    eql = EQLHarmonicBoost(window_size=500, warm_start=False, random_state=0)
    eql.fit(coordinates, data)
    coefs = eql.coefs_.copy()
    eql.fit(coordinates, data)
    npt.assert_allclose(coefs, eql.coefs_)
def test_eql_boost_single_window():
    """
    Check if EQLHarmonicBoost works with a single window that covers the whole region
    """
    # Define a squared region
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(40, 40),
                                      extra_coords=0)
    # Get synthetic data
    data = hm.point_mass_gravity(coordinates, points, masses, field="g_z")

    # The interpolation should be perfect on the data points
    eql = EQLHarmonicBoost(window_size=region[1] - region[0])
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region=region, shape=(60, 60), extra_coords=0)
    true = hm.point_mass_gravity(grid, points, masses, field="g_z")
    npt.assert_allclose(true, eql.predict(grid), rtol=1e-3)
Exemplo n.º 10
0
def test_same_windows_data_and_sources():
    """
    Test if _create_windows generates the same windows for data and sources
    """
    spacing = 1
    # Create data points on a large region
    region = (1, 3, 1, 3)
    coordinates = vd.grid_coordinates(region=region,
                                      spacing=spacing,
                                      extra_coords=0)
    # Create source points on a subregion
    sources_region = (1, 2, 1, 3)
    points = vd.grid_coordinates(region=sources_region,
                                 spacing=spacing,
                                 extra_coords=-10)
    # Create EquivalentSourcesGB
    eqs = EquivalentSourcesGB(window_size=spacing)
    # Make EQL believe that it has already created the points
    eqs.points_ = points
    # Create windows for data points and sources
    # Set suffhle to False so we can compare the windows with expected values
    source_windows, data_windows = eqs._create_windows(coordinates,
                                                       shuffle=False)
    # Check number of windows
    assert len(source_windows) == 9
    assert len(data_windows) == 9
    # Define expected number of points inside each window for data and sources
    expected_data_windows = np.array([[4, 2, 4], [2, 1, 2], [4, 2, 4]]).ravel()
    expected_source_windows = np.array([[4, 2, 2], [2, 1, 1], [4, 2,
                                                               2]]).ravel()
    # Check if the windows were created correctly
    for i, window in enumerate(data_windows):
        assert len(window) == expected_data_windows[i]
    for i, window in enumerate(source_windows):
        assert len(window) == expected_source_windows[i]
Exemplo n.º 11
0
def test_eql_harmonic_custom_points_spherical():
    """
    Check that passing in custom points works and actually uses the points
    Use spherical coordinates.
    """
    region = (-70, -60, -40, -30)
    radius = 6400e3
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=radius - 500e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(5, 5),
                                      extra_coords=radius)
    # Get synthetic data
    data = point_mass_gravity(coordinates,
                              points,
                              masses,
                              field="g_z",
                              coordinate_system="spherical")

    # Pass a custom set of point sources
    points_custom = tuple(i.ravel() for i in vd.grid_coordinates(
        region=region, shape=(3, 3), extra_coords=radius - 500e3))
    eql = EQLHarmonicSpherical(points=points_custom)
    eql.fit(coordinates, data)

    # Check that the proper source locations were set
    npt.assert_allclose(points_custom, eql.points_, rtol=1e-5)
Exemplo n.º 12
0
def test_eql_harmonic_custom_points_cartesian():
    """
    Check that passing in custom points works and actually uses the points
    Use Cartesian coordinates.
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(5, 5),
                                      extra_coords=0)
    # Get synthetic data
    data = point_mass_gravity(coordinates, points, masses, field="g_z")

    # Pass a custom set of point sources
    points_custom = tuple(i.ravel() for i in vd.grid_coordinates(
        region=region, shape=(3, 3), extra_coords=-550))
    eql = EQLHarmonic(points=points_custom)
    eql.fit(coordinates, data)

    # Check that the proper source locations were set
    npt.assert_allclose(points_custom, eql.points_, rtol=1e-5)
Exemplo n.º 13
0
def test_get_region_data_sources(data_region, sources_region, expected_region):
    """
    Test the EquivalentSourcesGB._get_region_data_sources method
    """
    shape = (8, 10)
    coordinates = vd.grid_coordinates(data_region, shape=shape)
    points = vd.grid_coordinates(sources_region, shape=shape)
    region = _get_region_data_sources(coordinates, points)
    npt.assert_allclose(region, expected_region)
Exemplo n.º 14
0
def test_eql_harmonic_small_data_spherical():
    """
    Check predictions against synthetic data using few data points for speed
    Use spherical coordinates.
    """
    region = (-70, -60, -40, -30)
    radius = 6400e3
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=radius - 500e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(8, 8),
                                      extra_coords=radius)
    # Get synthetic data
    data = point_mass_gravity(coordinates,
                              points,
                              masses,
                              field="g_z",
                              coordinate_system="spherical")

    # The interpolation should be perfect on the data points
    eql = EQLHarmonicSpherical(relative_depth=500e3)
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Check that the proper source locations were set
    tmp = [i.ravel() for i in coordinates]
    npt.assert_allclose(tmp[:2], eql.points_[:2], rtol=1e-5)
    npt.assert_allclose(tmp[2] - 500e3, eql.points_[2], rtol=1e-5)

    # Gridding at higher altitude should be reasonably accurate when compared
    # to synthetic values
    upward = radius + 2e3
    shape = (8, 8)
    grid = vd.grid_coordinates(region=region, shape=shape, extra_coords=upward)
    true = point_mass_gravity(grid,
                              points,
                              masses,
                              field="g_z",
                              coordinate_system="spherical")
    npt.assert_allclose(true, eql.predict(grid), rtol=0.05)

    # Test grid method
    grid = eql.grid(upward, shape=shape, region=region)
    npt.assert_allclose(true, grid.scalars, rtol=0.05)
Exemplo n.º 15
0
def test_prism_layer_gravity():
    """
    Check if gravity method works as expected
    """
    coordinates = vd.grid_coordinates((1, 3, 7, 10),
                                      spacing=1,
                                      extra_coords=30.0)
    easting = np.linspace(1, 3, 5)
    northing = np.linspace(7, 10, 4)
    shape = (northing.size, easting.size)
    reference = 0
    surface = np.arange(20, dtype=float).reshape(shape)
    density = np.ones_like(surface, dtype=float)
    layer = prism_layer((easting, northing),
                        surface,
                        reference,
                        properties={"density": density})
    for field in ("potential", "g_z"):
        expected_result = prism_gravity(
            coordinates,
            prisms=layer.prism_layer._to_prisms(),
            density=density,
            field=field,
        )
        npt.assert_allclose(
            expected_result, layer.prism_layer.gravity(coordinates,
                                                       field=field))
Exemplo n.º 16
0
def test_point_mass_spherical_parallel():
    """
    Check if parallel and serial runs return the same result
    """
    region = (2, 10, -3, 5)
    radius = 6400e3
    points = vd.scatter_points(region,
                               size=30,
                               extra_coords=radius - 10e3,
                               random_state=0)
    masses = np.arange(points[0].size)
    coordinates = vd.grid_coordinates(region=region,
                                      spacing=1,
                                      extra_coords=radius)
    for field in ("potential", "g_z"):
        result_serial = point_gravity(
            coordinates,
            points,
            masses,
            field=field,
            coordinate_system="spherical",
            parallel=False,
        )
        result_parallel = point_gravity(
            coordinates,
            points,
            masses,
            field=field,
            coordinate_system="spherical",
            parallel=True,
        )
        npt.assert_allclose(result_serial, result_parallel)
Exemplo n.º 17
0
def test_single_tesseroid_against_constant_density(field):
    """
    Test the output of a single tesseroid against one with constant density
    """
    # Define a single tesseroid with constant density
    bottom, top = 5400e3, 6300e3
    tesseroid = [-3, 3, -2, 2, bottom, top]
    density = 2900.0

    # Define a constant density
    @jit
    def constant_density(
            radius,  # noqa: U100 # the radius argument is needed for the density function
    ):
        return density

    # Define a set of observation points
    coordinates = grid_coordinates(region=(-5, 5, -5, 5),
                                   spacing=1,
                                   extra_coords=top)

    # Compare effects against the constant density implementation
    npt.assert_allclose(
        tesseroid_gravity(coordinates, [tesseroid],
                          density=[density],
                          field=field),
        tesseroid_gravity(coordinates, [tesseroid],
                          density=constant_density,
                          field=field),
    )
Exemplo n.º 18
0
def test_prisms_parallel_vs_serial():
    """
    Check if the parallelized run returns the same results as the serial one
    """
    prisms = [
        [-100, 0, -100, 0, -10, 0],
        [0, 100, -100, 0, -10, 0],
        [-100, 0, 0, 100, -10, 0],
        [0, 100, 0, 100, -10, 0],
    ]
    densities = [2000, 3000, 4000, 5000]
    coordinates = vd.grid_coordinates(region=(-100, 100, -100, 100),
                                      spacing=20,
                                      extra_coords=10)
    for field in ("potential", "g_z"):
        result_parallel = prism_gravity(coordinates,
                                        prisms,
                                        densities,
                                        field=field,
                                        parallel=True)
        result_serial = prism_gravity(coordinates,
                                      prisms,
                                      densities,
                                      field=field,
                                      parallel=False)
        npt.assert_allclose(result_parallel, result_serial)
Exemplo n.º 19
0
def test_point_mass_cartesian_parallel():
    """
    Check if parallel and serial runs return the same result
    """
    region = (2e3, 10e3, -3e3, 5e3)
    points = vd.scatter_points(region,
                               size=30,
                               extra_coords=-1e3,
                               random_state=0)
    masses = np.arange(points[0].size)
    coordinates = vd.grid_coordinates(region=region,
                                      spacing=1e3,
                                      extra_coords=0)
    for field in ("potential", "g_z", "g_northing", "g_easting"):
        result_serial = point_gravity(coordinates,
                                      points,
                                      masses,
                                      field=field,
                                      parallel=False)
        result_parallel = point_gravity(coordinates,
                                        points,
                                        masses,
                                        field=field,
                                        parallel=True)
        npt.assert_allclose(result_serial, result_parallel)
Exemplo n.º 20
0
def grid_sources(coordinates, spacing=None, depth=None, **kwargs):
    """
    Create a regular grid of point sources

    All point sources will be located at the same depth, equal to the difference between
    the minimum elevation of observation points and the ``depth`` argument.

    Parameters
    ----------
    coordinates : tuple of arrays
        Tuple containing the coordinates of the observation points in the following
        order: (``easting``, ``northing``, ``upward``).
    spacing : float, tuple = (s_north, s_east)
        The block size in the South-North and West-East directions, respectively.
        A single value means that the size is equal in both directions.
    depth : float
        Depth shift used to compute the constant depth at which point sources will be
        located.

    Returns
    -------
    points : tuple of arrays
        Tuple containing the coordinates of the source points in the following order:
        (``easting``, ``northing``, ``upward``).
    """
    # Generate grid sources
    region = get_region(coordinates)
    easting, northing = grid_coordinates(region=region, spacing=spacing)
    upward = np.full_like(easting, coordinates[2].min()) - depth
    return easting, northing, upward
Exemplo n.º 21
0
def test_gradient_boosted_eqs_predictions(region, points, masses, coordinates,
                                          data):
    """
    Test GB eq-sources predictions
    """
    # The interpolation should be sufficiently accurate on the data points
    eqs = EquivalentSourcesGB(window_size=1e3,
                              depth=1e3,
                              damping=None,
                              random_state=42)
    eqs.fit(coordinates, data)
    # Error tolerance is 2% of the maximum data.
    npt.assert_allclose(data,
                        eqs.predict(coordinates),
                        rtol=0,
                        atol=0.02 * vd.maxabs(data))

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    grid = vd.grid_coordinates(region, shape=(60, 60), extra_coords=0)
    true = point_gravity(grid, points, masses, field="g_z")
    # Error tolerance is 2% of the maximum data.
    npt.assert_allclose(true,
                        eqs.predict(grid),
                        rtol=0,
                        atol=0.02 * vd.maxabs(true))
Exemplo n.º 22
0
def test_prism_layer_gravity_density_nans(field, dummy_layer,
                                          prism_layer_with_holes):
    """
    Check if prisms is ignored after a nan is found in density array
    """
    coordinates = vd.grid_coordinates((1, 3, 7, 10),
                                      spacing=1,
                                      extra_coords=30.0)
    prisms_coords, surface, reference, density = dummy_layer
    # Create one layer that has nans on the density array
    indices = [(3, 3), (2, 1)]
    for index in indices:
        density[index] = np.nan
    layer = prism_layer(prisms_coords,
                        surface,
                        reference,
                        properties={"density": density})
    # Check if warning is raised after passing density with nans
    with warnings.catch_warnings(record=True) as warn:
        result = layer.prism_layer.gravity(coordinates, field=field)
        assert len(warn) == 1
    # Check if it generates the expected gravity field
    prisms, rho = prism_layer_with_holes
    npt.assert_allclose(
        result,
        prism_gravity(coordinates, prisms, rho, field=field),
    )
Exemplo n.º 23
0
def test_dtype(
    region,
    coordinates,
    data,
    weights,
    block_size,
    custom_points,
    weights_none,
    damping,
    dtype,
):
    """
    Test dtype argument on EquivalentSources
    """
    # Define the points argument for EquivalentSources
    points = None
    if custom_points:
        points = vd.grid_coordinates(region, spacing=300, extra_coords=-2e3)
    # Define the points argument for EquivalentSources.fit()
    if weights_none:
        weights = None
    # Initialize and fit the equivalent sources
    eqs = EquivalentSources(
        damping=damping, points=points, block_size=block_size, dtype=dtype
    )
    eqs.fit(coordinates, data, weights)
    # Make some predictions
    prediction = eqs.predict(coordinates)
    # Check data type of created objects
    for coord in eqs.points_:
        assert coord.dtype == np.dtype(dtype)
    assert prediction.dtype == np.dtype(dtype)
Exemplo n.º 24
0
def test_equivalent_sources_jacobian_cartesian():
    """
    Test Jacobian matrix under symmetric system of point sources.
    Use Cartesian coordinates.
    """
    easting, northing, upward = vd.grid_coordinates(
        region=[-100, 100, -100, 100], shape=(2, 2), extra_coords=0
    )
    points = vdb.n_1d_arrays((easting, northing, upward + 100), n=3)
    coordinates = vdb.n_1d_arrays((easting, northing, upward), n=3)
    n_points = points[0].size
    jacobian = np.zeros((n_points, n_points), dtype=points[0].dtype)
    jacobian_numba_serial(coordinates, points, jacobian, greens_func_cartesian)
    # All diagonal elements must be equal
    diagonal = np.diag_indices(4)
    npt.assert_allclose(jacobian[diagonal][0], jacobian[diagonal])
    # All anti-diagonal elements must be equal (elements between distant
    # points)
    anti_diagonal = (diagonal[0], diagonal[1][::-1])
    npt.assert_allclose(jacobian[anti_diagonal][0], jacobian[anti_diagonal])
    # All elements corresponding to nearest neighbors must be equal
    nearest_neighbours = np.ones((4, 4), dtype=bool)
    nearest_neighbours[diagonal] = False
    nearest_neighbours[anti_diagonal] = False
    npt.assert_allclose(jacobian[nearest_neighbours][0], jacobian[nearest_neighbours])
Exemplo n.º 25
0
def test_equivalent_sources_points_depth(points, coordinates_small, data_small):
    """
    Check if the points coordinates are properly defined by the fit method
    """
    easting, northing, upward = coordinates_small[:]
    # Test with constant depth
    eqs = EquivalentSources(depth=1.3e3, depth_type="constant")
    eqs.fit(coordinates_small, data_small)
    expected_points = vdb.n_1d_arrays(
        (easting, northing, -1.3e3 * np.ones_like(easting)), n=3
    )
    npt.assert_allclose(expected_points, eqs.points_)

    # Test with relative depth
    eqs = EquivalentSources(depth=1.3e3, depth_type="relative")
    eqs.fit(coordinates_small, data_small)
    expected_points = vdb.n_1d_arrays((easting, northing, upward - 1.3e3), n=3)
    npt.assert_allclose(expected_points, eqs.points_)

    # Test with invalid depth_type
    eqs = EquivalentSources(
        depth=300, depth_type="constant"
    )  # init with valid depth_type
    eqs.depth_type = "blabla"  # change depth_type afterwards
    points = eqs._build_points(
        vd.grid_coordinates(region=(-1, 1, -1, 1), spacing=0.25, extra_coords=1)
    )
    assert points is None
Exemplo n.º 26
0
def test_equivalent_sources_cartesian_float32(
    region, points, masses, coordinates, data
):
    """
    Check that predictions are reasonable when interpolating from one grid to
    a denser grid, using float32 as dtype.
    """
    # The interpolation should be perfect on the data points
    eqs = EquivalentSources(dtype="float32")
    eqs.fit(coordinates, data)
    npt.assert_allclose(data, eqs.predict(coordinates), atol=1e-3 * vd.maxabs(data))

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    upward = 0
    shape = (60, 60)
    grid = vd.grid_coordinates(region=region, shape=shape, extra_coords=upward)
    true = point_gravity(grid, points, masses, field="g_z")
    npt.assert_allclose(true, eqs.predict(grid), atol=1e-3 * vd.maxabs(true))

    # Test grid method
    grid = eqs.grid(upward, shape=shape, region=region)
    npt.assert_allclose(true, grid.scalars, atol=1e-3 * vd.maxabs(true))

    # Test profile method
    point1 = (region[0], region[2])
    point2 = (region[0], region[3])
    profile = eqs.profile(point1, point2, upward, shape[0])
    true = point_gravity(
        (profile.easting, profile.northing, profile.upward), points, masses, field="g_z"
    )
    npt.assert_allclose(true, profile.scalars, atol=1e-3 * vd.maxabs(true))
Exemplo n.º 27
0
def test_eql_harmonic_cartesian():
    """
    Check that predictions are reasonable when interpolating from one grid to
    a denser grid. Use Cartesian coordinates.
    """
    region = (-3e3, -1e3, 5e3, 7e3)
    # Build synthetic point masses
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    masses = vd.datasets.CheckerBoard(amplitude=1e13,
                                      region=region).predict(points)
    # Define a set of observation points
    coordinates = vd.grid_coordinates(region=region,
                                      shape=(40, 40),
                                      extra_coords=0)
    # Get synthetic data
    data = point_mass_gravity(coordinates, points, masses, field="g_z")

    # The interpolation should be perfect on the data points
    eql = EQLHarmonic()
    eql.fit(coordinates, data)
    npt.assert_allclose(data, eql.predict(coordinates), rtol=1e-5)

    # Gridding onto a denser grid should be reasonably accurate when compared
    # to synthetic values
    upward = 0
    shape = (60, 60)
    grid = vd.grid_coordinates(region=region, shape=shape, extra_coords=upward)
    true = point_mass_gravity(grid, points, masses, field="g_z")
    npt.assert_allclose(true, eql.predict(grid), rtol=1e-3)

    # Test grid method
    grid = eql.grid(upward, shape=shape, region=region)
    npt.assert_allclose(true, grid.scalars, rtol=1e-3)

    # Test profile method
    point1 = (region[0], region[2])
    point2 = (region[0], region[3])
    profile = eql.profile(point1, point2, upward, shape[0])
    true = point_mass_gravity(
        (profile.easting, profile.northing, profile.upward),
        points,
        masses,
        field="g_z")
    npt.assert_allclose(true, profile.scalars, rtol=1e-3)
Exemplo n.º 28
0
def fixture_points(region):
    """
    Return the coordinates of some sample point masses
    """
    points = vd.grid_coordinates(region=region,
                                 shape=(6, 6),
                                 extra_coords=-1e3)
    return points
Exemplo n.º 29
0
def fixture_coordinates_9x9(region):
    """
    Return a small set of 81 coordinates and variable elevation
    """
    shape = (9, 9)
    easting, northing = vd.grid_coordinates(region, shape=shape)
    upward = np.arange(shape[0] * shape[1], dtype=float).reshape(shape)
    coordinates = (easting, northing, upward)
    return coordinates
Exemplo n.º 30
0
def fixture_coordinates_small(region):
    """
    Return a small set of 25 coordinates and variable elevation
    """
    shape = (5, 5)
    easting, northing = vd.grid_coordinates(region=region, shape=shape)
    upward = np.arange(25, dtype=float).reshape(shape)
    coordinates = (easting, northing, upward)
    return coordinates