Skip to content

petekTools (Python)

The horizontal toolkit: gridding / kriging / SGS kernels, a units system, curated stats / sampling front-doors, synthetic generators, and the viewer unit.

import petektools as pt

At a glance

Group Names
Geometry Lattice, Georef
Gridding / geostat sgs, local_kriging_grid, resample, Variogram, experimental_variogram, ExperimentalVariogram
Sampling / RNG Sampler, Rng, ZoneSpec
Synthetic generators synth_dome_surface, synth_isochore, synth_trend_map, synth_facies_series, synth_log_series, synth_por_with_facies, synth_trajectory, synth_trajectory_profile, tops_from_surface, place_wells, place_wells_in_polygon, closure_outline, study_area_outline
Units km2_to_m2, m2_to_km2, m3_to_msm3, m3_to_bcm, m3_to_mcm, format_volume, …
Stats mean, median, percentile, std, variance, weighted_mean, weighted_percentile, reservoir_summary, aggregate
Viewer petektools.viewerserve, save_view, build_server

See the petekTools guide for a narrative tour and the geostat notebook.

API

petektools — standalone numerics & geostatistics kernels.

A thin Python surface over the Rust petektools library:

  • sampling — every Sampler variant (uniform / normal / lognormal / triangular / truncated-normal) plus the .clamped() combinator, drawn through a seeded Rng for bit-for-bit reproducibility with the Rust engine.
  • statsmean / variance / std / percentile (type-7, Excel PERCENTILE parity) / median and the weighted family.
  • realization-set helpersreservoir_summary (the P90=low digest) and aggregate (per-segment sum under a correlation assumption).
  • formulaformula_info and evaluate_formula for domain-free assignment expressions over named vectors and scalar $params.
  • geostatexperimental_variogram, Variogram (fit + params), local_kriging_grid and sgs over a regular Lattice.
  • interp1d — 1-D interpolation / log resampling kernels (linear / nearest / previous / next / natural cubic).
  • resample — grid → grid resampling of a native regular grid onto a foreign Lattice ("bilinear" / "nearest", null- and extent-aware).
  • units — the SI/metric reporting layer (m3_to_mcm / m3_to_msm3 / m3_to_bcm + inverses, scf / stbSm³, km2m2, format_volume).

Vector inputs accept a list or a numpy array (no numpy dependency); results are plain floats/lists. The P90 = low (petroleum exceedance) convention is documented on reservoir_summary / ReservoirSummary. See https://github.com/kkollsga/petektools.

aggregate builtin

aggregate(segments, correlation='independent')

Sum per-segment realization vectors index-wise into a field total under a dependence assumption. correlation is "independent" (sum as-is) or "comonotonic" (sort each segment ascending, then sum rank-for-rank — the fully-dependent low-together/high-together bound). The result length is the shortest segment's; an empty input (or any empty segment) gives [].

bcm_to_m3 builtin

bcm_to_m3(bcm)

bcm (billion Sm³) -> cubic metres (Sm³).

closure_outline builtin

closure_outline(surface, lattice, spill_depth)

The closing contour of surface (nested lists, ncol × nrow) on lattice at level spill_depth — the largest closed ring as [x, y] 2-lists (empty if the structure does not close at that level). Marching squares.

evaluate_formula builtin

evaluate_formula(assignments, properties, params=None)

Evaluate assignment strings over named equal-length property vectors.

$name tokens are scalar runtime parameters from params; bare symbols are property vectors or prior assignments in the same block. Scalars broadcast.

experimental_variogram builtin

experimental_variogram(coords, lag, n_lags)

Omnidirectional experimental variogram of coords ([x, y, z] rows, value in z): n_lags bins of width lag, empty bins dropped, each class reporting its mean pair separation. Errors on < 2 data or non-positive lag / zero n_lags. The O(n²) pairing runs with the GIL released.

format_volume builtin

format_volume(v_m3)

Format a volume in m³ with an SI report unit chosen by magnitude (bcm ≥ 1e9, mcm ≥ 1e6, else ), e.g. format_volume(12.4e6) == "12.4 mcm".

formula_info builtin

formula_info(assignments)

Inspect a formula block without evaluating it.

Returns sorted dependency lists under params and properties, plus output names in source order (outputs) and topological evaluation order (order).

interp1d builtin

