The coverage algorithm

Coverage of seismic objects

A coverage geometry is a geometry object (usually a polygon) which indicates where there is data in a given object. The Cognite Seismics service supports computing coverage geometries for surveys, files, seismicstores, and seismic objects. These geometries follow the relationship between the objects: Seismic coverages are subsets of the coverage for the seismicstore where the data is stored. Seismicstore coverage is the same as the coverage of the corresponding file. Survey coverage is the union of the coverages of all the seismicstores contained in the survey.

How to retrieve coverage

Coverage of files can be retrieved from seismicstore and seismic objects by specifying a coverage format to the ‘get’ or ‘search’ endpoints. For example, to fetch the coverage of a seismic object with id seismic_id in the wkt format using its native coordinate system (assuming an existing client):

import shapely.wkt
seismic = client.seisimcs.get(id=seismic_id, coverage_format="wkt")
coverage = shapely.wkt.loads(seismic.coverage.wkt)

Now, coverage contains the coverage geometry. For example, this can be plotted using matplotlib with code like

import matplotlib.pyplot as plt
# Plot the boundary
x, y = coverage.exterior.xy
plt.plot(x, y, '.-')
# Plot the holes
for hole in coverage.interiors:
    x, y = hole.xy
    plt.plot(x, y, '.-')
# This is not necessary on jupyter
plt.show()

Details on the coverage computation

File, seismicstore, and seismic object coverage is computed on an as-needed basis in the seismic service, by taking advantage of a structure similar to SeismicExtent describing all the traces contained in each object. The service distinguishes between 2D and 3D objects by looking at the dimensionality value passed to the SourceSegyFile when registering the file.

Simplification

Both 2D and 3D coverages are simplified to avoid returning overly large geometries. This uses the Ramer-Douglas-Peucker algorithm, which removes any points that deviate from a given line by more than a given tolerance. This means that the coverage geometry will only be accurate to this tolerance. In the 2D case, since we work directly with projected coordinates, we set the tolerance to fixed value of 12.5m. The 3D case is more tied to the specific workings of the 3D coverage algorithm (see below), but the resulting coverage should be accurate to within 0.25% of the linear size of the geometry.

2D Coverage algorithm

The simplest case is computing coverage of a 2D seismic object. Ordering the traces by CDP number, we expect the coordinates to form an unbroken line string. We collect all the coordinates of the traces, create a line string ordered by CDP number, and simplify.

3D Coverage algorithm

The 3D coverage algorithm works from a structure similar to Seismic3dDef, which maps each inline coordinate to a compact representation of all xlines corresponding to that inline (or vice versa, but we will assume the former in this description). A natural way to think about this map is as a collection of xline spans for each inline. Two spans at successive inline numbers should be joined together into a bigger shape whenever they overlap each other. For example, drawing spans as black lines, we might join a simple collection into a quadrilateral (dashed red line) like so:

How to join spans into polygons

However, in order to properly handle holes and concave boundaries, we need to consider that the xline spans can contain gaps, so more than one span can overlap any given span. Whenever this happens, the boundary lines need to split or join. For example, if the extent contains a simple hole, we would get:

Coverage with a hole

Building the boundary from the bottom upwards, we first encounter a simple overlap like before. But in the next step, there are two spans overlapping the previous one, so we create an internal boundary which joins the middle of the span to each of the new ones. After each of the new spans are overlapped by a single new one, we get a big span overlapping both. This causes the two ends of the internal boundary to meet, joining the hole together. Finally, we grow the external boundary by one more span, yielding a rectangle with a hole as the coverage geometry.

We can also start with multiple spans, expecting them to get merged together eventually. And some spans might have no overlaps. By considering these possibilities, we can build complicated geometries:

Coverage with overhangs

Here we start at the bottom with two separate spans, which we maintain as two pieces of the eventual boundary. After growing them a bit, we find that both are overlapped by a single span, so the two pieces get merged into a single piece. This piece continues for one step on the left side, but then a new span appears which does not overlap any span from the previous inline. This gets added as a new piece to keep track of. Finally, a new large span overlaps both the big piece and the new piece, so the two pieces are merged together again, yielding a nicely convex geometry with overhangs.

Finally, it is possible for distinct pieces to never merge, if there never appears a span that overlaps both pieces:

Coverage with distinct pieces

In such cases, the geometry will be returned as a MultiPolygon or GeometryCollection object. Single isolated bins will be rendered as Points.

Tuning parameters

From the above description, the 3D coverage algorithm needs to find the gaps between xline coordinates in order to identify holes and overhangs in the eventual geometry. However, whether a particular gap between xlines is in fact a gap can be subjective. For example, it is common for bin grids to be defined at every grid point, such that the extent contains a gap of 1 between each xline. The result would be a lot of tiny holes, which is not very useful as a coverage geometry.

From a more general perspective, a coverage geometry detailing every small hole in the grid is not that useful for visualization. We therefore set a threshold distance, such that any gap larger than the threshold is considered an actual gap. To account for the case where only every other (or every third, etc.) bin is present, we make sure this threshold is larger than the most common step size. Beyond that, we aim for a gap threshold of 0.5% the size of the geometry. Since the simplification tolerance is 0.25% the size of the geometry, this means that the smallest holes are not simplified away.

Note that this threshold for the gap between xlines is not reflected in the inline direction. Because of how the algorithm works, we consider an inline number to be adjacent to another if and only if there is no other inline number present between them. This can result in some asymmetry between the inline and xline directions, for example leading to long narrow holes in the coverage.