how boitatá is organized¶
boitatá has five kinds of object, and each kind takes the same calls wherever it appears. once you know which kind you hold, you can guess most of what it accepts. you need basic python and numpy, and no geostatistics.
the map¶
with_column puts results back onto a container. the rust core does the arithmetic for containers, functions and estimators.one short run touches every layer:
import boitata as bt
samples = bt.datasets.walker_lake() # 1. get data: a PointSet
experimental = bt.experimental_variogram(samples, "V", 10.0, 120.0) # 3. a function
variogram = experimental.fit("spherical") # 3. a value object
search = bt.Search(radius=60, max_samples=24, min_samples=4) # 3. a value object
grid = bt.BlockModel(origin=(2.5, 2.5), size=(5, 5), count=(52, 60)) # 2. a container
kriging = bt.OrdinaryKriging(variogram, search).fit(samples, "V") # 3. an estimator
grid = grid.with_column("V", kriging.predict(grid)) # results back on the container
fig, ax = bt.plot.histogram("V", data=grid) # 4. a plot
PointSet(470 points, crs: none)
ID: Float64
V: Float64
U: Float64
T: Float64
BlockModel(regular, 3120 of 3120 cells, count [52, 60, 1], size [5.0, 5.0, 1.0], rotation [0.0, 0.0, 0.0])
V: Float64
five kinds of object¶
containers hold data. Table, PointSet, Drillholes, BlockModel, Mesh and Polylines store columns plus the geometry that places each row: coordinates for points, origin and block size for a grid, vertices and triangles for a mesh. containers and arrow covers them.
value objects describe a model. a Variogram, a Structure, a Search, a Categories scheme or a HighGrade restriction holds parameters and no data. you build one, read its properties, pass it to an estimator and save it as JSON. a value object never changes after you build it.
transforms learn a mapping. NormalScore, Capping, PPMT and their relatives fit to samples, then send values through transform and back through inverse_transform.
estimators learn from samples and answer at targets. OrdinaryKriging, BlockKriging, SGS and the rest fit to samples, then answer predict or simulate wherever you point them. transforms and estimators share one lifecycle: build with options, fit, then ask for results. fit, transform, predict walks through it.
functions compute a result in one call. exploratory statistics (describe, describe_by, swath, contact, grade_tonnage) and experimental variograms (experimental_variogram, variogram_map) take data and return numbers, a Table or an ExperimentalVariogram. they fit and remember nothing.
beyond those five, two modules draw and fetch: bt.plot draws on matplotlib and returns fig, ax, and every plot accepts ax= to draw into your own axes; bt.datasets downloads the teaching datasets once and caches them.
| kind | holds | you call | saves as |
|---|---|---|---|
| container | columns and geometry | with_column, filter, mask, ["V"] |
parquet |
| value object | parameters | properties, to_json |
JSON |
| transform | what fit learned |
fit, transform, inverse_transform |
JSON |
| estimator | the fitted samples | fit, predict, cross_validate |
parquet |
| function | nothing | one call | its result |
key idea
ask what kind of object you hold. a container answers with_column, a value object answers to_json, a transform and an estimator answer fit and then transform or predict, and a function answers once and keeps nothing.
guessing a call¶
the names follow a few rules, so you can often write a call you have not seen before.
- full names.
OrdinaryKriging,NormalScore,experimental_variogram. only standard acronyms stay short: SGS, DSS, SIS, PCA, MAF, CRS. - the same argument names everywhere.
coordsfor locations,valuesfor the variable,targetsfor where to estimate,weights,categories,domainsordomain_column,seed,search,variogram. ranges come as(major, semi-major, minor); arotationis one(azimuth, dip, rake)triple in degrees, with azimuth clockwise from north and dip positive down. - a column name stands for a column. where a function takes one value per row, you can pass the column name and the container:
kriging.fit(samples, "V"), orbt.describe("V", data=samples)for calls that take the values first. - options are keyword-only. you must name every argument that has a default, so
bt.Search(60, 24)fails andbt.Search(radius=60, max_samples=24)works:
bt.Search(60, 24)
TypeError: Search.__new__() takes 1 positional arguments but 2 were given
- methods return new objects.
with_column,filterandmaskreturn a new container and leave the old one as it was, so assign the result:grid = grid.with_column(...). - american spelling,
zup, right-handed axes, 3D internally: points given as(n, 2)getz = 0.
errors¶
the errors boitatá raises itself derive from bt.BoitataError and from the builtin exception you would expect, so you can catch either. python's own checks, such as a missing keyword, raise a plain TypeError.
| error | also a | raised when |
|---|---|---|
InvalidInput |
ValueError |
an argument is out of range, or a file holds another object |
MissingColumn |
KeyError |
the container has no column of that name |
FileError |
OSError |
a file cannot be read or written |
try:
samples["Au"]
except KeyError as error:
print(type(error).__name__, error)
MissingColumn no column "Au"; columns: ID, V, U, T
the message lists the columns the container has, so you can spot a typo.
pitfall
readers turn sentinels such as -999 into nulls, and statistics such as describe skip them. estimators, transforms and variograms do not: a missing value there raises InvalidInput: values must be finite; drop missing values first. drop the rows with filter before fit; containers and arrow shows how.
rust underneath¶
the numerical work runs in rust, in double precision. kriging runs in parallel over targets and simulation over realizations. each realization draws from a seed derived from yours, so a run gives the same numbers with one thread or many. the python layer checks the arguments and hands the work down; you never call the rust layer yourself.
API map¶
-
Table,PointSet,BlockModel,Mesh,Polylines,read_csv,read_shapefile,read_geotiff -
Drillholes,check_drillholes,merge_intervals,assign_domain,block_shell -
bt.datasets,bt.plot,bt.plot3d -
describe,describe_by,swath,contact,grade_tonnage,Categories -
NormalScore,Capping,HermiteAnamorphosis,PPMT,PCA,MAF -
Variogram,Structure,experimental_variogram,variogram_map -
Search,OrdinaryKriging,SimpleKriging,BlockKriging,IndicatorKriging -
SGS,DSS,TurningBands,SIS,Plurigaussian,SNESIM -
ImplicitModel: surfaces and solids from contacts and orientations