Source code for harmonica.synthetic.surveys

# Copyright (c) 2018 The Harmonica Developers.
# Distributed under the terms of the BSD 3-Clause License.
# SPDX-License-Identifier: BSD-3-Clause
#
# This code is part of the Fatiando a Terra project (https://www.fatiando.org)
#
"""
Create synthetic surveys for gravity and magnetic observations
"""
from verde import get_region, inside
from verde.coordinates import check_region

from ..datasets import fetch_britain_magnetic, fetch_south_africa_gravity


[docs]def airborne_survey(region=None, data_region=(-5.0, -4.0, 56.0, 56.5)): """ Create measurement locations for a synthetic airborne survey The observation points are sampled from the Great Britain total-field magnetic anomaly dataset (see :func:`~harmonica.datasets.fetch_britain_magnetic`). A portion of the original survey is cut (*data_region*) and the coordinates may be scaled to the given *region*. Parameters ---------- region : tuple or list (optional) Survey horizontal coordinates will be scaled to span this area. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. Only the 4 horizontal boundaries are used. Subsequent boundaries will be ignored. If ``None``, the survey points won't be scaled. Default ``None``. data_region : tuple or list (optional) Subsection of the original Great Britain magnetic dataset that will be sampled. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. All subsequent boundaries will be ignored. Returns ------- survey : :class:`pandas.DataFrame` Dataframe containing the coordinates of the observation points on a geodetic coordinate system. The :class:`pandas.DataFrame` will have the following columns: ``longitude``, ``latitude``, ``height``. Longitudes and latitudes are in degrees, and heights in meters. See also -------- harmonica.datasets.fetch_britain_magnetic """ # Sanity checks for region and data_region if region is not None: check_region(region[:4]) check_region(data_region) # Fetch airborne magnetic survey from Great Britain survey = fetch_britain_magnetic() # Rename the "elevation" column to "height" and # keep only the longitude, latitude and height survey = survey.rename(columns={"altitude_m": "height"}).filter( ["longitude", "latitude", "height"] ) # Cut the survey into the data_region and scale it to the passed region survey = _cut_and_scale(survey, region, data_region) return survey
[docs]def ground_survey(region=None, data_region=(13.60, 20.30, -24.20, -17.5)): """ Create measurement locations for a synthetic ground survey The observation points are sampled from the South Africa gravity dataset (see :func:`~harmonica.datasets.fetch_south_africa_gravity`). Only a portion of the original survey is sampled and its region may be scaled to the passed ``region``. Parameters ---------- region : tuple or list (optional) Region at which the survey points coordinates will be scaled. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. All subsequent boundaries will be ignored. If ``None``, the survey points won't be scaled. Default ``None``. data_region : tuple or list (optional) Region where the original Great Britain magnetic dataset will be sampled. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. All subsequent boundaries will be ignored. Returns ------- survey : :class:`pandas.DataFrame` Dataframe containing the coordinates of the observation points on a geodetic coordinate system. The :class:`pandas.DataFrame` will have the following columns: ``longitude``, ``latitude``, ``height``. Longitudes and latitudes are in degrees, and heights in meters. See also -------- harmonica.datasets.fetch_south_africa_gravity """ # Sanity checks for region and data_region if region is not None: check_region(region[:4]) check_region(data_region) # Fetch ground gravity survey from South Africa survey = fetch_south_africa_gravity() # Rename the "elevation" column to "height" and # keep only the longitude, latitude and height survey = survey.rename(columns={"elevation": "height"}).filter( ["longitude", "latitude", "height"] ) # Cut the survey into the data_region and scale it to the passed region survey = _cut_and_scale(survey, region, data_region) return survey
def _cut_and_scale(survey, region, data_region): """ Cut a subsection from the original survey and scale it to the given region Parameters ---------- survey : :class:`pandas.DataFrame` Original survey as a :class:`pandas.DataFrame` containing the following columns: ``longitude``, ``latitude`` and ``height``. region : tuple or list (optional) Region to which the survey points coordinates will be scaled. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. All subsequent boundaries will be ignored. If ``None``, the survey points won't be scaled. data_region : tuple or list (optional) Region where the original Great Britain magnetic dataset will be sampled. The boundaries must be passed in the following order: (``east``, ``west``, ``south``, ``north``, ...), defined on a geodetic coordinate system and in degrees. All subsequent boundaries will be ignored. Returns ------- survey : :class:`pandas.DataFrame` Dataframe containing the coordinates of the observation points on a geodetic coordinate system. Longitudes and latitudes are in degrees, and heights in meters. """ # Cut the data into the data_region inside_points = inside((survey.longitude, survey.latitude), data_region) survey = survey[inside_points].copy() # Scale survey coordinates to the passed region if region is not None: w, e, s, n = region[:4] longitude_min, longitude_max, latitude_min, latitude_max = get_region( (survey.longitude, survey.latitude) ) survey["longitude"] = (e - w) / (longitude_max - longitude_min) * ( survey.longitude - longitude_min ) + w survey["latitude"] = (n - s) / (latitude_max - latitude_min) * ( survey.latitude - latitude_min ) + s return survey