interp1d(x, y, query, method='linear', extrapolate=False)

Interpolate a 1-D series at query positions.

x must be finite and strictly increasing, with the same length as y. Supported methods are "nearest"/"closest", "previous"/"ffill", "next"/"bfill", "linear", and "cubic"/"spline" (natural cubic). Out-of-bounds queries return NaN unless extrapolate=True.

km2_to_m2 builtin

km2_to_m2(km2)

Square kilometres -> square metres (areal report scale).

local_kriging_grid builtin

local_kriging_grid(
    coords, lattice, variogram, max_neighbours, radius
)

Moving-neighbourhood ordinary kriging of coords onto lattice with variogram, using up to max_neighbours data within radius per node. Returns (estimate, variance) — two ncol × nrow nested-list fields (field[col][row]); a node with no data in range is NaN in both. The solve runs with the GIL released. For the flat crossing see local_kriging_grid_flat.

local_kriging_grid_flat builtin

local_kriging_grid_flat(
    coords, lattice, variogram, max_neighbours, radius
)

Flat crossing of [local_kriging_grid]: returns (estimate_bytes, variance_bytes, (ncol, nrow)) — the two fields as single little-endian f64 bytes buffers (field[col][row]) instead of boxed nested lists. np.frombuffer(estimate_bytes, dtype='<f8').reshape(ncol, nrow).

m2_to_km2 builtin

m2_to_km2(m2)

Square metres -> square kilometres (areal report scale).

m3_to_bcm builtin

m3_to_bcm(m3)

Cubic metres (Sm³) -> bcm (billion Sm³) — gas reporting.

m3_to_mcm builtin

m3_to_mcm(m3)

Cubic metres -> mcm (million m³).

m3_to_msm3 builtin

m3_to_msm3(m3)

Cubic metres (Sm³) -> MSm³ (million Sm³) — oil reporting.

max_dogleg_severity builtin

max_dogleg_severity(md, incl, azim)

The maximum dogleg severity (degrees of hole-angle change per 30 m MD) of a survey given its columnar md / incl / azim lists (as returned by synth_trajectory_profile). 0 for a vertical well; the believability yardstick for a directional path. The three lists must be equal length.

mcm_to_m3 builtin

mcm_to_m3(mcm)

mcm (million m³) -> cubic metres.

mean builtin

mean(data)

Arithmetic mean of data. Errors on empty input.

median builtin

median(data)

The median (50th percentile) of data.

msm3_to_m3 builtin

msm3_to_m3(msm3)

MSm³ (million Sm³) -> cubic metres (Sm³).

ntg_curve builtin

ntg_curve(net_flag, depth_step, window_m)

A continuous NTG display curve from a derived net_flag (list of numbers, non-zero = net — accepts the 1.0/0.0 floats synth_petro_curves returns, or 1/0 ints): the centred running mean of the flag over a window_m-metre window (samples spaced depth_step m). Returns a [0,1] list aligned with net_flag.

percentile builtin

percentile(data, p)

The p-th percentile (p in [0, 100]), type-7 (Excel PERCENTILE parity): percentile([1, 2, 3, 4, 5], 25) == 2.0.

place_wells builtin

place_wells(xmin, ymin, xmax, ymax, n, seed)

Place n seeded uniform-random well heads inside the rectangular extent (xmin, ymin, xmax, ymax). Returns [x, y] 2-lists. Seeded/reproducible.

place_wells_in_polygon builtin

place_wells_in_polygon(polygon, n, seed)

Place n seeded uniform-random well heads inside polygon ([x, y] 2-lists, implicitly closed), by rejection sampling. Returns [x, y] 2-lists.

resample builtin

resample(src_grid, src_georef, target, method='bilinear')

Resample src_grid (values on src_georef) onto target's node lattice. src_grid is nested lists field[col][row] (ncol × nrow, NaN = undefined); method is "bilinear" (default) or "nearest". Returns the target.ncol × target.nrow field as nested lists (NaN outside the source extent or where the null policy propagates a hole).

resample_flat builtin

resample_flat(
    src_grid, src_georef, target, method="bilinear"
)

Flat crossing of [resample]: src_grid is a little-endian f64 bytes buffer (field[col][row], from np.ascontiguousarray(a, '<f8').tobytes()) matching src_georef; returns (field_bytes, (ncol, nrow)) for the target. Both crossings are one memcpy (no boxed nested lists / per-cell floats). np.frombuffer(field_bytes, dtype='<f8').reshape(ncol, nrow).

