CLI API reference
The VirtuCath™ CLI API provides a persistent REPL (Read-Eval-Print Loop) interface for interacting with the application programmatically over standard input/output (stdin/stdout). It supports fully headless operation — machine learning training, dataset generation, and direct interaction via AI agents or external scripts.
The API runs continuously, holding the loaded simulation model and Flowdown engine state in memory between commands. It communicates exclusively using single-line JSON strings.
About the examples on this page. Response samples use
...as a visual placeholder for truncated content (omitted object members, additional array entries, etc.). The samples are illustrative — copying one directly will not produce valid JSON. For the canonical schema, callexport_schemaat runtime; for actual live responses, call the relevant command and read what comes back.
For AI agents — start here
If you're an LLM-driven agent encountering VirtuCath for the first time:
- Start the process with
./VirtuCath.exe --cli-api(see Starting the API for the executable path on Windows). - Send
{"command": "export_schema"}overstdin. The response contains the full JSON Schema for every command — parameter names, types, required fields, enums. Treat that schema as the source of truth. - Use
{"command": "get_config"}after anyloadorwizard_stepto inspect the active configuration as ground-truth state. - Build catheters either by passing a
.jsonfile path / inline dict toload, or by walking thewizard_stepstate machine. The wizard validates each layer against the global OD constraint at submission time, so it's the easier path for trial-and-error optimization. - Wrap each request in a try-step-observe loop: any command that errors returns
{"status": "error", "error_code": "<CODE>", ...}for deterministic handling.
Most commands accept an optional keys array to trim the response payload — useful for keeping each round-trip small.
Command index
| Category | Commands |
|---|---|
| Introspection | export_schema · get_config · get_license_info · get_materials |
| Configuration | load · validate_config · wizard_step · add_temporary_material · create_blend |
| Static analysis | get_static_kpis · calculate_flowdown · calculate_kink_safety |
| Dynamic simulation | set_environment · reset_simulation · step_simulation · set_pullwires · get_dynamic_kpis |
| Output | render_simulation · generate_graphics · generate_reports |
| DOE / response surface | run_doe · get_doe_results |
| Lifecycle | exit |
JSON config glossary
The same catheter .json schema is used by load, validate_config, and the Setup Wizard GUI. Call export_schema for the full definition; the most-referenced fields are:
| Field | Where | Meaning |
|---|---|---|
catheter_definition.name | top level | Human-readable design name (used in reports). |
catheter_definition.dimension_mode | top level | One of FIXED_ID, FIXED_OD, or OD_ID_FIXED. Controls how the layer stackup is solved. |
catheter_definition.mandrel_diameter_mm | top level | Mandrel (innermost) diameter when dimension_mode = FIXED_ID. |
catheter_definition.fixed_inner_diameter_mm | top level | Inner diameter target when dimension_mode = OD_ID_FIXED. Takes precedence over mandrel_diameter_mm in that mode. |
catheter_definition.overall_diameter_mm | top level | Outer diameter target when dimension_mode = FIXED_OD or OD_ID_FIXED. |
catheter_definition.sections[] | array | Ordered list of catheter sections, distal → proximal. |
sections[].length_mm | per section | Section length. Min 2 mm, cumulative max 1500 mm. |
sections[].layers[] | per section | Layer stack, defined inside-out (liner first, jacket last). |
sections[].is_manual_stiffness | per section | When true, skips layer-based stiffness calculation and uses user-supplied EI/GJ overrides. Certain geometry-derived KPIs (like linear_density_kg_per_m) become null. |
layers[].material_name | per layer | Must match a name in the active material library. Use get_materials to list. |
layers[].reinforcement_type | per layer | None, Polymer, Braid, or Coil. Polymer is a passive polymer layer; Braid and Coil additionally require reinforcement_settings. |
layers[].reinforcement_settings | per layer | Nested object: ppi, num_carriers, wire_shape, wire_material_name, round_wire_diameter_mm or flat_wire_thickness_mm/flat_wire_width_mm, etc. |
layers[].pullwire_settings.radial_offset_mm | pullwire layer | Radial position of the pullwire lumen centers. Bounded by radial_offset + lumen_radius + liner_wall <= section_outer_radius. |
layers[].pullwire_settings.lumen_radius_mm | pullwire layer | Round-lumen radius (or use width/thickness fields for flat lumens). |
Starting the API
Run the compiled executable with the --cli-api argument:
./VirtuCath.exe --cli-api
Installation Note: If you installed VirtuCath using the standard Windows setup wizard, the executable's location depends on your installation choice. If installed for "All Users", it is located at
C:\Program Files\VirtuCath\VirtuCath.exe. If installed for "Current User Only", it is in%LocalAppData%\Programs\VirtuCath\VirtuCath.exe. You must navigate to this directory in your terminal or add it to your systemPATHto run the commands below.
Once running, the API process waits silently for JSON commands on stdin. Logs are written to api_cli.log in the working directory to keep stdout clean.
Verbose mode:
Append the --verbose flag (e.g., ./VirtuCath.exe --cli-api --verbose) to stream internal simulation engine logs to standard error (stderr). Useful when debugging physics divergence or command failures.
Usage protocol
- Send a single line of valid JSON to
stdin. This can be a single command object{...}or an array of command objects[{...}, {...}]for batch execution. Note: Even when sending an array, the entire payload must be compacted onto a single string line without embedded newlines. - Terminate the JSON string with a newline (
\n). - The program processes the command and responds with a single line of JSON on
stdout, followed by a newline. If sending a batch array, it will respond with a single line of JSON per command. - All commands are validated against an internal JSON Schema before execution.
- If a command causes an error (or fails schema validation), the response will be explicitly structured to include an
"error_code"for deterministic programmatic handling.
Example Error Response (Schema Validation):
{
"status": "error",
"error_code": "SCHEMA_VALIDATION_ERROR",
"message": "Command failed validation: 'timeout_s' must be of type number",
"path": ["timeout_s"]
}
Security Note: All inputs are strictly parsed as JSON and type-casted internally. Do not use Python eval() or send arbitrary code.
API commands
export_schema
Returns the full JSON Schema defining every command, its expected parameters, required fields, and types. Use this as the runtime source of truth for what the API accepts — particularly useful for zero-prompt AI agents discovering the surface dynamically.
Request:
{
"command": "export_schema"
}
Response (Success):
{
"status": "success",
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "VirtuCath CLI API Request",
...
}
}
load
Loads a catheter configuration into the simulation engine and initializes the mechanics.
Request:
{
"command": "load",
"config": "C:/path/to/catheter.json"
}
Note: config can be an absolute file path, a path relative to the working directory, or a complete nested JSON object representing the configuration. Absolute paths are highly recommended.
Dimension Mode Priority Note: When passing a raw configuration JSON directly to the CLI, if
"dimension_mode": "OD_ID_FIXED"is specified within the catheter definition, the API will strictly enforce thefixed_inner_diameter_mmproperty over themandrel_diameter_mmparameter when evaluating the internal layer flowdown mechanics.
Configuration Validation Note: When a configuration is loaded, its pullwire geometric constraints are strictly validated. Specifically, the radial extent of the pullwires (
radial_offset_mm+lumen_radius_mm+liner_wall_thickness_mm) must not exceed the outer radius of the catheter section to which they are attached.
Response (Success):
{
"status": "success",
"message": "Catheter loaded successfully.",
"static_kpis": {... }
}
get_static_kpis
Retrieves the static mechanical properties (e.g., Sectional Stiffness, Elastic Instability Radius, Burst Pressure) of the currently loaded model. You can optionally request specific keys to minimize the payload size.
Note: If is_manual_stiffness is flagged for a section in the configuration, certain geometric KPIs derived from the cross-section (like linear_density_kg_per_m) are bypassed and will return null.
Request:
{
"command": "get_static_kpis",
"keys": ["sectional_stiffness"]
}
Note: The keys array is optional. If omitted, all static KPIs are returned.
Response (Success):
{
"status": "success",
"static_kpis": {... }
}
get_dynamic_kpis
Retrieves the current state of the simulation without advancing time. You can optionally request specific keys.
Request:
{
"command": "get_dynamic_kpis",
"keys": ["tip_position_mm", "physics_stable"]
}
Note: The keys array is optional. If omitted, all dynamic KPIs are returned.
Response (Success):
{
"status": "success",
"dynamic_kpis": {
"physics_stable": true,
"tip_position_mm": [4.9, 0.0, -120.5]
}
}
Note: The physics_stable flag allows agents to immediately recognize if the latest parameters caused the simulation to diverge (e.g., NaN velocities).
set_environment
Enables or disables gravity along a specific axis (x, -x, y, -y, z, -z).
Request:
{
"command": "set_environment",
"gravity_enabled": true,
"gravity_axis": "-z"
}
Response (Success):
{
"status": "success",
"message": "Gravity set to enabled along axis '-z'"
}
reset_simulation
Resets the simulation state to neutral/zero-deflection and flushes accumulated kinematics without reloading the model config from disk. Useful for rapidly starting a new sequence in bounded optimization loops.
Request:
{
"command": "reset_simulation"
}
Response (Success):
{
"status": "success",
"message": "Simulation reset successfully.",
"dynamic_kpis": {... }
}
step_simulation
Advances the physics simulation by a precise duration. Useful for algorithmic agents that need to observe continuous motion. Optionally accepts target X/Y deflections to update before stepping.
Real-time limiter:
step_simulationis throttled to wall-clock speed — the simulation is not allowed to advance faster than real time. A request to step 10 seconds will take at least 10 seconds of wall time to return. Use smallduration_svalues (e.g., 0.01–0.1) for interactive loops. For bulk static-design exploration that does not require dynamic state, preferrun_doeor recompute static KPIs via repeatedloadcalls.
Request:
{
"command": "step_simulation",
"duration_s": 0.01,
"x_mm": 5.0,
"y_mm": 0.0
}
Note: x_mm and y_mm are optional. If omitted, the simulation will step towards the last known target.
Response (Success):
{
"status": "success",
"message": "Stepped 0.01s.",
"dynamic_kpis": {... }
}
render_simulation
Captures a static frame of the current simulation state headlessly.
Request:
{
"command": "render_simulation",
"view": "custom",
"azimuth": 45.0,
"elevation": -30.0,
"distance": 0.5,
"lookat": [0.0, 0.0, -0.2],
"width": 800,
"height": 600,
"output_path": "C:/path/to/save/simulation_frame.png"
}
Note: view can be iso, front, side, top, or custom. If custom, you must specify azimuth, elevation, and distance. lookat is optional. Defaults to 800x600. Absolute paths are highly recommended for output_path.
Response (Success):
{
"status": "success",
"message": "Simulation rendered to /path/to/save/simulation_frame.png"
}
set_pullwires
Dynamically actuates the pullwires to achieve a specific spatial deflection at the catheter tip and steps the physics simulation until the tip settles (velocity drops below a threshold) or times out. Returns the dynamic KPIs of the settled state.
API Ambiguity Note: The
x_mmandy_mmparameters refer to the target spatial position (deflection amplitude) of the distal tip in the simulation world, not the linear displacement (length) of the tendon pulled.
Note on Deflection Modeling: Catheters are modeled as cantilevers rigidly fixed at the base. Therefore, if you are designing and simulating a deflectable distal section, it is highly recommended to model the proximal shaft as a rigid, minimal-length stand-in (e.g., 50-100 mm) rather than its full anatomical length. This significantly improves simulation stability and focus.
Request:
{
"command": "set_pullwires",
"x_mm": 5.0,
"y_mm": 0.0,
"timeout_s": 15.0
}
Note: timeout_s is optional and defaults to 10.0 seconds of simulation time.
Response (Success):
{
"status": "success",
"message": "Pullwires set and simulation settled.",
"dynamic_kpis": {
"is_settled": true,
"tip_position_mm": [4.9, 0.0, -120.5],
"tendon_forces_N": { "0": 1.2, "1": 0.0,... },
...
}
}
Note: If the tip fails to settle within timeout_s, the response still returns status: "success" but with message: "Simulation reached timeout before settling." and dynamic_kpis.is_settled: false. Check is_settled rather than status to determine whether the tip actually reached steady state.
Error Codes:
| Code | Condition |
|---|---|
MODEL_NOT_LOADED | load or wizard_step has not been called yet. |
SCHEMA_VALIDATION_ERROR | x_mm or y_mm is missing or not a number. |
SIMULATION_CRASHED | The physics integrator diverged (NaN/Inf tip position or runaway velocity). The simulation is auto-reset before this error returns; the response includes "crashed": true. |
calculate_flowdown
Interacts with the Flowdown Engine to iteratively calculate pre-reflow and post-reflow stackup dimensions.
Important Conceptual Note: The flowdown calculator is a secondary, manufacturing-focused tool. It is designed to be used after the catheter geometry is modeled and simulated to determine what raw, pre-reflow extrusions to procure in order to achieve the desired final design. It is not strictly required for the physics simulation itself, which runs off the final composite stackup.
This command allows AI agents to optimize designs by passing in manual layer overrides (e.g., fixed wall thicknesses or inner diameters).
Request:
{
"command": "calculate_flowdown",
"section_index": 0,
"layer_overrides": {
"0": { "is_manual": true, "fixed_wall_mm": 0.05 },
"1": { "is_manual": false, "gap_below_mm": 0.2 }
}
}
Note: section_index defaults to 0. layer_overrides uses the layer index as the key. Available override properties are is_manual, fixed_wall_mm, fixed_id_mm, gap_below_mm, and gap_above_mm. To change the base mandrel size, set mandrel_diameter_mm in the top-level catheter_definition of your loaded configuration. By default, polymer layers have a 0.15mm radial pre-reflow gap below them to simulate loose fitment prior to reflow which affects final OD if not actively accounted for. Override gap_below_mm to 0.0 to enforce a strict flush fit.
Response (Success):
{
"status": "success",
"stackup": [
{
"name": "Mandrel",
"pre_od_mm": 1.5,
...
},
...
]
}
generate_graphics
Headlessly generates 3D renderings of the catheter components (such as Braid/Coil technical illustrations and Peelaway diagrams) and saves them as images to the specified directory. This allows AI agents to retrieve visual feedback without a GUI.
Request:
{
"command": "generate_graphics",
"output_dir": "/path/to/save/images"
}
Note: The model must be loaded first. The directory will be created if it does not exist.
Response (Success):
{
"status": "success",
"message": "Graphics generated successfully.",
"saved_files": [
"/path/to/save/images/braid_render.png",
"/path/to/save/images/peelaway_render.png"
]
}
get_materials
Retrieves the full list of materials available in the local material library.
Request:
{
"command": "get_materials"
}
Response (Success):
{
"status": "success",
"materials": [
{
"name": "SS 304V",
"material_family": "Metal",
"thermoplastic": false,
"density_g_cm3": 8.0,
...
},
...
]
}
add_temporary_material
Adds a custom material to the library in-memory only for the duration of the API session. This material can then be referenced by name in subsequent calculate_flowdown or load commands without permanently altering the user's materials.json file.
Request:
{
"command": "add_temporary_material",
"material": {
"name": "Custom Agent Polymer",
"material_family": "PEBA",
"thermoplastic": true,
"density_g_cm3": 1.05,
"modulus_of_elasticity_mpa": 150.0,
"tensile_strength_mpa": 45.0,
"poissons_ratio": 0.45
}
}
Response (Success):
{
"status": "success",
"message": "Temporary material 'Custom Agent Polymer' added to memory.",
"material": {... }
}
create_blend
Creates a new blended material from two parents (or polymer + additive) using the same mechanics model as the GUI's Create Polymer Blend / Polymer + Additive dialog. The resulting material is added to the in-memory material library for the session (it is not persisted to materials.json) and can immediately be referenced by name in subsequent load, wizard_step, or calculate_flowdown commands.
Either parent can be referenced by library name (string) or supplied as an inline material object — mirroring the dialog's "Custom..." additive workflow.
Request — both parents from the library:
{
"command": "create_blend",
"base_material": "PEBAX® 2533 SA 01 MED",
"additive_material": "Barium Sulfate (BaSO4)",
"base_mass_fraction": 0.80,
"blend_mode": "additive"
}
Request — inline custom additive (equivalent to the dialog's "Custom..." entry):
{
"command": "create_blend",
"base_material": "PEBAX® 2533 SA 01 MED",
"additive_material": {
"name": "MyCustomFiller",
"density_g_cm3": 4.5,
"modulus_of_elasticity_mpa": 30000.0,
"tensile_strength_mpa": 20.0,
"poissons_ratio": 0.30
},
"base_mass_fraction": 0.80,
"blend_mode": "additive",
"name": "PEBAX 2533 + 20% MyCustomFiller"
}
Parameters:
| Field | Required | Type | Description |
|---|---|---|---|
base_material | Yes | string | object | Base polymer. A library name, or an inline material object with at least name, density_g_cm3, modulus_of_elasticity_mpa, poissons_ratio. |
additive_material | Yes | string | object | Additive (or second polymer for blend_mode = "blend"). Same accepted shapes as base_material. |
base_mass_fraction | Yes | number | Mass fraction of the base material in the resulting blend (0.05–0.95). The additive receives 1 - base_mass_fraction. |
blend_mode | No | string | "additive" (default) treats additive_material as a rigid/lubricious filler — uses the mass-loading model where modulus follows the immiscible-blend law and tensile strength drops with filler fraction. "blend" treats both parents as miscible polymers (volume-rule-of-mixtures tensile strength). |
name | No | string | Override the resulting material name. Must not collide with an existing library entry. If omitted, a name is auto-generated from the parents and ratio. |
Inline material validation (same constraints as the GUI dialog): density_g_cm3 > 0, modulus_of_elasticity_mpa > 0, tensile_strength_mpa > 0 if provided, and −1 < poissons_ratio < 0.5.
Response (Success):
{
"status": "success",
"message": "Blend 'PEBAX 2533 + 20% MyCustomFiller' created and added to in-memory library.",
"material": {
"name": "PEBAX 2533 + 20% MyCustomFiller",
"material_family": "Blend",
"thermoplastic": true,
"density_g_cm3": 1.184,
"modulus_of_elasticity_mpa": 15.51,
"poissons_ratio": 0.442,
"tensile_strength_mpa": 27.79
}
}
Error Codes:
| Code | Condition |
|---|---|
MISSING_PARAMETER | base_material, additive_material, or base_mass_fraction not provided. |
SCHEMA_VALIDATION_ERROR | blend_mode is not "blend"/"additive", base_mass_fraction out of [0.05, 0.95], or name is an empty string. |
NAME_CONFLICT | A material with the resulting name already exists in the in-memory library. |
INTERNAL_ERROR | A library lookup failed, an inline material was invalid (missing fields, bad units, out-of-range Poisson's ratio, etc.), or the blend calculation itself raised. The message describes which input failed. |
Persistence note: Like
add_temporary_material,create_blendonly mutates the in-memory library for the active session. The user'smaterials.jsonon disk is untouched. To persist a blend across sessions, use the GUI's Materials Library dialog — saved blends serialize as ordinaryMaterialentries withmaterial_family: "Blend"and reload through the standard library path with no schema additions.
get_license_info
Retrieves read-only information about the active application license, including Hardware ID, expiration status, and license type.
Request:
{
"command": "get_license_info"
}
Response (Success):
{
"status": "success",
"license_info": {
"type": "Team License (1 Year)",
"status": "Active",
"expires_at": "2027-10-31",
"days_remaining": "365 days",
"hwid": "UUID:12345678-ABCD-...",
"key_masked": "00000000-XX1234"
}
}
generate_reports
Generates the full analysis report bundle for the currently loaded configuration and saves it to the specified directory. The bundle always includes catheter_report.json (raw config + static KPIs) and, when generation succeeds, the PDF and Excel analysis reports. If dynamic simulation data has been logged, a simulation_log.csv is also written. PDF/Excel generation failures are non-fatal — the JSON dump still succeeds and saved_files reflects what was actually written.
Request:
{
"command": "generate_reports",
"output_dir": "/path/to/save/reports"
}
Note: The model must be loaded first. The directory is created if it does not exist.
Response (Success):
{
"status": "success",
"message": "Reports generated successfully.",
"saved_files": [
"/path/to/save/reports/catheter_report.json",
"/path/to/save/reports/catheter_report.pdf",
"/path/to/save/reports/catheter_data.xlsx"
]
}
validate_config
Performs pre-flight validation checks on a configuration without loading it into the physics engine. Useful for verifying geometric constraints like ensuring layer stackups do not exceed the specified overall outer diameter.
statusvsvalid: The two fields mean different things.
statusis"success"whenever the command itself ran without an exception. A schema-malformed input or missingconfigparameter would returnstatus: "error"instead.validistrueonly when the configuration passed every validation check. A configuration that loads cleanly but contains warnings will returnstatus: "success"andvalid: false, plus awarningsarray describing what's wrong.Agents looking for "did the config pass?" should branch on
valid, notstatus.
Request:
{
"command": "validate_config",
"config": "C:/path/to/catheter.json"
}
Response — valid config:
{
"status": "success",
"valid": true,
"message": "Configuration is valid.",
"warnings": []
}
Response — loadable but with warnings:
{
"status": "success",
"valid": false,
"message": "Configuration loaded but has validation warnings.",
"warnings": [
"Section '1': Sum of layer thicknesses (5.200 mm) exceeds overall_diameter_mm (4.000 mm)."
]
}
calculate_kink_safety
For each flexible section in the currently loaded configuration, computes the safety factor between a target bend radius and that section's predicted Elastic Instability Radius — the tightest bend the linear-elastic model can be trusted for. A safety factor below 1.0 means the target bend is tighter than the section's elastic-instability limit. overall_safe is true only when every section's safety factor is ≥ 1.0. Rigid sections, or sections whose elastic instability radius is undefined (infinite/zero/null), return null for that section's safety factor and do not affect overall_safe.
Request:
{
"command": "calculate_kink_safety",
"radius_mm": 15.0
}
Response (Success):
{
"status": "success",
"message": "Calculated kink safety factors.",
"target_radius_mm": 15.0,
"overall_safe": true,
"safety_factors": {
"1": 3.25,
"2": null,
"3": 1.15
}
}
Error Codes:
| Code | Condition |
|---|---|
MODEL_NOT_LOADED | load or wizard_step has not been called yet. |
SCHEMA_VALIDATION_ERROR | radius_mm is missing or not a number. |
INTERNAL_ERROR | The loaded configuration has no elastic-instability-radius data (e.g., a section with is_manual_stiffness and no derived radius). |
get_config
Retrieves the full JSON configuration object currently loaded in the simulation engine. This allows an AI agent to inspect the current state (or a default load), tweak specific parameters (like a layer thickness or pullwire offset), and re-issue a load command without having to reconstruct the entire document from scratch.
Request:
{
"command": "get_config"
}
Response (Success):
{
"status": "success",
"config": {
"schema_version": "3.0.0",
"catheter_definition": {
"name": "MyCatheter",
...
}
}
}
wizard_step
Guides an AI agent through building a new catheter configuration step-by-step, mimicking the UI's Setup Wizard. It manages an internal state machine (Global Setup -> Section Setup -> Layer Setup -> Review). It performs real-time validation at each step (e.g., rejecting a layer if it causes the flowdown OD to exceed the global OD constraint).
Workflow:
- Send
{"action": "start"}to initialize. - Send
{"action": "submit_global", "payload": {...}}with global parameters. - Send
{"action": "submit_section", "payload": {...}}to define the section parameters. - Send
{"action": "submit_layer", "payload": {...}}iteratively for each layer (from the inside out). - Send
{"action": "finish_section"}to close the current section and loop back to step 3 for the next section. - Send
{"action": "finish_wizard"}. This automatically hydrates the built configuration, calculates KPIs, loads it into the simulation engine, and returns the full"static_kpis"just like a standardloadcommand.
Request (Example Layer Submission):
{
"command": "wizard_step",
"action": "submit_layer",
"payload": {
"name": "Braid Layer",
"material_name": "PEBAX 35D",
"reinforcement_type": "Braid",
"thickness_mm": 0.1,
"reinforcement_settings": {
"ppi": 80,
"num_carriers": 16,
"wire_shape": "Round",
"wire_material_name": "SS 304V",
"round_wire_diameter_mm": 0.05
}
}
}
Response (Example Validation Error):
{
"status": "error",
"message": "Layer rejected. Predicted Flowdown OD (4.150mm) exceeds global target (4.000mm)."
}
DOE / response surface commands
The following two commands expose the Response Surface Analysis Module programmatically. A catheter configuration must be loaded first (via load or wizard_step) before calling these commands.
run_doe
Runs a headless Design of Experiments (DOE) sweep over one or two continuous design parameters (with an optional A/B categorical split attribute). For each design point, the static KPIs are recalculated from scratch using the composite mechanics models and the results are aggregated into a response surface. A cubic polynomial is then fitted to the specified output metric so you can query predicted values at arbitrary input combinations.
Design Matrix:
- 1 variable: 5-point linear sweep (min, 25%, mid, 75%, max).
- 2 variables: 5×5 full factorial — 25 runs covering every combination of the 5 levels on each axis.
- Attribute (A/B): The entire continuous DOE is duplicated for each attribute value, doubling the run count.
If too many of the requested simulations error out to support a cubic fit, the modeler fits a simpler quadratic surface instead so you still get a usable result. The surface_model.degree field in the response tells you which was used.
Path Specification: Variables and attributes reference a location inside the config using a JSON path array. Each element is either a string key or an integer array index. The path must resolve to a leaf value in the active catheter configuration. Use get_config first to inspect the structure if needed.
Note:
run_doecurrently supports static KPI sweeps only — no live dynamic simulation per run. If you need dynamic simulation data across design points, use the GUI's Response Surface Analysis Module.
Request:
{
"command": "run_doe",
"variables": [
{
"name": "Wall Thickness",
"path": ["catheter_definition", "sections", 0, "layers", 0, "thickness_mm"],
"min_val": 0.1,
"max_val": 0.5
},
{
"name": "Braid PPI",
"path": ["catheter_definition", "sections", 0, "layers", 1, "reinforcement_settings", "ppi"],
"min_val": 40,
"max_val": 120
}
],
"attribute": {
"path": ["catheter_definition", "sections", 0, "layers", 1, "reinforcement_settings", "wire_material_name"],
"val_a": "SS 304V",
"val_b": "MP35N"
},
"output_metric": "sec0_bending_stiffness_EI_Nm2",
"output_csv": "C:/path/to/results/doe_sweep.csv"
}
Parameters:
| Field | Required | Type | Description |
|---|---|---|---|
variables | Yes | array (1-2 items) | Continuous input variables to sweep. Each item must have name, path, min_val, and max_val. |
attribute | No | object | Categorical A/B split. Must have path, val_a, and val_b. |
output_metric | No | string | KPI column to fit the cubic surface to. Defaults to "sec0_bending_stiffness_EI_Nm2". |
output_csv | No | string | Absolute path to save the full raw results as a CSV file. |
Available output metrics (prefix sec{N}_ for section index N):
bending_stiffness_EI_Nm2torsional_stiffness_GJ_Nm2axial_stiffness_EA_Nburst_pressure_mpadisplay_linear_density_kg_per_melastic_instability_radius_mm— curvature radius at which the section first becomes elastically unstable (Brazier ovalization limit with helical-wire augmentation).elastic_instability_moment_Nm— bending moment corresponding to the elastic instability radius.tensile_failure_load_Ntorque_failure_Nmcrush_pressure_atm
Response (Success):
{
"status": "success",
"message": "DOE complete: 50 runs, metric='sec0_bending_stiffness_EI_Nm2'.",
"total_runs": 50,
"output_metric": "sec0_bending_stiffness_EI_Nm2",
"runs_summary": [
{
"run": 1,
"x1": 0.1,
"x2": 40,
"attr": "SS 304V",
"sec0_bending_stiffness_EI_Nm2": 0.000412,
"error": null
}
],
"surface_model": {
"fitted": true,
"degree": 3,
"r2_score": 0.9987,
"adjusted_r2": 0.9978,
"residual_rms": 1.24e-5,
"predictions": {
"x1": [0.1, 0.144, "..."],
"x2": [40, 48.9, "..."],
"z": [[0.000412, "..."], "..."]
}
},
"output_csv": "C:/path/to/results/doe_sweep.csv"
}
surface_model fields:
| Field | Type | Meaning |
|---|---|---|
fitted | bool | true if the modeler produced a usable surface. false if too few simulations succeeded to fit one. |
degree | int | Polynomial degree used — 3 for the standard cubic fit, 2 when the modeler had to fall back to a quadratic. |
r2_score | float | null | Overall goodness-of-fit (1.0 means the surface passes through every sample point). |
adjusted_r2 | float | null | R² adjusted for the number of fitted coefficients — stays honest when the data is noisy or near-flat. Use this one when deciding whether to trust the surface. |
residual_rms | float | null | Average distance from the surface to the simulated points, in the metric's units. Treat predicted values as accurate to roughly ±residual_rms. |
predictions | object | null | Fine-grid surface evaluation suitable for plotting (x1, x2, z). |
Interpreting fit quality:
adjusted_r2 ≥ 0.95means the surface tracks the data closely and predictions are trustworthy. Between 0.70 and 0.95 the surface is usable but the underlying behavior likely has features the cubic doesn't fully capture — treat predictions directionally. Below 0.70 the surface is mostly fitting noise; rely on the raw simulated values instead. These are the same thresholds the GUI uses for its green/amber/red color tier.
Error Codes:
| Code | Condition |
|---|---|
MODEL_NOT_LOADED | load or wizard_step has not been called yet. |
MISSING_PARAMETER | variables array is empty. |
INTERNAL_ERROR | Unhandled exception during the sweep. |
get_doe_results
Returns the raw per-run data table from the most recent run_doe call. This is useful to retrieve the full result set (including all KPI columns, not just the surface-fitted metric) without repeating the sweep. Results are cached in memory until the next run_doe call.
Optionally, you can filter the returned columns to reduce payload size.
Request:
{
"command": "get_doe_results",
"columns": ["x1", "x2", "sec0_bending_stiffness_EI_Nm2", "sec0_elastic_instability_radius_mm"]
}
Note: columns is optional. If omitted, all columns are returned.
Response (Success):
{
"status": "success",
"last_metric": "sec0_bending_stiffness_EI_Nm2",
"total_runs": 50,
"columns": ["x1", "x2", "sec0_bending_stiffness_EI_Nm2", "sec0_elastic_instability_radius_mm"],
"rows": [
{
"x1": 0.1,
"x2": 40,
"sec0_bending_stiffness_EI_Nm2": 0.000412,
"sec0_elastic_instability_radius_mm": 8.3
}
]
}
Error Codes:
| Code | Condition |
|---|---|
NO_DOE_RESULTS | run_doe has not been called in this session. |
exit or quit
Safely stops the simulation engine, deallocates memory, and closes the application.
Request:
{
"command": "exit"
}
Response (Success):
{
"status": "success",
"message": "Exiting CLI API."
}
(The program will then terminate)
Related pages
- Getting Started — install and run VirtuCath before using the CLI.
- Catheter Setup Tab — schema reference for the catheter
.jsonfiles loaded via the CLI. - Catheter Analysis Tab — KPI definitions returned by analysis commands.
- Model Accuracy and Confidence — accuracy notes for the predicted stiffnesses returned by the CLI.