Considerations when designing your own seismic format for INTViewer

The Geoscience industry has created many formats to represent seismic data. Here are some considerations for a best fit of your proprietary file format for future integration in INTViewer.

For an example on how to plug your own format, follow this example of ISeismicData implementation for a text format.

Sample Statistics

INTViewer needs the following sample statistics to be precalculated:

- Average

- Minimum

- Maximum

- RMS

Percentiles is also nice to have.

It might not be practical to calculate these statistics for all traces. 200 significant traces is a good number in most cases.

See ISeismicStatistics: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicStatistics.html

Other Meta Data

INTViewer needs to be able to quickly access the following information:

A/ what type of dataset is it?

Useful for defaulting data selections and some other features below. Typically:

- volume, or

- gather, or

- 2d line, or

- other

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, 2 keys (ex: INLINE& XLINE) imply that the dataset is a volume. More than 2 keys (ex: INLINE, XLINE and OFFSET) imply that the dataset is a gather.

B/ What are the volume keys for gathers ? What are the offset keys?

Useful for map displays

Useful for variable trace spacing display of gathers in XSection windows.

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, INTViewer uses the first 2 keys as "volume keys" (ex: INLINE & XLINE). Other keys are offset keys (ex: OFFSET). INTViewer also looks for header names like DIST or OFFSET for variable trace spacing.

C/ What is the CRS used?

Ideally the EPSG code + WGS84 transform code.

Useful for map displays and to combine with other datasets like wells.

This is the String returned by ISeismicData.getEPSGCode()

Example: 23029:1138 for

- EPSG "ED50 / UTM zone 29N" (see http://georepository.com/crs_23029/ED50-UTM-zone-29N.html), and

- Transformation to WGS84 "Europe-British Isles and Channel Islands onshore" (see http://georepository.com/transformation_1138/ED50-to-WGS-84-6.html)

See ISeismicData interface: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicData.html#getEPSGCode()

D/ What is the corner point geometry?

Useful for map displays and to combine with other datasets like wells.

This is the object returned by ISeismicData.getIJToXYTransformation()

See ISeismicData interface: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicData.html#getIJToXYTransformation()

E/ What is the trace spacing (distance + unit)?

Useful for F-K displays

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, INTViewer reads a few traces within the dataset, attempting to find consecutive traces in the INLINE/XLINE grid. The EPSG code (see section C/) is used to find the unit (usually feet or meters)

F/ What are the X and Y headers? Is there a scaler header?

Useful for variable trace spacing display in XSections

Useful for calculating the corner point geometry if D/ wasn't provided.

Useful for calculating the trace spacing if E/ wasn't provided.

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, INTViewer looks for header names like CDPX, CDPY and LOC SCALER.

G/ What is the outline for 3D+ datasets? Is the dataset regular?

Useful for 3D+ map displays

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, INTViewer reads all traces to detect the outline. The performance of this detection can be greatly improved if a meta data indicates that the dataset is regular (i.e. has no missing traces)

H/ What is the line/trajectory for 2D line datasets?

Useful for fast 2D line displays in maps

INTViewer has a private API to read this metadata from any ISeismicData instance. By default, INTViewer reads all traces to detect the trajectory.

Features

1/ FindFirstTrace

The ISeismicReader interface requires support for a "findFirstTrace" method. This method allow quick subsearches within a selection of traces. This feature is used by INTViewer to:

- synchronize the cursor across windows without reading every trace of a selection

- annotate XSection windows without reading every trace of a selection

If your index doesn't allow quick subsearches, visualization performance will be impacted.

See ISeismicReader interface: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicReader.html#findFirstTrace(com.interactive.intviewerapi.data.query.SeismicRangeQuery)

Note that in future versions of INTViewer, findFirstTrace will change to allow more annotation options. The tentative new method signature will be:

    List<Integer> findTracesWithin(SeismicRangeQuery query, int maxMatchingTraces,
            Scope scope, SearchOrder searchOrder, ILongTaskProgressMonitor monitor);
    public enum Scope {
        SKIP_MISSING_TRACES,
        KEEP_MISSING_TRACES
    };
    public enum SearchOrder {
        ASCENDING_SEARCH_ORDER,
        DESCENDING_SEARCH_ORDER
    }

2/ Missing Traces

The "missing traces" option allow visualization of imaginary traces that would exist if a dataset was regular.

From an API point of view, this is implemented as part of the support for SeismicRangeQuery.setEmptyTraceKeyRange(IKeyRange emptyTraceRange).

See SeismicRangeQuery class: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/query/SeismicRangeQuery.html#setEmptyTraceKeyRange(com.interactive.intviewerapi.data.IKeyRange)

3/ Map/Transposed Access

The map option allow visualization of seismic datasets in Map windows as time slices

Time slices need fast access to the samples at a particular time

From an API point of view, this is implemented as part of the the support for SeismicRangeQuery.getSeismicTraceOrder and ISeismicData.hasOrder(int order) methods

4/ Decimation

When a seismic range query is built, each seismic key range might have an increment specified, Ex INLINE: 180-190[2]. Your index needs to be able to support decimation as this is an important feature of INTViewer.

See the getIncrement() method in the ISeismicKeyRange interface: http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicKeyRange.html

See the seismic range query class:

http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/query/SeismicRangeQuery.html

5/ Ascending and descending sort orders

By default, seismic range queries are "unsorted", meaning that the traces are returned in the order they were recorded (i.e. their global trace number). However, users are free to force a sorting order for each key of a seismic range query.

See the getSortOrder() method in the ISeismicKeyRange interface.

6/ Previous and next slice

When datasets are sparse, going to the "next" slice sometimes means jumping to a far away slice. For best performance, finding out where the "next slice" is should be fast. See the getNextValue and getPreviousValue methods in ISeismicReader.

http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/seismic/ISeismicReader.html

7/ Arbitrary paths

Seismic volumes (ex: INLINE, XLINE) are expected to support arbitrary path queries. From an API point of view, these queries are SeismicPathQuery and SeismicDiscreteQuery. Seismic path queries interpolate between each point while discrete queries don't.

See the seismic path query class:

http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/query/SeismicPathQuery.html

See the seismic discrete query class:

http://intviewer.int.com/intviewer/docs/api/latest/com/interactive/intviewerapi/data/query/SeismicDiscreteQuery.html

8/ Quick XY search for 2D Lines

For synchronization between XSection and Map windows, it is useful to have a way to find the closest trace number to a region defined in X-Y coordinates.

Reversely, it is useful to have a way to find the X-Y coordinate associated with any trace number. It is normally taken care of by item F/ in the "meta data" section.

INTViewer has a private API to control this synchronization. By default, map and XSections don't synchronize for 2D lines.

9/ Multithreading

It is very common in INTViewer to access the same datasets from several threads. Code with this constraint in mind.

10/ File System

As your data grows, you'll need to use advanced file systems like Lustre for best performance. Consider using libraries like HDF5 for an easy compability with most advanced file systems.

Anti-patterns

Formats such as SEP take a simple approach to indexing. All samples are stored in a 3D matrix, with each sample at an "easy to calculate" file offset on disk. While this approach has many merits, the drawback is that is takes lots of space for sparse datasets.

Also, it doesn't allow a quick filtering of dead traces. Having to filter dead traces often requires reading all traces, which affects performance. The best approach is to design an index that ignores dead traces. Practically, no calls to ISeismicData.select(...) should return an ISeismicReader vending dead traces.

Don't assume that all seismic datasets are in Time. Some datasets are in Depth. The ISeismicData.getZUnit() method returns this sample unit.