reservoir_summary builtin

reservoir_summary(data)

Summarise data (one realization per element) into a [ReservoirSummary] under the oil-industry P90 = low convention. Errors on empty input.

scf_to_sm3 builtin

scf_to_sm3(scf)

Standard cubic feet -> standard cubic metres (pure geometric factor).

sgs builtin

sgs(
    coords, lattice, variogram, max_neighbours, radius, seed
)

Sequential Gaussian simulation of coords onto lattice, conditioned exactly on the data, seeded (seed reproduces the field bit-for-bit). The variogram should be fitted on normal-score data (total sill ~1). Returns the ncol × nrow simulated field in data space as nested lists (field[col][row]). Errors on empty input or invalid neighbourhood params. The simulation runs with the GIL released. For the flat crossing see sgs_flat.

sgs_flat builtin

sgs_flat(
    coords, lattice, variogram, max_neighbours, radius, seed
)

Flat crossing of [sgs]: returns (field_bytes, (ncol, nrow)) — the simulated field as one little-endian f64 bytes buffer (field[col][row]) instead of a boxed nested list. np.frombuffer(field_bytes, dtype='<f8').reshape(ncol, nrow).

sm3_to_scf builtin

sm3_to_scf(sm3)

Standard cubic metres -> standard cubic feet (pure geometric factor).

sm3_to_stb builtin

sm3_to_stb(sm3)

Standard cubic metres -> stock-tank barrels.

stb_to_sm3 builtin

stb_to_sm3(stb)

Stock-tank barrels -> standard cubic metres.

std builtin

std(data)

Unbiased sample standard deviation (√variance).

study_area_outline builtin

study_area_outline(
    xmin, ymin, xmax, ymax, corner_radius, arc_steps
)

A rectangular (optionally corner-rounded) study-area outline for the extent (xmin, ymin, xmax, ymax): corner_radius ≤ 0 ⇒ sharp corners; else each corner is arc_steps segments. Returns a closed ring of [x, y] 2-lists.

synth_asset

synth_asset(
    root,
    *,
    seed=20260704,
    n_wells=8,
    ncol=NCOL,
    surfaces_as_points=False
)

Write the complete synthetic Petrel-export tree under root and return the planted-truth manifest. Deterministic per (seed, ncol, n_wells).

ncol sizes the square node lattice (default 41 = a 4 km study area, THE suite dataset); a smaller value yields a lighter tree for fast tests. The tree is asset v2: a mixed vertical/deviated well program, a tops-only split horizon, per-zone contacts (two-contact / single / contactless), a pinching zone, and a single world georef — see the module docstring.

surfaces_as_points=True emits each mapped horizon ONLY in the scattered point formats (IRAP classic points + EarthVision), skipping the pre-gridded IRAP / CPS-3 grid copies — so the loader classifies the horizons as point-sets and the framework routes them down petekStatic's from_scatter_stack conditioning path (HorizonSource::Scatter), exactly as the canonical real model does. The default (False, the pre-gridded Mapped escape hatch) is unchanged. This is the fixture the scatter-conditioning perf/dedup work (task_suite_scatter_perf) drives to exercise the expensive per-horizon bilinear solve on the synthetic asset.

synth_dome_surface builtin

synth_dome_surface(
    lattice,
    relief,
    aspect,
    tilt,
    noise_variance,
    noise_variogram,
    seed,
)

A synthetic dome structure on lattice: an elliptical four-way closure of amplitude relief, elongation aspect, a regional tilt, and correlated noise (noise_variance amplitude², continuity noise_variogram; variance 0 ⇒ none). Returns the ncol × nrow relief field (crest = max) as nested lists.

synth_dome_surface_flat builtin

synth_dome_surface_flat(
    lattice,
    relief,
    aspect,
    tilt,
    noise_variance,
    noise_variogram,
    seed,
)

Flat crossing of [synth_dome_surface]: (field_bytes, (ncol, nrow)) (little-endian f64, field[col][row]) instead of a boxed nested list.

synth_facies_series builtin

synth_facies_series(
    n, depth_step, ntg_target, bed_scale_m, seed
)

