Wellbore Genius
Help

Downhole Performance · CSV schema

A short reference for the depth-profile CSV produced by the Export CSV button on the Downhole results view.

1. Data columns: canonical Field units

Every numeric column in the CSV is emitted in canonical Field units — depth in ft, pressure in psi, temperature in °F — regardless of the per-chart unit toggles (Auto / Field / SI) selected in the UI.

This keeps the schema stable so spreadsheets, pandas pipelines, and downstream tools can rely on a single, well-defined column shape:

depth [ft],hydrostatic [psi],wellbore_pressure [psi],geothermal_temperature [°F],flowing_temperature [°F]

The unit is restated in [brackets] on every column header per project convention.

2. Per-chart unit metadata

The pressure-vs-depth and temperature-vs-depth charts each carry an independent unit override (Auto / Field / SI). To preserve what the user saw at export time, the CSV records the resolved selection in the metadata header above the data:

# Pressure chart units: [AUTO → SI] SI (kPa, m, °C) · y-axis "Pressure [kPa]"
# Temperature chart units: [FIELD] Field (psi, ft, °F) · y-axis "Temperature [°F]"

Read the bracketed tag as the toggle state. AUTO → SI means the chart was on Auto and resolved to SI through the global unit toggle; FIELD means the chart was explicitly locked to Field.

The table below shows how each toggle resolves per quantity. Data columns are always emitted in the canonical Field column regardless of the chart toggle — only the chart axis, tooltip, and the shown as … suffix on *_ref_* columns change.

QuantityCanonical (data column)Auto → FieldAuto → SIField (locked)SI (locked)
Pressurepsi8,000 psi →8,000 psi8,000 psi →55,158 kPa8,000 psi55,158 kPa
Depthft10,000 ft →10,000 ft10,000 ft →3,048 m10,000 ft3,048 m
Temperature°F212 °F →212.0 °F212 °F →100.0 °C212.0 °F100.0 °C

Conversions: kPa = psi × 6.894757, m = ft × 0.3048, °C = (°F − 32) × 5⁄9. Auto resolves through the app-wide unit toggle, so the same export can record AUTO → FIELD for one user and AUTO → SI for another.

3. Reference lines & scenario targets

Overlays such as BHP target, BHP min, and BHP max are recorded in two places so downstream tools can choose either representation:

  • Metadata header — one line per overlay with both the canonical Field value and the chart-formatted display value:
    # Pressure chart reference lines (display in chart units):
    #   - BHP target: 8000.00 psi (canonical) · 55,158 kPa (as shown)
  • Appended columns — one constant column per overlay, named <chart>_ref_<slug> with a bracket suffix that encodes both the canonical unit and the chart-selected display formatting:
    pressure_ref_bhp_target [psi | shown as 55,158 kPa]
    The numeric values in these columns are always canonical Field — the display formatting is preserved in the header label only.

Currently exported BHP columns

The Downhole results view emits exactly three pressure-chart reference overlays — the BHP target and the BHP min/max range. Each one becomes a single constant column appended after the canonical schema. Slugs come from the UI label via label.toLowerCase().replace(/[^a-z0-9]+/g, "_"), so the set is fixed:

UI overlayColumn name (row 1)Unit cell (row 2)Legacy name [unit] header
BHP targetpressure_ref_bhp_targetpsi | shown as 8,000 psipressure_ref_bhp_target [psi | shown as 8,000 psi]
BHP minpressure_ref_bhp_minpsi | shown as 6,500 psipressure_ref_bhp_min [psi | shown as 6,500 psi]
BHP maxpressure_ref_bhp_maxpsi | shown as 9,500 psipressure_ref_bhp_max [psi | shown as 9,500 psi]

The shown as … suffix mirrors the pressure chart's unit toggle at export time — the same overlay reads psi | shown as 8,000 psi when the chart is on Field and psi | shown as 55,158 kPa when it resolved to SI. The data value in the column body is always the canonical Field number (psi). If the BHP target/min/max inputs are blank or the pressure chart has no overlays, the corresponding columns are omitted entirely — they never appear as empty placeholders.

Two-row header structure for BHP columns

Each BHP overlay column occupies the same column index across two consecutive header rows. Row 1 carries the machine-readable column name; row 2 carries the unit cell, which encodes both the canonical unit and the chart's display formatting at export time. Pivot the column index, not the row order, when parsing — the data rows that follow line up under row 1.

RowPurposepressure_ref_bhp_targetpressure_ref_bhp_minpressure_ref_bhp_max
Row 1Column name (label)pressure_ref_bhp_targetpressure_ref_bhp_minpressure_ref_bhp_max
Row 2Unit cell · <canonical> | shown as <display>psi | shown as 8,000 psipsi | shown as 6,500 psipsi | shown as 9,500 psi
  • Row 1 is the only row downstream tools should key on for column lookup — it never changes with the unit toggle.
  • Row 2 is informational. The substring before | is the canonical unit (always psi for BHP); the substring after shown as is the chart-formatted display (e.g. 55,158 kPa when the pressure toggle resolved to SI).
  • If a row-2 cell contains a comma (it always does for BHP because of the thousands separator), the cell is CSV-quoted — "psi | shown as 8,000 psi" — so a standards-compliant CSV parser is required.

