Skip to content

Make a wavelet

A wavelet is a short series of samples at a fixed interval, the pulse a synthetic seismic section is convolved with. Ophiolite keeps a wavelet as a small text file that states its shape, the frequency it was made for, the sample interval, the time of its first sample and its polarity, followed by the samples. Nothing about it is inferred: a file that does not state its sample interval is refused with “Declare the sample interval; nothing is inferred.”

Two shapes are computed by the SDK from their formulas, with the same numbers in Python and in the browser:

Shape Made from
Ricker one frequency f: (1 - 2 (π f t)²) e^-(π f t)²
Ormsby four corner frequencies f1-f2-f3-f4 (Hz), scaled so the centre sample is 1

The frequency content is calculated from the stored samples on a 1 Hz grid up to the Nyquist frequency, so it shows what the samples hold, not what the file declares.

Open the wavelet in Data. The inspector shows:

  • Shape, for example “Ricker, 30 Hz (declared)”; Samples, for example “129 samples every 1 ms, from -64 to 64 ms”; Polarity in words.
  • The wavelet drawn one column per sample, up is positive. Move along it with the arrow keys; the readout says “Sample 52 of 129 · time -13 ms · value -0.446260016743396”, the stored value.
  • “Frequency content: strongest at 30 Hz (read to the nearest 1 Hz)”. When a Ricker wavelet’s samples do not peak at the frequency it declares, the inspector says so, for example “The strongest frequency is 40 Hz, not the declared 30 Hz.”
  • For a wavelet with a newer version: “This is version 1 of 2; a newer version exists.”

There is no upload dialog entry for wavelets; they are made and uploaded from Python.

client is an ophiolite.Client for your project; see Build on Ophiolite for a key and the SDK. Compute a 30 Hz Ricker wavelet, 128 ms long at 1 ms:

from ophiolite.synthetics import ricker
from ophiolite.typed import Wavelet
wavelet = ricker(30, 0.001, duration=0.128)
c = wavelet.context
print(f"{c['sample_count']} samples every {c['dt'] * 1000:g} ms, from {c['t0'] * 1000:g} to {-c['t0'] * 1000:g} ms")

This prints 129 samples every 1 ms, from -64 to 64 ms. Check the strongest frequency of the samples against the declared one. The same samples read at twice the interval peak at half the frequency:

peak = wavelet.peak_frequency()
print(f"Strongest at {peak:g} Hz (read to the nearest 1 Hz); declared {c['frequency_hz']:g} Hz")
stretched = Wavelet(None, {"context": {**c, "dt": 0.002, "t0": 2 * c["t0"]}, "samples": wavelet.samples}, None)
print(f"The same samples every 2 ms: strongest at {stretched.peak_frequency():g} Hz")

This prints Strongest at 30 Hz and strongest at 15 Hz. Upload the wavelet; it starts private to you. A second wavelet uploaded with append_to and expected_parent becomes version 2 of the same wavelet, and version 1 is kept:

import uuid
upload = dict(profile="wavelet-text/1", name="Ricker 30 Hz", attribution="Computed with ophiolite.synthetics",
audience=[], rights_confirmed=True)
first = client.upload_data(Wavelet.write(wavelet).bytes, filename="ricker-30.txt", command_id=str(uuid.uuid4()), **upload)
sharper = ricker(35, 0.001, duration=0.128)
second = client.upload_data(Wavelet.write(sharper).bytes, filename="ricker-35.txt", command_id=str(uuid.uuid4()),
append_to=first.asset_id, expected_parent=first.revision, **upload)
for number, receipt in ((1, first), (2, second)):
read = client.read_data(first.asset_id, receipt.revision)
print(f"version {number}: strongest at {read.peak_frequency():g} Hz")

read_data returns the samples exactly as uploaded. An Ormsby wavelet is made the same way, ormsby((5, 10, 40, 50), 0.002, duration=0.2).

A refusal says what to do. ValidationFailed from ophiolite.synthetics names the problem, for example “A frequency must be below the Nyquist frequency (500 Hz at this interval).”, “The Ormsby corner frequencies must increase.” or “A wavelet must be sampled every 0.0005 to 0.01 s.”; nothing was uploaded. IntegrityConflict on a new version: the wavelet changed since you read it; read it again. “A new version keeps the result’s audience; change who may read it separately”: a version cannot change who may read the wavelet.

To try the same steps without a project, download the Make a wavelet notebook: it computes everything on your own computer. Wedge model and synthetic uses the wavelet to make a synthetic seismic section.