A binary sand/shale series of n samples at depth_step m, sand proportion = ntg_target, mean bed thickness ~ bed_scale_m. Returns a list of ints (1 = sand, 0 = shale). Seeded/reproducible.

synth_isochore builtin

synth_isochore(
    lattice, mean_thickness, variability, variogram, seed
)

A synthetic isochore (thickness map) on lattice: a correlated field about mean_thickness with std variability and continuity variogram, clamped at zero. Returns the ncol × nrow field as nested lists. Seeded/reproducible.

synth_isochore_flat builtin

synth_isochore_flat(
    lattice, mean_thickness, variability, variogram, seed
)

Flat crossing of [synth_isochore]: (field_bytes, (ncol, nrow)) (little-endian f64, field[col][row]) instead of a boxed nested list.

synth_log_series builtin

synth_log_series(zones, depth_step, transition_beds, seed)

One continuous, depth-autocorrelated log over the zones stack, sampled every depth_step m (top first). Each zone hits its {mean, std} in [0,1]; transition_beds blends the statistics across each internal boundary (0 = hard). Seeded/reproducible. Returns the series (a list of floats).

synth_petro_curves builtin

synth_petro_curves(zone, depth_step, n_samples, seed)

The coupled porosity + derived net-flag curve for one zone, n_samples samples spaced depth_step m (top first). The net flag is phie ≥ net_cutoff by construction; the generator solves a facies mixture so the realized series hits ntg_target and the net-rock moments (see PetroZoneSpec). Returns a dict {"phie": [float], "net_flag": [int] (1/0)}. Errors on an infeasible spec (with the achievable bound stated). Seeded/reproducible.

synth_por_with_facies builtin

synth_por_with_facies(
    facies,
    depth_step,
    sand_mean,
    sand_std,
    shale_mean,
    shale_std,
    corr_length_m,
    seed,
)

Porosity composed onto a facies series (list of ints, 1 = sand): each sample drawn from the sand/shale {mean, std} target per its facies, over a shared AR(1) driver of length = facies (correlation length corr_length_m). Returns a [0,1] porosity list aligned with facies. Seeded/reproducible.

synth_trajectory builtin

synth_trajectory(
    wellhead_xy, kb_elevation, td, md_step, seed
)

A vertical well trajectory from wellhead_xy ([x, y]), KB elevation kb_elevation (subsea +up), to TD td (TVD below KB), station spacing md_step m (final station lands on td). Returns a columnar dict of equal- length lists: md, x, y, z (elevation), tvd, incl, azim (vertical: MD==TVD, constant xy, incl=azim=0). seed is reserved for the deviated case. Seeded/reproducible.

synth_trajectory_profile builtin

synth_trajectory_profile(
    wellhead_xy,
    kb_elevation,
    td,
    md_step,
    seed,
    profile,
    kickoff_md=0.0,
    build_rate_deg_per_30m=3.0,
    hold_incl_deg=45.0,
    azimuth_deg=0.0,
    drop_start_md=None,
    drop_rate_deg_per_30m=3.0,
    final_incl_deg=0.0,
)

A directional well trajectory following profile from wellhead_xy ([x, y], world), KB elevation kb_elevation (subsea +up), to TD td (MD below KB), station spacing md_step m (final station lands on td).

profile is "vertical" | "build_hold" | "build_hold_drop": - build_hold — kick off at kickoff_md, build to hold_incl_deg at build_rate_deg_per_30m (believable ~1–4 °/30 m), hold on azimuth_deg. - build_hold_drop — as above, then from drop_start_md drop back toward final_incl_deg at drop_rate_deg_per_30m (an S-well).

Stations are placed by the minimum-curvature relation (this is trajectory synthesis, not survey interpretation). Use md_step ≈ 15–30 m for a deviated bore so it crosses many areal columns. Returns the same columnar dict as synth_trajectory (md/x/y/z/tvd/incl/azim). Deterministic; seed is reserved.

synth_trend_map builtin

synth_trend_map(
    lattice, variogram, seed, correlate_with=None
)

A depositional trend map on lattice: a correlated field mapped to [0,1] (Uniform marginal). With correlate_with = (field, rho) the trend is built to correlate with field (nested lists, ncol × nrow) at ~rho ∈ [-1,1]. Returns the ncol × nrow trend as nested lists. Seeded/reproducible.

synth_trend_map_flat builtin