Export preview

Toggle the pressure chart's unit selection below to see the exact metadata line and the two header rows the exporter writes. The BHP overlay cells in row 2 update live; everything else stays canonical.

Export preview · pressure chart toggle
Metadata line
# Pressure chart units: [Auto → FIELD] Field (psi, ft, °F) · y-axis "Pressure [psi]"
Header row 1 (column names)
depth,hydrostatic,wellbore_pressure,geothermal_temperature,flowing_temperature,pressure_ref_bhp_target,pressure_ref_bhp_min,pressure_ref_bhp_max
Header row 2 (units · BHP cells reflect toggle)
ft,psi,psi,°F,°F,"psi | shown as 8,000 psi","psi | shown as 6,500 psi","psi | shown as 9,500 psi"

Only the trailing pressure_ref_bhp_* unit cells change with the toggle — the canonical column names and base units stay constant. Data values in those columns are always canonical psi regardless of which toggle was active.

4. Importer guarantees

The bundled CSV validator (drop-zone on the Downhole results view) accepts any file whose column header begins with the canonical schema and whose extra columns match (pressure|temperature)_ref_<slug> [...]. It also checks that every Auto → … tag resolves to the same system the y-axis label declares, so a CSV exported from one unit-toggle configuration and re-imported under another will be flagged with a clear error code.

5. Validation checklist

The drop-zone validator on the Downhole results view runs each of these checks in order and surfaces a stable code per issue so downstream tooling can branch on the failure type without string-matching the human message.

LevelCodeWhat it checksExample failure
warningmissing-titleThe first comment line is "# Downhole Performance — depth profile".Title line was hand-stripped from the file.
warningmissing-generatedA `# Generated: <ISO timestamp>` line is present.Re-saved by a tool that dropped the timestamp.
errormissing-schema-versionA `# Schema version: <MAJOR.MINOR.PATCH>` line is present (currently `1.0.0`). Files without one are treated as legacy / pre-1.0 and rejected.An older export (or hand-edited file) is loaded that was saved before schema versioning was introduced.
errorbad-schema-version-formatThe schema-version value parses as `MAJOR.MINOR.PATCH`.Someone wrote `# Schema version: v1` or `# Schema version: 1.0`.
errorincompatible-schema-versionThe file's MAJOR matches the importer's supported MAJOR. Newer MINOR versions warn but still import.A future build emits `2.0.0` after a breaking metadata-block change; this importer refuses it.
errormissing-data-units-lineA `# Data columns: canonical Field units (psi, ft, °F)` declaration is present so readers know the data is canonical Field.Without it, downstream tools could mis-interpret SI-rendered overlays as the data unit system.
errormissing-pressure-chart-lineA `# Pressure chart units: …` line is present.Pressure chart metadata block was deleted.
errormissing-temperature-chart-lineA `# Temperature chart units: …` line is present.Temperature chart metadata block was deleted.
errorbad-chart-tag-formatThe chart unit line matches `[<TAG>] <label> · y-axis "<axisLabel>"`.Hand-edit broke the bracket tag, e.g. `Pressure chart units: SI · y-axis Pressure`.
errorbad-resolved-systemThe bracket tag resolves to either FIELD or SI (Auto must arrow to one).`[Auto → ?]` or `[METRIC]` instead of `[FIELD]` / `[SI]`.
errorlabel-system-mismatchThe human label after the tag mentions the resolved system.`[SI] Field (psi, ft, °F) · y-axis "Pressure [kPa]"`.
erroraxis-unit-mismatchThe y-axis label uses the unit suffix expected for the resolved system (`[psi]`/`[kPa]` for pressure, `[°F]`/`[°C]` for temperature).`[Auto → SI] … · y-axis "Pressure [psi]"` (should be kPa).
errormissing-column-headerAt least one non-comment, non-blank line exists after the metadata block (the names row).File ends right after the metadata header, no data block.
errormissing-units-rowA second header row (bare unit abbreviations) follows the names row.Excel-friendly two-row header was collapsed back to a single `name [unit]` row.
errorcolumn-header-mismatchThe reconstructed name [unit] header begins with the canonical Field schema, and any extra columns match (pressure|temperature)_ref_<slug> [...].A column was renamed (e.g. `wellbore [psi]` instead of `wellbore_pressure [psi]`) or an unrelated extra column was appended.

A file is reported as ok: true only when every error-level check passes. Warnings never block import — they're surfaced so you can still spot non-fatal drift (e.g. a hand-stripped title).

6. Sample CSV

A real export — produced by the same buildDownholeProfileCsv code path the app uses — is bundled with the site so you can verify your parser against the documented schema. It includes three pressure overlays (BHP target, BHP min, BHP max), an Auto → SI pressure chart selection, and an explicit Field temperature chart selection.

Stable schema: column shape and metadata layout match the format described in sections 1–5. Re-running the export only refreshes the # Generated: timestamp.