Public API¶
The top-level package exports the main user-facing classes:
from tep_studio import (
AdvanceResult,
ClosedLoopSimulation,
GymTEPEnv,
OptimizationAdapter,
ProcessSchema,
RickerMultiLoopController,
TEP_SCHEMA,
TennesseeEastmanProcess,
TrajectoryDataset,
)
The closed-loop control and interface layers have their own public APIs, summarized at the end of this page: tep_studio.control and tep_studio.ui.
TennesseeEastmanProcess¶
Core process simulator.
Create¶
Reset¶
obs, info = sim.reset(
mode="mode1",
seed=1431655765,
initial_state=None,
disturbances=None,
ms_flag=None,
)
Returns:
obs: 41-element measurement vector;info: dictionary with time, schema, implemented action, disturbances, margins, shutdown status, and solver stats.
Advance¶
Returns an AdvanceResult.
Snapshot and restore¶
Use this for deterministic replay and candidate rollout.
Validate dimensions¶
Checks schema/kernel dimensions for states, manipulated variables, disturbances, and measurements.
AdvanceResult¶
Returned by TennesseeEastmanProcess.advance().
Fields:
| Field | Meaning |
|---|---|
time_start |
Start time of the interval. |
time_end |
End time of the interval. |
control_interval |
Requested interval length. |
state |
50-element state at time_end. |
measurements |
41 standard measurements at time_end. |
requested_action |
12-element raw requested action. |
implemented_action |
12-element clipped action applied to the process. |
disturbances |
28-element disturbance vector. |
constraint_margins |
Named operating-limit margins. |
events |
Structured process event records. |
shutdown_status |
Shutdown code, message, and termination flag. |
solver_stats |
Solver method, success flag, message, and evaluation counts. |
objective_terms |
Operating-cost monitor terms exposed by the core. |
TrajectoryDataset¶
Converts results into tabular data.
dataset = TrajectoryDataset.from_results(
results,
run_id="run_001",
scenario_id="mode1_short",
)
frame = dataset.to_pandas()
matrix, columns = dataset.to_numpy("measurements")
dataset.to_csv("trajectory.csv")
dataset.to_parquet("trajectory.parquet")
Supported NumPy views:
measurements;states;requested_actions;implemented_actions;disturbances.
GymTEPEnv¶
Gymnasium-compatible environment.
env = GymTEPEnv(control_interval=0.01, horizon=24.0)
obs, info = env.reset(seed=123)
next_obs, reward, terminated, truncated, info = env.step(action)
The action space is 12-dimensional. The observation space is 41-dimensional.
OptimizationAdapter¶
Finite-horizon rollout and finite-difference gradient helper.
adapter = OptimizationAdapter(sim)
rollout = adapter.rollout(action_plan, control_interval=0.001)
gradient = adapter.finite_difference_gradient(action_plan, control_interval=0.001)
The adapter restores the simulator after each rollout.
TEP_SCHEMA¶
Machine-readable process schema.
from tep_studio import TEP_SCHEMA
state_names = TEP_SCHEMA.names("states")
measurement_names = TEP_SCHEMA.names("measurements")
mv_names = TEP_SCHEMA.names("manipulated_variables")
disturbance_names = TEP_SCHEMA.names("disturbances")
Named lookup helpers:
pressure_index = TEP_SCHEMA.index("measurements", "reactor_pressure")
coolant_mv = TEP_SCHEMA.variable("mvs", "reactor_cooling_water_valve")
Vector helpers:
action = TEP_SCHEMA.vector(
"mvs",
{
"purge_valve": 40.064,
"reactor_cooling_water_valve": 38.0,
},
)
next_action = TEP_SCHEMA.update_vector(
"mvs",
action,
{"reactor_cooling_water_valve": 41.106},
)
measurements = TEP_SCHEMA.to_dict("measurements", result.measurements)
reactor_pressure = measurements["reactor_pressure"]
Common role aliases include measurement, measurements, mv, mvs, manipulated_variable, manipulated_variables, state, states, disturbance, and disturbances.
tep_studio.control¶
The decentralized control package. See Closed-Loop Control for the loop structure and usage.
from tep_studio.control import (
ClosedLoopSimulation, # couples controller + core; .run() -> ClosedLoopResult
ClosedLoopResult, # trajectory, metrics, peak, terminated/truncated, stabilized
RickerMultiLoopController, # the controller; reset(meas0) then compute_action(meas, time=t)
ControllerSetpoints, # frozen setpoint bundle (reactor_level, production_rate, %G, ...)
ControlStepDiagnostics, # per-step setpoints, loop outputs, active overrides
RICKER_MODE1, # the Mode-1 loop registry (gains, reset times, pairings)
MetricsAccumulator, # IAE/ISE/constraint-violation metrics
DiscretePI, VelocityPI, # the PI primitives (positional + velocity form)
online_control_view, # the 16 measurements the controller may use (P5 boundary)
diagnostic_view, # full offline view (state + events)
build_experiment_record, # reproducible P6 record (revision, hashes, seed, solver)
controller_config, process_description_hash,
)
result = ClosedLoopSimulation(control_interval=0.0005, horizon=48.0).run()
result.stabilized # bool: ran the horizon without a shutdown
result.peak["reactor_pressure_max"]
result.metrics["iae"]["reactor_level"]
compute_action accepts only measurements (never state), enforcing the controller-is-not-the-plant boundary at the type level.
tep_studio.ui¶
The Simulation Studio and its Dash-free backend. See Interface (Studio). The backend is importable without the ui extra; create_app imports Dash lazily.
from tep_studio.ui import (
ScenarioConfig, # frozen, JSON-round-trippable run spec (the save/load unit)
StepTestSpec, # an MV or setpoint step
DisturbanceActivation, # a latched, timed IDV
BatchSpec, # seeds x disturbance x parameter sweep
RunResult, BatchResult, # compact, serializable run artifacts
run_scenario, # run one open/closed-loop scenario -> RunResult
run_mv_step_test, # open-loop MV step
run_setpoint_step_test, # closed-loop setpoint step
build_dataset, # (runs, fmt="csv"|"parquet") -> (payload_bytes, filename)
run_batch, # run a BatchSpec -> (BatchResult, list[RunResult])
create_app, # build the Dash app (requires the `ui` extra)
)
run = run_scenario(ScenarioConfig(loop_type="closed", horizon=12.0, control_interval=0.01))
payload, filename = build_dataset([run], fmt="csv")
Launch the interface with python3 -m tep_studio.ui or the tep-ui console script (installed with pip install -e ".[ui]").