petekSim (Python)¶
The product façade — the v2 declarative spec API and the whole stack behind one import.
At a glance¶
| Group | Names |
|---|---|
| Synthetic data | synth_asset |
| Structure specs | Horizons, hz, Subzones, splits, Layering, Contacts, zone |
| Settings | TieSettings, Gridding, decay_to_flat, flat, nearest, Run, ViewSettings |
| Property specs | Props, Prop, Propagate, variogram, collocated |
| Uncertainty | Mc, McSettings, shift, dist, aggregate, distribution_bundle |
| Charts | Distribution, Tornado |
| Scenarios | AssetSpec, spec_from_dict, registered_specs |
| Apply results | Model, StaticModel, Uncertainty, ZonedUncertainty |
| Analytic box | run_box_model |
| Errors | NotYetSupported, ApplyError |
See the petekSim guide, the flagship tutorial, and the full-workflow notebook.
Note
Project loading is owned by petekio, and static model construction is owned
by petekstatic; peteksim no longer exposes Project or LoadSettings.
API¶
petekSim — fast field/discovery appraisal toolkit (Rust core, Python API).
Code-first: build a model in Python, then model.view() pops open a three.js
render of it in your browser. The compute lives in the Rust extension
(peteksim._core); the renderer is petekTools' horizontal petektools.viewer
unit (owner ruling), which this package feeds a render payload and a live-section
callback.
import peteksim
m = peteksim.run_box_model(area_km2=(0.32, 0.4, 0.52), gross_height_m=(12, 15, 20),
porosity=0.25, net_to_gross=0.8, water_saturation=0.3,
fvf=1.25, fluid="oil", contact_m=2743)
m.view() # opens the 3D viewer in a browser
sm = peteksim.Model(0.4, 15.0, ni=24, nj=24, nk=8,
top_m=1500, contact_m=1510.5)
sm.add_control(12, 12, 1489) # a structural high, in code
sm.view() # build + view
All inputs are SI/metric (area km², lengths/depths m positive-down, FVF Rm³/Sm³); results in Sm³ (GRV in mcm = 10⁶ m³).
ApplyError ¶
Bases: ValueError
A spec could not be resolved against the project at apply time (a missing name, an illegal combination). The message names BOTH the project object and the spec entry.
AssetSpec
dataclass
¶
AssetSpec(
name="",
horizons=None,
subzones=None,
layering=None,
contacts=None,
ties=None,
gridding=None,
props=None,
mc=None,
run=None,
view=None,
)
Bases: Spec
A whole modelling scenario as one value — the durable, re-applicable
descriptor (asset.to_dict() is a savable scenario file). Every field is a
spec, so the round-trip is total.
CollocatedTrend
dataclass
¶
Bases: Spec
A collocated-cokriging trend that holds the steering surface's NAME
(ps.collocated("depo_trend", corr=0.6)), resolved against the project at
apply. as_depth=False reads the surface as a trend in its own units;
True flips a structural elevation to positive-down depth.
Extrapolation
dataclass
¶
Bases: Spec
A gridding extrapolation policy — build with ps.decay_to_flat(range_m),
ps.flat(), or ps.nearest(). Mirrors petekStatic's ExtrapolationPolicy;
honoured once the structure-investigation gridding branch wires SolveOpts.
McSettings
dataclass
¶
Bases: Spec
MC run settings (ps.McSettings(lo_pct=10, hi_pct=90, workers=4)) — the
percentile band + realize-loop sharding. Mirrors petekStatic's McSettings.
NotYetSupported ¶
Bases: NotImplementedError
A spec field is valid and serializes, but the engine capability that would honour it has not landed yet. Raised LOUDLY at apply time, naming the task that carries the capability — never a silent no-op.
Propagate
dataclass
¶
Propagate(
variogram=Variogram(),
seed=1,
max_neighbours=None,
radius_m=None,
trend=None,
mode="level_shift",
allow_mean_fill=False,
)
Bases: Spec
An SGS propagation recipe: a Variogram + seed + optional search
(max_neighbours/radius_m) + optional collocated trend +
mode ("level_shift" | "resimulate") + allow_mean_fill.
Spec
dataclass
¶
Immutable declarative value with family value-semantics.
Concrete specs are @dataclass(frozen=True, eq=False) subclasses decorated
with @spec; store collection data as tuples (immutable + JSON-able).
Equality + hash are canonical over to_dict so a spec is comparable and
hashable regardless of its field types.
replace ¶
Return a NEW value with field changes (the original is unchanged).
Collection specs (Horizons, Layering, Contacts, ...) override to accept a
leading name/glob targeting matching entries — hz.replace("H1",
surface=...), lay.replace("Z*", dz=0.5).
to_dict ¶
A plain JSON-able dict carrying the "spec" type tag. A scenario is
a durable file: removing/renaming a field is a CHANGELOG-gated break.
Variogram
dataclass
¶
Bases: Spec
A serializable variogram descriptor (ps.variogram("spherical",
range_m=1500)) — built into a _core Vgm (petekTools' VariogramSpec) at
apply. The single-home kernel stays downstream; this is the durable value.
Mc ¶
Mc(
porosity=None,
net_to_gross=None,
water_saturation=None,
fvf=None,
gas_fvf=None,
contacts=None,
goc=None,
per_zone=None,
settings=None,
n=10000,
seed=42,
)
Build an Mc — normalizing scalars/_core spreads into serializable
descriptors. contacts is the lower (FWL/OWC) spread; goc its own.
Prop ¶
Prop(
name,
zone=None,
upscale_method="arithmetic",
net_only=False,
net_cutoff=0.5,
propagate=None,
)
aggregate
builtin
¶
ps.aggregate([mc, ...], correlation="independent") — a field roll-up.
collocated ¶
A collocated-cokriging trend. surface a name (str) → a name-holding
CollocatedTrend spec resolved at apply (the v2 pattern). surface a
_core.Surface → the v1 eager trend (deprecated: bind by name instead).
decay_to_flat ¶
Extrapolate beyond data by decaying the gradient to flat over range_m.
distribution_bundle
builtin
¶
ps.distribution_bundle([mc, ...], aggregate=field, names=[...], gas=False) —
a multi-series distribution panel: one overlaid series per segment plus, if
an aggregate dict (from ps.aggregate) is given, a "Field" series from its
realization samples. Per-structure + field-aggregate in one histogram/CDF, in
MSm³ (oil) / bcm (gas). Binning is deterministic (the plumbing's nice-bin
rule); the viewer only draws.
exponential
builtin
¶
ps.exponential(range_m, sill=1, nugget=0).
fit_variogram
builtin
¶
ps.fit_variogram(coords, model="spherical", lag=.., n_lags=..) — fit a
model to an experimental variogram over [x, y, value] rows.
gaussian
builtin
¶
ps.gaussian(variogram, seed, max_neighbours=None, radius_m=None) — an SGS spec.
gaussian_vgm
builtin
¶
ps.gaussian_vgm(range_m, sill=1, nugget=0).
hz ¶
A horizon row for ps.Horizons — ps.hz("H1", tie="H1 picks",
sd=3.0, vgm=("spherical", 2500)).
layers
builtin
¶
ps.layers(n=None, dz_m=None, style="proportional").
style selects the conformity:
- "proportional" (default) — equal-fraction layers; the count is n= (or
dz_m= → ceil(gross/dz)).
- "follow_top" / "follow_base" — constant-dz_m drape parallel to the top
(truncation/erosional) or base (onlap); nk is dz-derived at the build seam
(capped at MAX_NK=200), deep/shallow layers truncate at pinch-outs. dz_m
is required; n is ignored.
level_shift
builtin
¶
ps.level_shift(sd) — a zero-mean additive shift for a modelled cube.
registered_specs ¶
Every registered spec class (the conformance battery iterates this).
resimulate
builtin
¶
ps.resimulate() — select the resimulate MC mode for
property.propagate(..., resimulate=...): a fresh SGS pattern per realization
(captures heterogeneity uncertainty) instead of the default level-shift.
Equivalent to resimulate=True; exposed because the symbol was expected to
exist (propagate(resimulate=ps.resimulate())).
run_box_model
builtin
¶
run_box_model(
area_km2,
gross_height_m,
porosity,
net_to_gross,
water_saturation,
fvf,
*,
fluid="oil",
top_m=0.0,
contact_m=Ellipsis,
ni=10,
nj=10,
nk=5,
realizations=10000,
seed=1
)
Run a box appraisal model end-to-end: area + height (+ properties) -> deterministic in-place and a Monte Carlo P90/P50/P10, plus a render mesh.
Units: area_km2 in km² (reservoir-scale-natural; converted to m²
internally), heights/depths in m (positive down), FVF in Rm³/Sm³. Results
are Sm³ (p90/p50/p10/mean/deterministic_in_place/samples), GRV in mcm;
summary_msm3 / summary_bcm give the MSm³ / bcm reporting scales.
Each volumetric input accepts
- a number → deterministic constant;
- a
(min, mode, max)tuple → triangular (shorthand); - a tagged dict → the matching distribution:
{"normal": [mean, sd]},{"lognormal": [mu, sigma]},{"uniform": [lo, hi]},{"triangular": [lo, mode, hi]}. (Area distributions are parameterised in km²; lognormalmu/sigmaare log-space km² parameters.)
An unknown tag or wrong parameter count raises ValueError.
fluid is "oil" or "gas" (both report Sm³). contact_m is required
(a finite depth in metres) — it defines the base of the hydrocarbon column.
The result's samples attribute holds every per-realization in-place value
(draw order) behind the summary, for compositional workflows.
spec_from_dict ¶
Reconstruct any spec from its tagged dict (the family from_dict).
spherical
builtin
¶
ps.spherical(range_m, sill=1, nugget=0).
splits ¶
A zone split recipe — each entry a name or (name, dict(surface=,
tie=)): ps.splits("upper", ("lower", dict(surface="H3b"))).
truncated_normal
builtin
¶
ps.truncated_normal(mean, sd, lo, hi).
view ¶
Open the viewer for any model/result (same as model.view()).