Skip to content

A spreadsheet becomes wells and tops

A table you already have (a CSV file or an Excel workbook) becomes typed project data in one journey: you say what the table holds and which column holds each value, review what will be added, and confirm. Nothing is added before you confirm, and a table added twice is not added twice.

A table can hold one of five things:

It holdsOne row isNeeds at least
Wellsa well, with its positionidentifier, name, X, Y and their coordinate system
Well topsa named depth along a wellthe well, the name of the top, its measured depth
Deviation surveysa station along a wellthe well, measured depth, inclination, azimuth
Pointsa point with numeric attributesX, Y and their coordinate system
Time-depth pairsa depth and its travel time in one wellthe well, depth, time

A table that names several wells becomes one set per well: a tops table of two wells adds two sets of tops, each linked to the well of the project that has that name. A set whose well is not found is still added, without a link, and the result says so. Adding wells needs a project administrator; the other kinds need a contributor.

  1. Drop the file on Add data (or choose it). A table shows as “This looks like a table” with its rows and columns, and Needs your decision: say what this table holds. Choose Say what it holds.
  2. Check how it is read. The strip names the sheet, the header row and the separators; choose Change beside one that is wrong (a workbook whose first rows are a title has its header further down) and Read again.
  3. Choose what the table holds. A table whose header is Ophiolite’s standard layout for one kind has that kind and its columns chosen already, marked Matches Ophiolite’s standard layout.
  4. Map the columns: say which column holds each value. A column whose name fits is offered as Use column and marked Guessed from the column names. Check it.; nothing is chosen for you. Say the unit, coordinate system or depth reference the table does not state. Each problem is named beside the value it concerns.
  5. Choose Review the import. The review counts the sets to add and those already here, lists every row that will be skipped with its row number and reason (“Row 3, Measured depth: “17x9.0” is not a number.”), names the wells found and not found, and says how many of the project’s uploads it uses.
  6. Choose who else sees the sets, then Confirm and import. The progress names the set being added; Pause stops after the current set and Continue goes on. Cancel import asks first and keeps what was added.
  7. The result has one line per set: “Added: 24 tops, linked to well HON-GT-01”, “Already here”, or why it was not added.

Adding the same table again finds every set Already here and adds nothing.

Bring your tables. The examples use NLOG’s Groningen well headers and the formation tops of two geothermal wells (public data from NLOG.NL, the Dutch subsurface portal):

wells_table = "wells-groningen.csv" # BOREHOLE_CODE, BOREHOLE_NAME, X, Y, CURRENT_OWNER, END_DEPTH_MAH, REFERENCE_LEVEL
tops_table = "nlog-tops.xlsx" # a title, a source line, then Well, Formation, Top MD (m), Source

Review the wells first. A dry run reads the table on the server and adds nothing; it says what would be added in the same words as Workspace. The columns map each value to a column of the table, and declarations say what the table does not (here the coordinate system of X and Y and how the depths were measured). authority names the register the identifiers come from, so a well already added from it is recognised:

from ophiolite.imports import result_lines, review_lines
columns = {"id": "BOREHOLE_CODE", "name": "BOREHOLE_NAME", "x": "X", "y": "Y", "depth": "END_DEPTH_MAH", "operator": "CURRENT_OWNER"}
declared = {"crs": "EPSG:28992", "depth_unit": "m", "depth_kind": "MD", "depth_reference": "KB"}
review = client.imports.from_table(wells_table, "wells", columns, declarations=declared, authority="nlog", dry_run=True)
print("\n".join(review_lines(review["preview"])))

Add them. on_start gets the import’s id before its first step: an interrupted import is continued from any process with client.imports.run(id), and nothing is added twice:

wells = client.imports.from_table(wells_table, "wells", columns, declarations=declared, authority="nlog",
on_start=lambda started: print("Import", started["id"], "started"))
print("\n".join(result_lines(wells["run"], wells["preview"])))

Then the tops. The workbook’s title rows are found and skipped; each well in the table becomes one set of tops, linked to the project’s wellbore of that name when there is exactly one. In the example project HON-GT-01 is a wellbore and NLW-GT-01 is not, so the second set is added without a link:

tops = client.imports.from_table(tops_table, "well-tops", {"well": "Well", "name": "Formation", "md": "Top MD (m)"},
declarations={"depth_unit": "m"})
for line in result_lines(tops["run"], tops["preview"]):
print(line)

Each set is ordinary project data. Read one back exactly as it was added:

first = tops["run"]["units"][0]
read = client.read_data(first["asset_id"], first["revision"])
print(len(read.tops), "tops, the first", read.tops[0]["name"], "at", read.tops[0]["md"], "m")

A refusal is raised with the sentence Workspace shows (“Choose the column that holds the measured depth.”, “Only a project administrator can add wells from a table. Ask one to do it.”); the service’s own text is kept as server_message.

Terminal window
ophiolite import table nlog-tops.xlsx --target well-tops --map "well=Well,name=Formation,md=Top MD (m)" --declare depth_unit=m --dry-run
ophiolite import table nlog-tops.xlsx --target well-tops --map "well=Well,name=Formation,md=Top MD (m)" --declare depth_unit=m
ophiolite import table wells-groningen.csv --target wells --map id=BOREHOLE_CODE,name=BOREHOLE_NAME,x=X,y=Y --authority nlog \
--declare crs=EPSG:28992 --declare depth_unit=m --declare depth_kind=MD --declare depth_reference=KB
ophiolite import list
ophiolite import resume ID

--dry-run prints the review and adds nothing. A run prints its id before its first step (“If it stops, continue with: ophiolite import resume ID”) and one line per set at the end. --sheet, --header-row, --delimiter, --decimal-mark and --encoding say how to read a table when the first reading is wrong. A paused import exits with code 4 and says who paused it; pause, resume, cancel and status take the import’s id. --json prints the service’s answers.

You seeWhat to do
Ophiolite could not read this file as a table. Ask whoever sent it for a CSV or Excel file.Save it again as CSV or as an Excel workbook (.xlsx).
Choose the column that holds …Map that value to a column, then review again.
Only contributors can add this. Ask the project owner for access.Ask the project owner for the contributor role.
Only a project administrator can add wells from a table. Ask one to do it.Ask an administrator, or add the table as another kind.
This import changed since you reviewed it. Review it again.Review again; someone changed the project in between.
This would add N sets but this project has room for M more. …Remove sets you no longer need, or ask your project administrator.
Another import is still running in this project. Wait for it to finish or stop it.ophiolite import list names it.

Wells appear in the Wells list and on the map; tops, surveys and time-depth pairs appear on the wellbores they are linked to. A set links to a wellbore found by its name or by the name of its well. A well added from a table has no wellbore yet, so a set that names it is added with ”… has no wellbore yet, so these are not linked yet.” A notebook that makes a small tops table and adds it is in the notebook gallery.