Seismic Trace Processor Extension

Seismic Trace Processors (STP) are an extension point that allows the addition of custom trace processors. Each seismic layer can have any number of STP applied to it. They are applied in the order that they are selected in the Trace Processors tab in the Seismic Layer Properties window.. Examples that are included with INTViewer are the Filter, Phase Rotation, Static Shift, and AGC processors. The following sections will illustrate how to create and install a custom plugin. We will use INTViewer’s Static Shift STP as an example.

A walkthrough is available for the creation and deployment of a seismic trace processor.

Trace Processor

There are two abstract classes that are provided to help implement your own Seismic Processors. The first is the AbstractSeismicProcessor class. This class is dependent on the visual that the seismic layer is a part of. The second class is the AbstractStandaloneSeismicProcessor class. This class is not dependent on a visual, and is the class that Seismic Workbench will utilize for its’ seismic processing capabilities.

To implement an STP plugin, you will first need to implement a class which extends either of the two abstract classes provided.

Seismic layer calls the preProcess method before trace processing actually happens. The method signature is different depending on whether you are implementing AbstractSeismicProcessor or AbstractStandaloneSeismicProcessor. If you are using AbstractSeismicProcessor, the method is called as preProcess(ISeismicData seismicData, IVisual visual). For AbstractStandaloneSeismicProcessor the method’s signature is: preProcess(ISeismicData seismicData).

The processing is actually handled by the method processTrace, and is called for every trace that will be processed. The interface ITrace describes how you can interact with these traces. See the section Working with seismic data for more information on how to get/set the trace samples.

Trace Processor Editor

If the trace processor needs to implement a dialog for parameter input, the interface ISeismicProcessorEditor should be implemented.

Static Shift Trace Processor Implementation

There are two methods where all of the actual processing happens. They are the preProcess and the processTrace methods.

The preProcess method should be used to do any sort of calculations and array creation that can be done before processing each trace, as we do not want to do these over for every single trace. The implementation of the preProcess method for our static shift processor is shown below.

    public void preProcess(ISeismicData seismicData) {
        ISeismicStatistics statistics = seismicData.getDataStatistics();
        unit = seismicData.getZUnit();
        if (statistics != null) {
            numSamples = statistics.getSamplesPerTrace();
            sampleRate = statistics.getSampleRate();
            workArray = new float[numSamples];
        }
        this.updateLookup();
    }

The implementation of the processTrace method for our static shift processor is shown below.

public void processTrace(ITrace trace) {

        int nshift = Math.round(timeShift / sampleRate);
        if (Math.abs(nshift) > numSamples) {
            nshift = numSamples;
        }
        float[] input_data = new float[trace.getSize()];
        trace.getSamples(input_data);
        for (int i = 0; i < numSamples; i++) {
            workArray[i] = input_data[i];
        }
        if (nshift > 0) {
            for (int i = 0; i < nshift; i++) {
                input_data[i] = 0;
            }
            for (int i = nshift; i < numSamples; i++) {
                input_data[i] = workArray[i - nshift];
            }
        } else if (nshift < 0) {
            for (int i = 0; i < numSamples + nshift; i++) {
                input_data[i] = workArray[i - nshift];
            }
            for (int i = numSamples + nshift; i < numSamples; i++) {
                input_data[i] = 0;
            }
        }
        trace.setSamples(input_data);
    }

Any arguments that our trace processor has can be saved and restored. To accomplish this, we must override the restoreState(IMemento m) and saveState(IMemento m) methods.

    public void restoreState(IMemento m) {
        double shift = m.getDouble("shiftValue", 0);
        timeShift = (float) shift;
    }
    public void saveState(IMemento m) {
        m.putDouble("shiftValue", timeShift);
    }

The complete implementation of StaticShiftProcessor is available as an attachment at the bottom of this page. A complete NetBeans project is also available as an attachment at the bottom of this page.

Static Shift Editor Implementation

