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.
What you get for each type of data
Section titled “What you get for each type of data”| Type of data | What 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 file | the 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.
When a file is refused
Section titled “When a file is refused”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, notGrid-North, andEPSG:28992, notepsg: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.
An example tool
Section titled “An example tool”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, readersfrom ophiolite.writers import write_curves
@proceduredef 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:
ophiolite procedures run shale-volume --output out --input log=W-1.las --kind log=las2/1Technical details
Section titled “Technical details”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.
| Kind | Result |
|---|---|
points-csv/1 | Table |
mesh-text/1 | Mesh |
esri-ascii-grid/1 | Grid |
well-tops-csv/1 | Table |
deviation-csv/1 | Table |
opendtect-faultsticks/1 | Sticks |
las2/1 | Las |
well-location/1 | Location |
wavelet-text/1 | Wavelet |
model-section-text/1 | ModelSection |
seismic-section-text/1 | SeismicSection |
time-depth-csv/1 | Table |
A refusal is ophiolite.readers.ReadRefused, with code, field and row. A
well-residual/1 result is read with ophiolite.residuals, not with read().
