Skip to content

Read your tool's inputs

When Ophiolite runs a tool on your computer, it hands the tool’s entry function its input files. ophiolite.readers.read turns one of those files into plain Python values: numbers as numbers, a missing value as None, and the text you wrote kept as you wrote it. It reads a file the way the server reads it, so a file the server accepts reads here too, and a file the server refuses is refused here with the same sentence.

from ophiolite import readers
log = readers.read(inputs['log'][0])

Give read() one input as the run hands it over. You can also name a file and its type of data yourself: readers.read(path='tops.csv', kind='well-tops-csv/1'). Nothing is sent anywhere and nothing is repaired: you get the whole file, or a refusal that says what to change.

Type of dataWhat you get
Point set (CSV)the points, each with x, y, its z when given and every extra column you named
Triangulated surface (text)the corner points, their named values and the triangles that join them
Horizon grid (ESRI ASCII)the grid’s header and every cell, row by row from the north, with a missing cell as None
Well tops (CSV)the rows of the table, with every column you wrote
Deviation survey (CSV)the stations in depth order, with measured depth, inclination, azimuth and vertical depth when given
Fault sticks (OpendTect)every point with the number of its stick
LAS 2.0 well log filethe header sections, the curves with their units, the missing-value marker as written and every depth row
Well location (JSON)the position, its coordinate system and the depth reference
Wavelet (text)the header values and the samples
Rock model section (text)the section’s axes, the rocks with their speed and density, and the grid of rock numbers
Seismic section (text)the section’s axes, origin and polarity, and the grid of amplitudes
Time-depth table (CSV)the pairs of time and depth, in the order you wrote them

Every result also carries the declarations given with the file, exactly as given, and the same facts in the form the server keeps them.

read() raises ReadRefused with one sentence that names the problem and, where it can, the data row. Nothing was changed in your file. Correct the file and run again. The common refusals:

  • A row has more or fewer cells than the header. A trailing comma counts as an extra cell. Give each row one value per column.
  • The header does not name the columns the type needs, names one twice, or (for a deviation survey) names a column the type does not know. Use the column names from the table above.
  • A value is not a number, or is outside its range. Measured depth must increase down a survey; inclination is 0 to 180 degrees and azimuth 0 to 360.
  • A declaration is not one of the words the server accepts. For example grid-north, not Grid-North, and EPSG:28992, not epsg:28992.
  • The file has no data rows, or more than the server reads. A tops or survey file holds 1 to 10,000 rows; a grid holds at most 4,194,304 cells.
  • A grid header line is repeated or has more than one value, or the cell size is not positive.

The residual tool that ships with Ophiolite reads its tops, survey and grid this way too. Since this release it refuses the files above where it used to read them. A tops file with a header and no rows used to run and give each well a “no top” row; it is now refused.

This tool reads a well log, finds the gamma ray curve by its name and writes a shale-volume curve. A missing gamma ray value stays missing in the output.

"""Shale volume from gamma ray: read the log with ophiolite.readers, write a derived curve."""
from ophiolite import procedure, readers
from ophiolite.writers import write_curves
@procedure
def shale_volume(inputs, settings):
log = readers.read(inputs['log'][0])
names = [curve[0] for curve in log.curves]
depth = [row[0] for row in log.data]
gamma = [row[names.index('GR')] for row in log.data]
known = [value for value in gamma if value is not None]
low, high = min(known), max(known)
shale = [None if value is None else round((value - low) / (high - low), 4) for value in gamma]
return {'vsh': write_curves(depth, {'VSH': ('v/v', shale)}, depth_unit=log.curves[0][1], well='DERIVED')}

Save it as entry.py beside a procedure.json with one input slot log of type las2/1 and one output vsh, then run it on your computer:

Terminal window
ophiolite procedures run shale-volume --output out --input log=W-1.las --kind log=las2/1

read() returns one frozen result per shape of file. Mappings are read-only and sequences are tuples, so a result cannot be changed by accident. The source of truth is ophiolite.readers.MATRIX, which also lists each kind’s columns, declarations and the server reader it is compared with.

KindResult
points-csv/1Table
mesh-text/1Mesh
esri-ascii-grid/1Grid
well-tops-csv/1Table
deviation-csv/1Table
opendtect-faultsticks/1Sticks
las2/1Las
well-location/1Location
wavelet-text/1Wavelet
model-section-text/1ModelSection
seismic-section-text/1SeismicSection
time-depth-csv/1Table

A refusal is ophiolite.readers.ReadRefused, with code, field and row. A well-residual/1 result is read with ophiolite.residuals, not with read().