Seismic Generator Extension

Seismic generators are an extension point that allows the addition of custom seismic generators. There are two main types of seismic generators provided by the INTViewer Platform.

  • The first type is one that takes in seismic data, and produces a modified version of that data. An example of this type of generator is the Remove Empty Traces generator that is built into INTViewer. This generator takes a seismic dataset as input, and produces a seismic dataset with all zero valued traces removed. This type of seismic generator is created by extending the AbstractSeismicGeneratorFromReader class. Use this class for generators that do not modify the dimensions of a dataset (You can change the number of traces, but not their length). If you need to do something more complex, consider using AbstractSeismicToSeismicGenerator instead.
  • The second type of generator is one which has no input data, and produces seismic data. An example of this is the Create Random Volume generator that is built into INTViewer. This generator simply produces a completely randomized seismic dataset with the size determined by several user inputs. This type of generator is created by extending AbstractVoidToSeismicGenerator.

A walkthrough is available for the creation and deployment of the Remove Empty Traces generator.

CleanEmptyTracesSeismicGenerator Implementation

If you are using AbstractSeismicGeneratorFromReader there are only two methods that you must implement. getName is self explanatory. getSeismicReader is also a fairly simple method. This method returns a seismic reader, which is a class which provides all of the information about a seismic dataset. This method will create an instance of our own reader and return it. It will not be doing any of the processing, this is saved for the reader class that we define. The following is sample code from INTViewer's Remove Empty Traces generator.

    public ISeismicReader getSeismicReader(ISeismicData seismicData, ILongTaskProgressMonitor monitor) throws Exception     {
        ISeismicReader reader = seismicData.select(new SeismicRangeQuery(ISeismicData.ORDER_XSECTION));
        return new CleanEmptyTracesSeismicReader(reader);
    }

CleanEmptyTracesSeismicReader Implementation

You will typically extend AbstractGeneratedSeismicReader if you are creating a generator from AbstractSeismicGeneratorFromReader. There are only two methods that you must implement. The methods that we must implement are the getNumberOfTraces and getTrace methods. In our Remove Empty Traces example, getNumberOfTraces simply returns the size of our array. The getTrace method uses the index that was stored, and returns the trace at that index from the original reader.

public class CleanEmptyTracesSeismicReader extends AbstractGeneratedSeismicReader {
    private List<Integer> nonEmptyTraceIndexes;
    public CleanEmptyTracesSeismicReader(ISeismicReader reader) throws Exception {
        super(reader);
    }
    private void findNonEmptyTracesIfNeeded()  {
        if (nonEmptyTraceIndexes == null) {
            this.findNonEmptyTraces();
        }
    }
    private void findNonEmptyTraces() {
        nonEmptyTraceIndexes = new ArrayList<Integer>();
        ISeismicReader reader = this.getOriginalReader();
        for (int originalIndex = 0; originalIndex < reader.getNumberOfTraces(); originalIndex++) {
            ITrace currentTrace = reader.getTrace(originalIndex);
            float[] values = new float[currentTrace.getSize()];
            currentTrace.getSamples(values);
            boolean isTraceEmpty = true;
            for (float currentValue : values) {
                if (currentValue != 0) {
                    isTraceEmpty = false;
                    break;
                }
            }
            if (!isTraceEmpty) {
                nonEmptyTraceIndexes.add(originalIndex);
            }
        }
    }
    @Override
    public int getNumberOfTraces() {
        this.findNonEmptyTracesIfNeeded();
        return nonEmptyTraceIndexes.size();
    }
    @Override
    public ITrace getTrace(int i) throws IllegalArgumentException {
        this.findNonEmptyTracesIfNeeded();
        Integer index = nonEmptyTraceIndexes.get(i);
        return this.getOriginalReader().getTrace(index.intValue());
    }
}

CleanEmptyTracesSeismicGeneratorEditor

In this case, the editor class is just an empty skeleton as the remove empty traces generator does not require any user input. If your generator does require user input, this class would return your own panel. There are two things to note with this class.The first is that it is required with each generator. The second is that your editor will extend IDataGeneratorEditor<?, ?>. The question marks are the input and output class types for this generator. So for the Remove Empty Traces generator they are both replaced by ISeismicData. For a generator like the ones that generate random data with no input data you replace the first question mark with Void, and the second with ISeismicData.

Declarative Registration

The NetBeans way to register plugins is used. This involves adding entries about your generator 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 file that will properly register the Remove Empty Traces Generator.

LAYER.XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
<filesystem>
    <folder name="DataGenerators">
        <folder name="CleanEmptyTracesGenerator">
            <folder name="Generator">
                <file name="com-interactive-intviewer-generators-seismic-cleantraces-CleanEmptyTracesSeismicGenerator.instance"/>
            </folder>
            <folder name="Editor">
                <file name="com-interactive-intviewer-generators-seismic-cleantraces-CleanEmptyTracesSeismicGeneratorEditor.instance"/>
            </folder>
        </folder>
    </folder>
</filesystem>

There are two important things to note about this file. The first is that com-interactive-intviewer-generators-seismic-cleantraces-CleanEmptyTracesSeismicGenerator.instance corresponds to the fully qualified name of the generator's class. in this case the fully qualified name is com.interactive.intviewer.generators.seismic.cleantraces.CleanEmptyTracesSeismicGenerator.class. The second thing to note is that both the seismic generator and its editor are located in the same com.interactive.intviewer.generators.seismic.cleantraces folder. This is how INTViewer knows which editor corresponds to which particular seismic generator.

Troubleshooting

If you don't see the seismic generator in the contextual menu there are a few common errors.

  • If you created the file layer.xml manually (not from the wizard), make sure it is registered. In the folder Important Files, edit the file Module Manifest. You should have a line

OpenIDE-Module-Layer: com/interactive/intviewer/generators/seismic/layer.xml

  • Make sure the paths for CleanEmptyTracesSeismicGenerator.instance and CleanEmptyTracesSeismicGeneratorEditor.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 CleanEmptyTracesGenerator level. INTViewer specifically searches DataGenerators for generators.