Seismic Widgets are high level reusable graphics components built for visualization of seismic data. The Seismic package of GeoToolkit provides an API to help viewing, interpreting and processing seismic data in applications such as seismic QC, cross-section displays, velocity analysis or VSP applications. This tutorial demonstrates the use of the Seismic widget, loading seismic data, and how to change the initial widget appearance.
# Create a Reader
The Seismic Toolkit breaks down seismic data into relatively simple definitions where the most basic primitive data type is called a sample. A sample represents a single value at a particular time or depth. A contiguous sequential collection of samples with an associated sampling interval or rate is called a trace. Lastly, a sequential collection of traces is called a reader. GeoToolkit provides several implementations of readers to provide data from memory, from remote data sources, or from files. In this example, the memory reader is used. It has several callbacks to provide trace samples "getTraceData" and trace headers "getTraceHeader" and data statistics. The code below creates memory reader and fills traces by request.
# Create a Pipeline
The next step is to prepare data to be visualized. The Seismic Toolkit uses the flexible structure for processing of seismic data called the pipeline model. In this model, the seismic data processing pipeline is basically a chain of trace processes (operations) working on trace data (samples). The output data from one trace process serves as the input data for the next process in the pipeline. In this section, a simple pipeline is created, it contains default normalization, interpolation and rendering routines. Also, specify the color map and plot type to render wiggles with negative and positive color fill.
# Create a Widget
The last step is to create a seismic widget using the pipeline created earlier. Use the geotoolkit/seismic/widgets/SeismicWidget, which has a center part to display seismic data and a set of annotations on each side to display axes, titles, or the colorbar. The widget has several default tools which can be enabled/disabled as needed, a status bar and a table of trace headers. Alternatively, geotoolkit/seismic/widgets/SeismicViewWidget can be used. It has the same tools, but doesn't have status bar and table to display trace headers.
The following code demonstrates how to create a widget and specify scale options for trace and samples.
# Modify Widget Settings
Default widget settings can be customized using setOptions method.
The following code demonstrates how to modify a widget setting to change the colorbar size and to add a title.
# General Information
Widget initialization is built upon Carnac Getting Started , but it also requires including additional JavaScript libraries. The following example uses initialization based on VueJS Vue framework and demonstrates the first typical operations performed on the seismic data such as: reading the data, choosing the plot type and changing visualization properties such as the color map.
import { MemoryReader } from "@int/geotoolkit/seismic/data/MemoryReader.ts";
import { SeismicPipeline } from "@int/geotoolkit/seismic/pipeline/SeismicPipeline.ts";
import { SeismicColors } from "@int/geotoolkit/seismic/util/SeismicColors.ts";
import { NormalizationType } from "@int/geotoolkit/seismic/pipeline/NormalizationType.ts";
import { SeismicWidget } from "@int/geotoolkit/seismic/widgets/SeismicWidget.ts";
import { ColorBarLocation } from "@int/geotoolkit/controls/shapes/ColorBarLocation.ts";
import { Alignment } from "@int/geotoolkit/layout/BoxLayout.ts";
import { AnnotationLocation } from "@int/geotoolkit/layout/AnnotationLocation.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
const createReader = function() {
const sampleRate = 1;
const sampleCount = 600;
const traceCount = 500;
return new MemoryReader({
"numberoftraces": traceCount,
"numberofsamples": sampleCount,
"samplerate": sampleRate
}).setTraceProcessor({
"getTraceData": function(reader, trace, traceId) {
for (let i = 0; i < sampleCount; i++) {
trace[i] = Math.sin((i / 10 + traceId / 4) * Math.PI);
}
},
"getDataStatistics": function() {
return {
"average": 0,
"min": -1,
"max": 1,
"rms": Math.sqrt(2) / 2
};
}
});
};
const createPipeline = function(reader) {
const pipeline = new SeismicPipeline({
"name": "MemorySeismic",
"reader": reader,
"statistics": reader.getStatistics()
});
const colorProvider = SeismicColors.getDefault();
pipeline.setOptions({
"colors": {
"colormap": colorProvider.createNamedColorMap("RedWhiteBlack")
},
"normalization": {
"type": NormalizationType.Limits,
"limits": {
"min": -1,
"max": 1
}
},
"plot": {
"type": {
"wiggle": true,
"negativecolorfill": true,
"positivecolorfill": true
},
"decimationspacing": 5
}
});
return pipeline;
};
const createWidget = function(pipeline) {
return new SeismicWidget({
"pipeline": pipeline,
"colorbar": {
"axis": {
"tickgenerator": {
"edge": {
"tickvisible": false,
"labelvisible": false
}
}
}
}
}).setScaleOptions({
"tracescale": 3,
"samplescale": 30,
"deviceunit": "in",
"sampleunit": "ms"
});
};
function createScene(canvas) {
const reader = createReader();
const pipeline = createPipeline(reader);
const widget = createWidget(pipeline);
widget.setOptions({
"layouttype": "inside",
"statusbar": {
"visible": false
},
"colorbar": {
"axis": {
"size": 30
},
"title": {
"size": 20
},
"colorbox": {
"size": 10
},
"location": ColorBarLocation.West,
"maxheight": "90%",
"alignment": Alignment.Center
},
"title": {
"text": "Seismic Widget",
"location": AnnotationLocation.North,
"visible": true
},
"axes": {
"samples": {
"size": 50
}
}
});
return new Plot({
"canvaselement": canvas,
"root": widget
});
}
export { createScene };
createScene(document.querySelector('[ref="plot"]'));