The "seismictraceswithheader" web service provides all trace header and sample values for a selection of traces using provided header descriptor. For performance reasons, these values are provided in the form of a binary stream instead of JSON objects.
A typical URL is http://myserver.mycompany.com:8080/INTGeoServer/api/ds/{datasourcetype}/v1/sources/{datasource}/seismic/{seismicuniqueid}/querytraces/withheaderdescriptor
where
datasourcetype: type of a datasource, i.e. geofiles, s3, etc.
datasource: unique id of a datasource
seismicuniqueid: unique id of a seismic
The following parameters are available:
headerdescriptor: specifies a header descriptor XML string
starttraceindex: specifies an index of the first trace to return. This is an optional parameter. The default is 0.
endtraceindex: specifies an index of the last trace to return. This is an optional parameter. The default is the index of the last trace.
compression: specifies a name of the seismic compression algorithm. This is an optional parameter. The default is no compression.
traceindices: specifies indices of traces to include. This is an optional parameter. The default is all trace indices.
includesamples: indicates whether sample values should be included. This is an optional paramter. The default is true.
byteorder: the endianess of the streamed sample bytes. Valid options are "BIG_ENDIAN" or "LITTLE_ENDIAN". This is an optional parameter. When not specified, the endianess of the OS where INTGeoServer is hosted will be used
sampleformat: specifies a name of the format for sample values: Raw, Float, Integer, Short, Byte. This is an optional parameter. The default is Float.
query: the query that will be run on the dataset. See the seismicquery web service for more information.
If the specified seismicuniqueid doesn't match a valid seismic dataset, no JSON response will be provided. The HTTP response will only show a "InvalidUniqueId" (error 404) in its headers.
The binary stream contains a series of traces. The size of each trace can be calculating using headerSize + samplesPerTrace * 4. We multiply the number of samples by four, because all sample data is encoded using 4 bytes, regardless of the seismic data's actual format.
The samplesPerTrace and headerSize are provided by the seismicdata web service. The number of samples per trace can be accessed using the "samplesPerTrace" entry. To retrieve the header size, get the "traceHeader" entry, then retrieve "size" entries contained within it. It is important to note that if the "includesamples" entry is false, the Trace Samples portion of the trace layout would not be added, and only the Trace Headers would be streamed. This means the size of each trace would only be the headerSize.
The trace headers are also provided by the seismicdata web service. The trace headers will be placed in the same order as they are listed according to the "traceHeader" + "fields" entry. When reading the fields, you will need to use the "type" entry to determine how to interpret the header value. These values could be ints, shorts, floats, or doubles.
The number of traces can be found by using the seismicquery web service using the "numberOfTraces" entry. Using the number of traces and the calculated size of each trace, you can determine the total size of the stream. Using this total size, you could create a progress bar to display to the user.
The structure of the binary stream is the same regardless of the file format (Segy, JavaSeis, etc) or the sample format (8 bit, 32 bit, etc).
For performance reasons, it is best to request less than 10,000 traces at a time. Paging should be used to avoid long-running HTTP requests.
The following Java code can be used to parse this input stream into a set of trace objects:
Create a ByteBuffer, with a size equivalent to: headerSize + samplesPerTrace * 4. Then, begin reading in the information.
DataInputStream dis = ...
int traceBlockSize = headerSize + samplesPerTrace * 4;
ByteBuffer traceBuffer = ByteBuffer.allocate(traceBlockSize);
dis.readFully(traceBuffer.array());
Get the trace headers from the seismicdata web service. Get the headerSize, headerType, and headerName from the trace headers. Trace headers are not all necessarily the same size. Some are stored as ints, floats, etc. We need this information to be able to correctly parse the ByteBuffer.
Read the trace header information, and store this into a map containing the trace header names and their values.
Map<String, Double> traceHeaderData= ...
String headerName = ...
int headerSize = ...
int bytePosition = 0;
traceHeaderData.put(headerName, traceBuffer.getDouble(bytePosition));
bytePosition = bytePosition + headerSize;
Depending on the type, you would use traceBuffer.getInt, traceBuffer.getFloat or traceBuffer.getDouble
Loop through the remaining trace buffer, reading in the sample values. All sample values will be four bytes in size.
for (int j = 0; j < samplesPerTrace; j++) { //read all samples
samples[j] = traceBuffer.getFloat(headerSize + j * 4);
}
Using HTML5 Geotoolkit:
var seismicdatasource = new geotoolkit.seismic.data.RemoteSeismicDataSource({
'file': 'data/seismic/' + filename + '.xgy',
'host': intgeourl + 'json/seismictraces'
});
seismicdatasource.open( // Fetch metadata
function () {
// Once metadata have been fetched, request an Inline
var inlinekey = seismicdatasource.getKeys()[0];
var oppositeKey = seismicdatasource.getKeys()[1];
var inlineNumber = 42;
var selectKeys = [inlinekey, oppositeKey];
selectKeys[0]['min'] = inlineNumber;
selectKeys[0]['max'] = inlineNumber;
selectKeys[0]['position'] = inlineNumber;
seismicdatasource.select({
'keys': selectKeys,
'emptyTracesKey': oppositeKey
},
function (reader) {
// Data has been fetched
// See geotoolkit.seismic.data.RemoteSeismicReader API for usage
},
function () {
// error
}
);
}, function () {
// error
}
);
Or without HTML5 Geotoolkit, the following Javascript code can be used to retrieve and parse data:
// Create an XHR object
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200 && xhr.response != null) {
// The 'response' property returns a binary ArrayBuffer
var data = xhr.response;
// [...] Use the data (See below)
} else {
geotoolkit.log("Failed to download:" + xhr.status + " " + xhr.statusText);
}
}
};
// Open the request for the provided url
xhr.open("GET", url, true);
// Set the responseType to 'arraybuffer' for ArrayBuffer response
xhr.responseType = "arraybuffer";
xhr.send();
Get the trace headers from the seismicdata web service. Get the headerSize, headerType, and headerName from the trace headers.
Read the trace header information, and store this into a json containing the trace header names and their values.
var headerNames = []; // [...]
var headers = {};
headerNames.forEach(function (headerName) {
var bytePosition = 0; // [...]
headers[headerName] = new Uint8Array(data, bytePosition, 1);
});
Depending on the type, you would use Float32Array, Float64Array, etc
To access the samples use:
var samples = new Float32Array(data, traceSize * traceId + headerSize, samplesPerTrace);