Geophysics Functions
Overview
The geophysics module provides functions for satellite-based geodetic analysis, specifically for processing InSAR (Interferometric Synthetic Aperture Radar) data. These functions allow projecting 3D displacement fields onto a line-of-sight (LOS) direction and converting projected displacements into interferometric fringe patterns.
InSAR Projection
// Project a 3D displacement field onto a satellite line-of-sight (LOS) direction.
// Returns the scalar projection (dot product) of each displacement vector
// onto the unit LOS vector.
Serie<double> insar(
const Serie<Vector3D> &displacements, // 3D displacement vectors
const Vector3D &los // Line-of-sight unit vector
);
The insar function computes the component of each 3D displacement vector along the
satellite's line-of-sight direction. This simulates what an InSAR satellite would measure: the
range change between the satellite and the ground surface. The LOS vector should be a unit vector
pointing from the ground toward the satellite.
// Simulated 3D displacement field from a fault model
df::Serie<Vector3D> displacements{
{0.01, 0.02, -0.005},
{0.03, 0.01, -0.010},
{0.02, 0.03, -0.008},
{0.005, 0.005, -0.002}
};
// Satellite LOS direction (e.g., descending orbit, ~23 deg incidence)
// Typically: LOS = {east, north, up} components
Vector3D los = {-0.38, -0.09, 0.92}; // Approximate descending LOS
// Project displacements onto LOS
auto los_disp = df::geo::insar(displacements, los);
// los_disp contains the scalar range change at each point
for (size_t i = 0; i < los_disp.size(); ++i) {
std::cout << "Point " << i << ": LOS displacement = "
<< los_disp[i] * 1000.0 << " mm" << std::endl;
}
Interferometric Fringes
// Convert scalar displacement values to interferometric fringe pattern.
// Each fringe cycle represents one full wavelength of displacement.
Serie<double> fringes(
const Serie<double> &los_displacements, // LOS displacement values
double fringeSpacing // Fringe spacing (e.g., half-wavelength)
);
The fringes function wraps displacement values into a periodic fringe pattern, simulating
the wrapped phase that an InSAR interferogram displays. The fringeSpacing parameter
determines the displacement interval per fringe cycle. For C-band SAR (e.g., Sentinel-1), one fringe
corresponds to about 2.8 cm of LOS displacement (half the radar wavelength of ~5.6 cm).
// LOS displacements from the insar() function
auto los_disp = df::geo::insar(displacements, los);
// Convert to fringes with C-band half-wavelength spacing (2.8 cm)
double half_wavelength = 0.028; // 28 mm
auto fringe_pattern = df::geo::fringes(los_disp, half_wavelength);
// fringe_pattern values are in [0, 1) representing the wrapped phase
// 0 and 1 correspond to the same fringe color
Complete Example
#include <dataframe/Serie.h>
#include <dataframe/geo/geophysics.h>
#include <dataframe/geo/grid/from_dims.h>
#include <dataframe/geo/interpolation/idw.h>
#include <iostream>
int main() {
// Model displacement field at scattered points
df::Serie<Vector<3>> model_pts = /* fault model observation points */;
df::Serie<Vector3D> model_disp = /* 3D displacements from BEM model */;
// Create a regular grid for visualization
auto grid_pts = df::grid::cartesian::from_dims<3>(
{100, 100, 1},
{0.0, 0.0, 0.0},
{50000.0, 50000.0, 0.0} // 50 km x 50 km surface grid
);
// Interpolate displacements to the grid
auto grid_disp = df::geo::idw<Vector3D, 3>(
model_pts, model_disp, grid_pts
);
// Project onto ascending orbit LOS
Vector3D los_asc = {0.38, -0.09, 0.92};
auto los_asc_disp = df::geo::insar(grid_disp, los_asc);
// Project onto descending orbit LOS
Vector3D los_desc = {-0.38, -0.09, 0.92};
auto los_desc_disp = df::geo::insar(grid_disp, los_desc);
// Generate fringe patterns (C-band)
auto fringes_asc = df::geo::fringes(los_asc_disp, 0.028);
auto fringes_desc = df::geo::fringes(los_desc_disp, 0.028);
std::cout << "Generated " << fringes_asc.size()
<< " fringe values for ascending and descending orbits\n";
return 0;
}