Loading...
Loading...
Gravity and magnetic data processing and forward modelling using Fatiando a Terra. Use when Claude needs to: (1) Compute gravity forward models (point masses, prisms, tesseroids), (2) Apply terrain/Bouguer corrections, (3) Grid scattered potential field data with equivalent sources, (4) Perform upward/downward continuation, (5) Calculate magnetic anomalies from magnetized bodies, (6) Apply derivative filters (gradients, tilt angle), (7) Process regional or local gravity surveys.
npx skill4agent add steadfastasart/geoscience-skills harmonicaimport harmonica as hm
import numpy as np
# Forward model - prism gravity
prism = [-500, 500, -500, 500, -2000, -500] # (west, east, south, north, bottom, top)
gravity = hm.prism_gravity(coordinates, prism, density=500, field='g_z')
# Terrain correction
layer = hm.prism_layer((easting, northing), surface=topo, reference=0,
properties={'density': 2670})
terrain_effect = layer.gravity(coordinates, field='g_z')
# Equivalent source gridding
eqs = hm.EquivalentSources(depth=10000, damping=10)
eqs.fit(coordinates, gravity_data)
grid = eqs.grid(spacing=5000, data_names=['gravity'])
# Upward continuation (requires gridded xarray)
upward = hm.upward_continuation(gravity_grid, height_displacement=1000)| Function | Purpose |
|---|---|
| Gravity from point masses |
| Gravity from rectangular prisms |
| Gravity from spherical prisms (regional/global) |
| Magnetic anomaly from prisms |
| Create layer of prisms from topography |
| Grid scattered data with equivalent sources |
| FFT-based upward continuation |
| Simple Bouguer plate correction |
# Define prism: (west, east, south, north, bottom, top) in meters
prism = [-500, 500, -500, 500, -2000, -500]
density = 500 # kg/m3 density contrast
# Observation grid
x_obs, y_obs = np.meshgrid(np.linspace(-5000, 5000, 100), np.linspace(-5000, 5000, 100))
z_obs = np.zeros_like(x_obs)
# Calculate gravity (mGal). Fields: 'g_z', 'g_north', 'g_east', 'potential'
gravity = hm.prism_gravity((x_obs.ravel(), y_obs.ravel(), z_obs.ravel()),
prism, density, field='g_z')import xarray as xr
topo = xr.open_dataarray('dem.nc')
layer = hm.prism_layer((topo.easting.values, topo.northing.values),
surface=topo.values, reference=0,
properties={'density': 2670})
terrain_effect = layer.gravity((obs_easting, obs_northing, obs_height), field='g_z')
bouguer_anomaly = free_air_anomaly - terrain_effectimport verde as vd
# Project to Cartesian
projection = vd.get_projection(longitude, latitude)
easting, northing = projection(longitude, latitude)
eqs = hm.EquivalentSources(depth=10000, damping=10)
eqs.fit((easting, northing, altitude), gravity_mgal)
grid = eqs.grid(spacing=5000, data_names=['gravity'])prism = [-500, 500, -500, 500, -2000, -500]
magnetization = hm.magnetic_vector(intensity=5.0, inclination=60, declination=10)
b_total = hm.prism_magnetic(coordinates, prism, magnetization, field='b_total')dx = hm.derivative_easting(gravity_grid)
dy = hm.derivative_northing(gravity_grid)
dz = hm.derivative_upward(gravity_grid)
thg = np.sqrt(dx**2 + dy**2) # Total horizontal gradient
tilt = np.arctan2(dz, thg) # Tilt angle| Use Case | Tool | Why |
|---|---|---|
| Gravity/magnetic forward modelling | Harmonica | Purpose-built, Fatiando ecosystem |
| Potential field inversion | SimPEG | Full inversion framework with regularization |
| Commercial gravity processing | Oasis Montaj | Industry-standard GUI, proprietary formats |
| Simple Bouguer corrections only | Custom numpy | Fewer dependencies for one-off calculations |
| Equivalent source gridding | Harmonica | Best open-source option for potential fields |
| Regional/global scale | Harmonica (tesseroids) | Handles spherical geometry natively |
| Magnetic data reduction to pole | Harmonica | FFT-based filters for gridded data |
| Teaching/prototyping | Harmonica | Clean API, good documentation |
hm.prism_layer()verde.get_projection()hm.EquivalentSources()vd.distance_mask()| Issue | Solution |
|---|---|
| Wrong gravity sign | Check z-axis convention (positive upward) |
| Poor equivalent source fit | Adjust |
| Slow terrain correction | Reduce DEM resolution or use larger prisms |
| Edge effects in FFT filters | Pad grid before applying |
| Coordinate mismatch | Ensure consistent use of projected vs geographic coords |