Skip to content

Consumer API (itis_sumo.api)

itis_sumo.api is the whole of what an application embedding itis-sumo is expected to import — a web service, a notebook, a script. Pass a table of samples and some configuration; get back a typed result in your own units.

Everything in between belongs to itis-sumo and is not reachable from here: training-file layout, Dakota configuration, normalization, internal variable renaming, run directories, and inverse transforms.

from itis_sumo.api import cross_validate

result = cross_validate(samples, variables=["width", "height"], response="stress")
result.predicted  # one value per sample, in the units of `stress`
result.warnings  # anything that went wrong but did not stop the run

The vocabulary is the one defined in the Glossary: a sample is a row, a variable (parameter) is an input column, a response (quantity of interest) is an output column.

Workflows

cross_validate

Predicts every sample from a surrogate that never saw it. The samples are split into folds; each fold is predicted by a surrogate trained on the others, so the result is an honest picture of how the surrogate behaves on data it has not memorised.

Returns a CrossValidationResult: the observed values, the predicted values and their standard deviations aligned positionally with your rows, plus any warnings.

If Dakota abandons a fold — which it occasionally does when the training points are nearly degenerate — the samples in that fold keep a NaN prediction and the reason appears in warnings, rather than the whole run failing.

evaluate_along_axes

Sweeps each variable in turn across its observed range while every other variable is held still. This is the shape behind a one-dimensional profile plot.

Returns an AlongAxesResult containing one AxisSweep per variable, keyed by the variable's own name. Use at= to pin particular variables; anything you leave out is held at its mean across the samples.

Configuration

Sensible defaults are derived from your samples, so the common path needs no configuration at all. Advanced users may override behaviour per column with PreprocessingSpec:

from itis_sumo.api import PreprocessingSpec, VariableSpec

spec = PreprocessingSpec(overrides={"width": VariableSpec(scale="linear")})

Overrides are expressed in terms of the domain — what a column is like — never in terms of a transform. Which normalization or sign convention a choice implies is an implementation detail. You can always read back what was actually used, via result.effective_config; you cannot set it in transform terms.

Stochastic workflows take a seed that already has a value, so results are reproducible by default without you having to think about it. The seed that was used comes back in the result.

Errors

Every error that escapes itis_sumo.api is a SumoError. Catch the subclass rather than matching on message text.

Error Meaning Typical HTTP status
SumoInputError The samples or configuration are unusable. Fixable by sending something different. 400
SumoResultError The run finished but produced none of the requested values. Retrying unchanged will not help. 422
SumoEngineError Dakota itself failed. 500

Dakota reports its failures opaquely. Because of that, working files are discarded when a run succeeds but kept when one fails — and SumoEngineError carries the surviving run directory along with the tail of Dakota's own stderr, so there is something to look at.

try:
    result = cross_validate(samples, variables, response)
except SumoInputError as error:
    return bad_request(str(error))
except SumoEngineError as error:
    logger.error("surrogate build failed; evidence at %s", error.run_dir)
    return server_error("Could not build a surrogate from these samples")

Pass workspace= to keep working files from a successful run too, when you want to inspect what Dakota was given.