The seismic data API provides seamless access to all seismic data formats supported. We load a seismic dataset with the path filePath and print some statistics about the seismic data.
import com.interactive.intgeoapi.data.IData;
import com.interactive.intgeoapi.data.seismic.ISeismicData;
import com.interactive.intgeoapi.data.seismic.ISeismicStatistics;
...
ISeismicData sd = IData.factory.createNewInstance(filePath, ISeismicData.class);
ISeismicStatistics stats = sd.getDataStatistics();
System.out.println("Number of traces = " + stats.getNumberOfTraces());
System.out.println("Number of samples per trace = " + stats.getSamplesPerTrace());
Internally the default implementation of the factory uses a com.interactive.intgeo.data.filesystem.AbstractFileSystemDataObject to load the data files. The INTGeo API supports the notion of a data pool (implementing com.interactive.intgeo.data.filesystem.IFileSystemDataObjectPool), so that if you open several times the same file, you will get the same data object instance.
Range keys provide information about how to access the seismic data. They can be accessed as follows:
List<IKeyRange> keyRangeList = sd.getDataRange();
For basic dataset in formats like Segy or SU, there will only be two keys defined ("TraceNumber" and "Time"). For an indexed dataset, the number of keys in the list will be the number of keys used for indexing plus the sample key. For example, if a Segy dataset has been indexed with two keys, let say INLINE and XLINE, then keyRangeList will contain 3 keys, "INLINE", "XLINE" and "Time". Please note that the keys are always ordered from the slowest varying to the fastest one. The last key is always the trace sample key ("Time" or "Depth" typically).
The example below prints the values for the keys. For seismic data, the keys also implement ISeismicKeyRange to provide access to the data increment and sort order.
import com.interactive.intgeoapi.data.IKeyRange;
import com.interactive.intgeoapi.data.seismic.ISeismicKeyRange;
...
for (IKeyRange key: keyRangeList) {
System.out.println("keyname=" + key.getName() + " min=" + key.getMinimum() +
" max=" + key.getMaximum());
System.out.println("increment=" + ((ISeismicKeyRange)key).getIncrement() +
" sortOrder=" + ((ISeismicKeyRange)key).getKeySortOrder());
}
The interface ISeismicData has a select method which returns a reader that can be used to access the selected traces. A query needs to be passed as an argument to the select as shown below.
import com.interactive.intgeoapi.data.seismic.SeismicKeyRange;
import com.interactive.intgeorapi.data.seismic.ISeismicReader;
import com.interactive.intgeorapi.data.query.SeismicRangeQuery;
...
// in this example we query for both an inline and xline range
SeismicRangeQuery query = new SeismicRangeQuery(ISeismicData.ORDER_XSECTION);
SeismicKeyRange inlineRange = new SeismicKeyRange("INLINE", 10, 25);
query.addKeyRange(inlineRange);
SeismicKeyRange xlineRange = new SeismicKeyRange("XLINE", 1, 400);
query.addKeyRange(xlineRange);
ISeismicReader reader = sd.select(query);
In the above example we set the first key (typically the INLINE) to the first value. If our dataset is a volume, this query will give us access to the first inline.
If you work with volumes or pre-stack dataset, you can also perform a query by path. The following example shows how to use SeismicPathQuery to query traces along a path.
import com.interactive.intgeoapi.data.query.SeismicPathQuery;
...
SeismicPathQuery query = new SeismicPathQuery(
"INLINE",
new double[] {367,386,327,247,274},
"XLINE",
new double[] {246,402,472,539,606});
layer.select(query);
The example below shows how to extract the first trace from the reader obtained in the previous section.
import com.interactive.intgeoapi.data.seismic.ITrace;
...
try {
int ntraces = reader.getNumberOfTraces();
if (ntraces > 0) {
ITrace trace = reader.getTrace(0);
float values[] = new float[trace.getSize()];
trace.getSamples(values);
}
} catch (Exception ex) {
...
}
The example below print the OFFSET header values for the traces selected above.
import com.interactive.intviewerapi.data.IFieldDesc;
...
IFieldDesc offsetHeader = reader.getTraceHeaderField("OFFSET");
if (offsetHeader != null) {
for (int i=0; i<reader.getNumberOfTraces(); i++) {
Float value = reader.getTrace(i).getHeader(offsetHeader.getIdentifier()).floatValue();
System.out.println("Offset value = " + value);
}
}