synth_trend_map_flat(
    lattice, variogram, seed, correlate_with=None
)

Flat crossing of [synth_trend_map]: (field_bytes, (ncol, nrow)) (little-endian f64, field[col][row]) instead of a boxed nested list. correlate_with (if given) is still a nested list (rare path).

tops_from_surface builtin

tops_from_surface(
    surface, lattice, well_xy, residual, seed
)

Pick a top from surface (nested lists, ncol × nrow) on lattice at each well in well_xy ([x, y] 2-lists), adding one residual draw per well (a Sampler, e.g. Sampler.uniform(-10, 10)). A well outside the extent → NaN. Returns one top per well. Seeded/reproducible.

variance builtin

variance(data)

Unbiased sample variance (n − 1 denominator). A single value yields 0.0.

view2d

view2d(
    items,
    *,
    title="2D view",
    color=True,
    fill=False,
    contours=None,
    save=None,
    port=0,
    block=False,
    open_browser=True,
    max_grid_lines=800,
    max_line_points=1000,
    point_limit=200000,
    max_mesh_edges=150000,
    lod=True,
    encoding="blocks",
    block_threshold_bytes=_blocks.DEFAULT_THRESHOLD_BYTES
)

Open or save a generic 2-D map view.

color= colours points (and picks the colormap + clamp range through the "[<attr>_]<cmap>[_<min>_<max>]" spec grammar); fill= opts items into value-coloured fills; contours= opts them into contour lines (see :func:view2d_payload for the full grammar and duck-typed conventions). Returns the local server URL in live mode, the written path when save= is supplied, or the payload when open_browser=False and block=False is still served by the caller through view2d_payload directly.

view2d_payload

view2d_payload(
    items,
    *,
    title="2D view",
    color=True,
    fill=False,
    contours=None,
    max_grid_lines=800,
    max_line_points=1000,
    point_limit=200000,
    max_mesh_edges=150000,
    lod=True,
    encoding="blocks",
    block_threshold_bytes=_blocks.DEFAULT_THRESHOLD_BYTES
)

Build a generic 2-D map payload from points, geometries, and outlines.

