Intro and Theory Refresher

Last updated on 2025-04-17 | Edit this page

Estimated time: 20 minutes

Overview

Questions

  • What are the core components of a GPR system?

  • How does GPR work to detect subsurface changes?

  • What does a GPR trace represent?

  • How can we process and visualize SEG-Y GPR data using Python?

Objectives

  • Understand the structure and functionality of a GPR system.

  • Explain the concept of GPR signal reflection and trace acquisition.

  • Interpret what a single GPR trace and a 2D radargram represent.

  • Demonstrate loading and visualizing GPR SEG-Y data using Python and obspy.

Key Points

  • GPR uses EM waves to detect subsurface features.
  • A trace is a time series of reflections from a point.
  • SEG-Y files can be visualized using ObsPy.

What is geophysics?

In the broadest sense, the science of geophysics is the application of physics to investigations of the Earth, Moon and planets. The subject is thus related to astronomy. To avoid confusion, the use of physics to study the interior of the Earth, from land surface to the inner core, is known as solid earth geophysics. Applied geophysics’ covers everything from experiments to determine the thickness of the crust (which is important in hydrocarbon exploration) to studies of shallow structures for engineering site investigations, exploring for groundwater and for minerals and other economic resources, to trying to locate narrow mine shafts or other forms of buried cavities, or the mapping of archaeological remains, or locating buried pipes and cables – but where in general the total depth of investigation is usually less than 100 m.

Ground penetrating radar (GPR) is now a well-accepted geophysical technique. The method uses radio waves to probe “the ground”. In its earliest inception, GPR was primarily applied to natural geologic materials. Now GPR is equally well applied to a host of other media such as wood, concrete, and asphalt. The most common form of GPR measurements deploys a transmitter and a receiver in a fixed geometry, which are moved over the surface to detect reflections from subsurface features. Ground penetrating radar systems are conceptually simple; the objective is to measure field amplitude versus time after excitation. The heart of a GPR system is the timing unit, which controls the generation and detection of signals. Most GPRs operate in the time domain. GPRs are normally characterized by their center frequency. The common range varies between 50MHz to 2.5 GHz.

Most GPR consist of three components: a console, an antenna, and an encoder. The first two are mandatory. The third is typical for 99 percent of GPR users that work in the utility locating, civil engineering, concrete scanning, and archaeology industries. The console is the brains of the system. This data logger communicates with both the encoder and the antenna to initiate a signal and record the responses. The antenna is where the GPR signal is produced. The encoder, also referred to as a survey wheel, controls for locational accuracy of the GPR data. As the wheel turns a fraction of a turn, the console will initialize the antenna. Most GPR antenna actually consist of a transmitter and a receiver, and once it is initialized by the console, the transmitter will produce the signal. The receiver will record responses for a defined amount of time and once that “time window” has reached its maximum time, the console will terminate the receiver from recording any more data.

The GPR antenna produces an electromagnetic pulse at the ground surface. This pulse, which is in the form of a wave, travels into the subsurface and will continue until one of two things happen: the signal strength totally decays, or the wave encounters a change in the physical properties of the subsurface material. This change can be a small target such as a buried pipe or a large geological layer such a bedrock. When the wave encounters a change in material properties, some of the wave’s energy will reflect back to the ground surface and some will transmit further into the ground if any energy is left. This produces a one-dimensional view just below the antenna. If multiple of these one-dimensional views are collected next to each other (i.e. the GPR is pushed along the ground surface in a line), then a twodimensional view of the subsurface will be generated by the GPR. This two-dimensional view is equivalent to looking at the wall of an excavation trench. It is a vertical profile of the subsurface directly beneath the path that the GPR was pushed.

Diagram of a GPR system showing console, antenna, and encoder.
Schematic of a GPR setup

In this episode, we’ll introduce how to read and visualize a GPR trace from SEG-Y data using Python and the obspy library.

To visualize Ground Penetrating Radar (GPR) data, we can use the obspy library, which supports the SEG-Y format.

Below is a simple example of how to load and display a single GPR trace:

PYTHON

from obspy.io.segy.segy import _read_segy
import matplotlib.pyplot as plt

# Load SEG-Y using ObsPy (handles variable-length traces)
stream = _read_segy("LINE01.sgy", headonly=False)

# Access trace data
trace0 = stream.traces[0].data
n_traces = len(stream.traces)

# Plot first trace
plt.figure(figsize=(6, 4))
plt.plot(trace0)
plt.title("First Trace from LINE01.sgy")
plt.xlabel("Sample Index")
plt.ylabel("Amplitude")
plt.grid(True)
plt.show()

PYTHON

import matplotlib.pyplot as plt
from obspy.io.segy.segy import _read_segy
import numpy as np

# Load SEG-Y file
segy_file = "LINE01.sgy"
stream = _read_segy(segy_file, headonly=False)

# Number of traces and max trace length
n_traces = len(stream.traces)
max_len = max(len(tr.data) for tr in stream.traces)

# Fill 2D array with seismic data
data = np.zeros((max_len, n_traces))
for i, tr in enumerate(stream.traces):
    data[:len(tr.data), i] = tr.data

# Plot
plt.figure(figsize=(12, 6))
plt.imshow(data, cmap="gray", aspect="auto", origin="upper", interpolation="none")
plt.title("Seismic Section (LINE01.sgy)")
plt.xlabel("Trace Number")
plt.ylabel("Time Sample")
plt.colorbar(label="Amplitude")
plt.show()