The Static Shift Processor has an argument, and therefore we need to provide a GUI for users to set these arguments. This is done in two parts. The first step is to create the editor. This is done by implementing the ISeismicProcessorEditor class. This editor will create a new instance of, and update/retrieve variables from the processor’s panel.

The complete implementation of StaticShiftEditor is available in the code samples section. If you want to learn more about editors, look at INTViewer APIs for Dialogs and Editors .

Declarative Registration

The NetBeans way to register plugins is used. This involves adding entries about your processor to the layer.xml file for your project. layer.xml has nothing to do with layers in INTViewer, it is just the term that NetBeans uses. The following is a sample layer.xml that will properly register the Static Shift Processor.

LAYER.XML

<?xml version="1.0" encoding="UTF-8"?>
<filesystem>
    <folder name="Layers">
        <folder name="SeismicLayer">
            <folder name="TraceProcessors">
                <folder name = "StaticShiftProcessor">
                    <folder name="Processor">
                        <file name="com-interactive-tracefilters-staticshift-StaticShiftProcessor.instance"/>
                    </folder>
                    <folder name="Editor">
                        <file name="com-interactive-tracefilters-staticshift-StaticShiftEditor.instance"/>
                    </folder>
                </folder>
            </folder>
        </folder>
    </folder>
</filesystem>

There are two important things to note about this file. The first is that com-interactive-tracefilters-staticshift-StaticShiftProcessor.instance corresponds to the fully qualified name of the processor’s class. In this case the fully qualified name is com.interactive.tracefilters.staticshift.StaticShiftProcessor.class. The second thing to note is that both the trace processor and its editor are located in the same com.interactive.tracefilters.staticshift folder. This is how the seismic layer knows which editor corresponds to which particular trace processor.

Optional Display Parameters

Applying a trace processor doesn't change the normalization scale, limits or any other display parameter. For example, If you were to create a trace processor that just doubles amplitudes, you'd expect to see the amplitudes doubled visually on screen. Recalculating the limits automatically would negate the visible effects of this simple processor.

There is however a way to associate display parameters, including normalization limits, to trace processors. This technique demonstrated below is used in the "envelop" processor where many attributes are being modified when this processor is applied.

Make your processor implement IPropertyProvider. Here is a template:

MyProcessor implements IPropertyProvider {
    private NamedProps props = null;
    @Override
    public NamedProps getProperties() {
        if (this.props == null) { // set default properties
            this.props = new NamedProps();
            props.putProperty(ISeismicLayer.NORMALIZATION_MIN, 1f);
            props.putProperty(ISeismicLayer.NORMALIZATION_MAX, 2f);
        }
        return props;
    }
    @Override
    public void setProperties(NamedProps props, Object editor) { // called when the user overrides the defaults
        if (this.props == null) {
            getProperties();
        }
        this.props.putProperties(props);
    }
    @Override
    public void setProperties(NamedProps props) {
        setProperties(props, null);
    }

When you make your processor implement IPropertyProvider, the bottom of the processor panel will show a "display parameters" section where the user can override the properties set by default by the processor.

Another important note: if your processor implements IPropertyProvider, make sure you call super.saveState and super.restoreState in your own implementation of saveState and restoreState. This will make sure that the display parameters set are remembered through session files.

Troubleshooting

If you don’t see the trace processor in the list of processors there are a few common errors.

  • If you created file layer.xml manually (not from the wizard), make sure it is registered. In folder Important Files, edit file Module Manifest. You should have a line
      • OpenIDE-Module-Layer: com/interactive/tracefilters/staticshift/layer.xml
  • Make sure the paths for StaticShiftProcessor.instance and StaticShiftEditor.instance are both correct.
    • Make sure the folder hierarchy is correct and that the names are spelled correctly. The only folder name that can be changed is the StaticShiftProcessor level. INTViewer specifically searches Layers/SeismicLayer/TraceProcessors for processors.

Other implementations

An example of Normal Move Out trace processor is also provided.