items is normally a list such as [points, geometry]. The accepted object conventions are intentionally tiny:

  • points: xyz()/xy() or a sequence of [x, y]/[x, y, z] rows
  • geometry: node_xy(i, j), ncol, nrow and optional edge
  • trimesh: triangles() index triples over xyz()/points() vertices, with optional edge — the unique triangle edges render as grid lines; an optional wireframe_edges() (index pairs) overrides the drawn edge set, e.g. a quad-dominant wireframe with cell diagonals removed
  • outline: rings() returning rings of [x, y] or [x, y, z] rows
  • value fill (opt-in via fill=): value_layer(attr=None) returning {"name", "nodes", "triangles", "values", "range"} — a per-node value-coloured trimesh rendered UNDER the grid lines
  • contour lines (opt-in via contours=): iso_lines(interval=..., levels=..., attr=None) returning [(level, [polyline, ...]), ...]
  • structured surface (value-bearing, e.g. petekio's regular Surface): an item offering value_layer() (typically with a 2-D .geometry) that matches no convention above renders its STRUCTURE when passed bare — the .geometry lattice lines (clipped to edge), or, geometry-less, its primary value layer's unique triangle edges. Values never colour anything without an explicit fill=

color= colours POINTS (and selects the colormap for whatever is value-coloured); it never triggers fills. It defaults ON — pass color=False for monochrome points. fill= opts items into value fills (value_layer()); contours keep their own contours= parameter. Both accept bool or a string spec parsed by REGISTRY MATCH: the string splits on "_"; if a token matches a known colormap name (viridis / magma / grays / inferno), everything before it is the attribute (may itself contain underscores), and up to two trailing float tokens (negative numbers included) are the explicit [min, max] range. A string with no colormap token stays an ATTRIBUTE name (back-compat). Examples::

color=True                        # the default: points by z, data range
color=False                       # monochrome points
color="inferno"                   # + the inferno colormap
color="inferno_-2700_-2500"       # + an explicit clamp range
color="porosity"                  # attribute (forwards to iso_lines)
color="porosity_inferno_0_0.3"    # attribute + colormap + range
fill="phi"                        # value_layer(attr="phi") fills

A malformed spec (e.g. a colormap with a single trailing float, or non-float range tokens) raises ValueError.

With color on, plain points carrying a finite third component are colour-coded by it; map.point_color records the range — the explicit spec range when given (out-of-range values clamp to the ends), else the data z range. The parsed colormap travels as map.colormap (color's wins over fill's), and an explicit fill range overrides each fill entry's producer range. fill=True asks every item offering value_layer() for its primary layer; a string spec's attribute asks for that attribute. contours=<float> requests iso_lines(interval=...); a list requests iso_lines(levels=...); the color spec's attribute (if any) is forwarded as attr=. Items without these methods are unaffected, and an item that yields a fill still contributes its geometry/trimesh lines exactly as before.

Every emitted layer records a legend display name, duck-typed from the source object's optional name attribute (map.layers carries {"kind": "points"|"lines"|"contours", "name": str | None} entries; fills carry display_name); the viewer falls back to the layer kind.

Point objects are rendered as points only. Topology-bearing point sets do not imply grid-line rendering; pass a geometry, structured surface, or trimesh when the grid itself should be visible.

lod controls the display-only stride-ladder LOD: when on (default), every item whose producer duck accepts the striding kwargs emits BOTH a full-resolution ring and ONE coarse ring, so the viewer can drop to the coarse ring when a data cell shrinks below a few screen pixels (geometry truth is never decimated — the coarse ring is additive display data). The coarse ring is requested from the producer: value_layer(stride=...) for a fill (fills[i]["lod"] = {stride, nodes, triangles, values, range} — the range is the FULL-resolution range so colours stay stable across rings), wireframe_edges(stride=...) for mesh grid lines (map["grid_lines_lod"]), and iso_lines(..., simplify=tol) for contours (contours[i]["lines_lod"]). lod=True uses stride=4 and derives the contour simplify tolerance from the contour extent (extent / 512 ≈ two coarse-ring pixels); lod=(stride,) or lod=(stride, simplify) overrides those; lod=False emits no coarse ring (a payload byte-identical to the pre-LOD shape). A producer method that does not accept the striding kwarg is feature-detected (TypeError) and degrades silently to no coarse ring for that item — all LOD fields are additive and every one is block-encoded like its full ring.

encoding controls how the bulk arrays travel. "blocks" (default) encodes points, each fill's nodes/triangles/values, grid_lines and contours[i].lines as content-addressed typed binary blocks (the v3 wire format; see SCHEMA.md / :mod:_blocks) with a per-payload map["blocks"] digest table that ships each identical array once — the viewer decodes them off the main thread into typed arrays. A payload whose bulk arrays total under block_threshold_bytes (~64 KB of floats) stays plain JSON regardless. encoding="json" forces the plain (pre-blocks) shape; the viewer renders either.

view3d

view3d(
    items,
    *,
    title="3D view",
    color=True,
    fill=False,
    contours=None,
    save=None,
    port=0,
    block=False,
    open_browser=True,
    max_grid_lines=800,
    max_line_points=1000,
    point_limit=200000,
    z_exaggeration=5.0
)

Open or save a generic 3-D scene view (the viewer's 3D tab).

Same duck-typed item handling and color= / fill= / contours= semantics as :func:~petektools.viewer.view2d — see :func:view3d_payload for the full grammar and conventions. Returns the local server URL in live mode, or the written path when save= is supplied.

view3d_payload

view3d_payload(
    items,
    *,
    title="3D view",
    color=True,
    fill=False,
    contours=None,
    max_grid_lines=800,
    max_line_points=1000,
    point_limit=200000,
    z_exaggeration=5.0
)

Build a generic 3-D scene payload from the view2d item conventions.

items is normally a list such as [points, geometry]. Accepted duck types (identical to :func:~petektools.viewer.view2d_payload, plus wells):

  • points: xyz()/xy() or a sequence of [x, y, z?] rows — a colour-coded 3-D point cloud (compact base64 f32 block on the wire)
  • geometry: node_xy(i, j), ncol, nrow, optional edge — the lattice lines render as a flat grid at the scene's reference elevation (scene3d.ref_z, the midpoint of the scene's z extent; geometries carry no z of their own), clipped to edge exactly as in 2-D
  • trimesh: triangles() over xyz()/points() vertices — a 3-D surface mesh; neutral-shaded (with a wireframe toggle) unless fill= opts it into value colouring
  • value fill (opt-in via fill=): value_layer(attr=None) — the returned {"name", "nodes", "triangles", "values", "range"} layer IS the surface: it renders once, value-coloured. A node row may carry [x, y, z]; a 2-D [x, y] node takes its elevation from the layer's value when the PRIMARY layer was requested (fill=True / a pure-colormap spec — a surface's primary value layer is its elevation), and otherwise renders gapped (an attribute fill needs z-bearing nodes to be a 3-D shape)
  • contour lines (opt-in via contours=): iso_lines(interval=..., levels=..., attr=None) — each polyline renders at z = level (elevation iso-lines; an attribute-valued contour level is drawn at its level value on the z axis)
  • well: trajectory() (or attribute) returning [x, y, z] rows with z ELEVATION (negative down) — a 3-D bore path with a wellhead marker, identity-coloured; optional id/name labels it
  • outline: rings() of [x, y] rows — flat rings at ref_z
  • structured surface passed BARE (value-bearing, e.g. petekio's regular Surfacevalue_layer() + a 2-D .geometry, no top-level trimesh/geometry ducks): renders its STRUCTURE as a NEUTRAL elevation mesh from the primary value layer (value-as-elevation; values stay null → neutral shading + the wireframe toggle — never value-coloured without fill=); an item with only a 2-D .geometry falls back to lattice lines at ref_z

color= / fill= / contours= keep their exact view2d semantics and grammar: color= colours POINTS by z (default ON; color=False for monochrome) and selects the colormap for whatever is value-coloured; it never triggers fills. fill= opts items into value-coloured surfaces. Both accept bool or the registry-match spec "[<attr>_]<cmap>[_<min>_<max>]" (viridis / magma / grays / inferno; negative range floats fine — "inferno_-2700_-2500"); a string with no colormap token stays an attribute name; a malformed spec raises ValueError. An explicit range clamps the normalization (values outside it render at the ramp ends).

Point clouds cap at point_limit (default 200k) by striding, exactly like view2d (summary.point_stride). z_exaggeration seeds the 3D tab's z-exaggeration slider (display-only scale, badge + true-depth readouts — the same control the volume tab has; default 5x).

Every emitted layer records a legend display name duck-typed from the item's optional name attribute (scene3d.layers carries {"kind": "points"|"lines"|"contours"|"wells", "name": str | None}; value meshes self-describe via display_name, like 2-D fills).

weighted_mean builtin

weighted_mean(values, weights)

Weighted arithmetic mean of values under weights (equal length, non-negative weights summing > 0).

weighted_percentile builtin

weighted_percentile(values, weights, p)

Weighted p-th percentile (p in [0, 100]), consistent with the unweighted type-7 definition on equal weights.

weighted_std builtin

weighted_std(values, weights)

Weighted sample standard deviation (√weighted_variance).

weighted_variance builtin

weighted_variance(values, weights)

Weighted (reliability-weighted, unbiased) sample variance.

write_cps3_grid

write_cps3_grid(path, field, lattice, *, negate=False)

Write one CPS-3 ASCII grid over lattice.

write_cps3_lines

write_cps3_lines(path, rings)

Write one CPS-3 line-set polygon file.

write_earthvision_grid

write_earthvision_grid(
    path, field, lattice, *, negate=True
)

Write one EarthVision-style point grid over lattice.

write_irap_grid

write_irap_grid(path, field, lattice, *, negate=False)

Write one IRAP classic grid over lattice.

field is shaped field[col][row] and negate=True writes positive-down depth as negative-down elevation, matching petekIO's surface loaders.

write_irap_points

write_irap_points(path, field, lattice, *, negate=True)

Write one IRAP classic point cloud over lattice.

write_las2

write_las2(path, well, md, por, ntg, sw)

Write one LAS 2.0 comp-log with the suite synthetic curve mnemonics.

write_petrel_tops

write_petrel_tops(
    path,
    horizon_picks,
    contact_rows=None,
    latin1_row="Décor",
)

Write one Petrel well-tops file.

write_wellpath

write_wellpath(path, trajectory, kb)

Write one Petrel-style positioned wellpath file.

zone_sample_counts builtin

zone_sample_counts(zones, depth_step)

Per-zone depth-sample counts of the zones stack at depth_step — the shared depth layout of a stack's logs.