Skip to content

CODEGEN Studio

CODEGEN Studio is a browser-based visual editor for assembling User-Defined Models using the CODEGEN block library. Instead of writing DSL files by hand, you drag blocks onto a canvas, connect them, fill in metadata, and export a valid .txt file ready for the codegen binary.

Terminal window
git clone https://github.com/SPS-L/stepss-cg-studio
cd stepss-cg-studio
pip install -r requirements.txt
python server/app.py

Open http://localhost:8765 in your browser.

The interface has three columns:

AreaLocationPurpose
Block paletteLeft sidebarSearchable catalogue of all CODEGEN blocks, grouped by category
CanvasCenterDrag-and-drop block diagram with connection wires
Metadata tabsBelow canvasEditable tables for %data, %parameters, %states, %observables
Block inspectorRight panel (top)Edit output signal names and block arguments for the selected block
DSL previewRight panel (bottom)Live syntax-highlighted preview of the generated DSL code
TopbarTopModel type/name selectors, file operations, and settings

Use the Type dropdown in the topbar to select the model category:

TypeDescriptionMandatory outputsColour theme
EXCExcitation controllervfBlue
TORTorque controllertmGreen
INJCurrent injectorix, iyOrange
TWOPTwo-port deviceix1, iy1, ix2, iy2Purple

The UI accent colour changes to reflect the active model type. Type the model name (max 32 characters) in the Name field next to the dropdown.

The left palette lists all available blocks from the CODEGEN Blocks Library, organised by category (Transfer Functions, Limiters, Controllers, etc.).

  1. Search by typing in the search box at the top of the palette
  2. Expand a category by clicking its header
  3. Drag a block from the palette onto the canvas

Each block appears as a node with input ports on the left and output ports on the right. A coloured dot indicates the block category.

Click and drag from an output port (right side) of one block to an input port (left side) of another. A wire appears showing the signal flow. The connection assigns a signal name that links the two blocks in the generated DSL.

  • Each input port accepts exactly one incoming wire
  • Each output port can fan out to multiple inputs
  • The status bar below the canvas toolbar shows the current block and wire count

Click a block on the canvas to select it. The Block Inspector (right panel) shows:

  • Output signal names — one editable field per output port. The default auto-generated name (e.g., tf11, int2) can be renamed to any valid identifier. This is the state name that appears in the DSL.
  • Arguments — block-specific parameters such as gain K, time constant T, or limiter bounds. Values can be:
    • A numeric literal: 1.0
    • A data reference: {KA} (refers to an entry in %data)
    • A Fortran expression: {1/{omegac}}

The algeq (algebraic equation) block has a special Expression field for the equation set to zero.

The four tabs below the canvas correspond to the four metadata sections of a CODEGEN DSL file:

Purpose: Declare named constants whose values are read from the RAMSES data record at runtime.

ColumnDescriptionExample
NameIdentifier (max 20 chars)KA
ValueOptional default200.0
CommentAnnotationAVR gain

In block arguments and expressions, reference data values with braces: {KA}.

Click ”+ Add row” to append a row. Click the x button on a row to remove it. All edits update the DSL preview in real time.

The bottom-right panel shows a live syntax-highlighted preview of the generated DSL code. It updates automatically (with a 600 ms debounce) after every change. The preview uses colour coding:

ColourMeaning
Orange, boldSection headers (%data, %parameters, etc.)
Gray, italicComments (! ...)
BlueNumeric literals
PurpleData/parameter references ({KA})
CyanState/input references ([omega])

Click the copy button in the preview header to copy the DSL text to your clipboard.


Click “Save Project” in the topbar (or press Ctrl+S / Cmd+S).

The browser downloads a .json file named after your model (e.g., simple_avr.json) containing the complete project state:

  • Model type and name
  • All blocks with their positions, arguments, and output signal names
  • All wire connections
  • All metadata (data, parameters, states, observables)

This is a lossless format — every aspect of your canvas layout and configuration is preserved. Use this format for work-in-progress models that you intend to continue editing.


Click “Load Project” in the topbar and select a previously saved .json file.

The editor restores the full project state:

  • Canvas blocks appear at their saved positions
  • All wires are reconnected
  • Metadata tables repopulate
  • The model type and name update in the topbar
  • The colour theme switches to match the model type

A toast notification confirms the load with the model name.


Click “Load DSL” and select a .txt file written in the CODEGEN DSL format.

The backend parser extracts all sections and blocks from the file, and the editor reconstructs the canvas:

  1. Each & blockname in %models becomes a node on the canvas
  2. Signal references are resolved into wire connections
  3. Metadata sections populate the corresponding tabs
  4. A Sugiyama auto-layout algorithm assigns node positions automatically:
    • Blocks are arranged left-to-right by dependency order
    • A three-pass crossing-reduction minimises wire overlaps
    • Feedback loops are detected and handled gracefully

This lets you visually inspect and edit any existing CODEGEN model, including the example models.


Click “Export DSL” to download the generated .txt file.

Before export, the editor validates that all mandatory output states for the selected model type are produced by at least one block on the canvas. If any are missing, a warning dialog lists them:

Missing Mandatory Outputs

Missing mandatory outputs for exc: vf

The codegen binary will reject this model.

You can click “Export Anyway” to override the warning, or “Cancel” to go back and fix the model.

The exported file follows the strict DSL section order: model type, model name, %data, %parameters, %states, %observables, %models. Blocks are emitted in topologically-sorted order (dependencies before dependents).


Click “Run Codegen” (the accent-coloured button with the play icon) to compile the model into Fortran.

The same mandatory-output validation runs first. If validation passes:

  1. The editor generates the DSL text
  2. The backend writes it to a temporary file and invokes the codegen binary
  3. On success, a modal displays the generated .f90 source code with options to “Download .f90” or “Close”
  4. On failure, a modal shows the error output from the codegen binary

The downloaded .f90 file follows the naming convention exc_simple_avr.f90 (type prefix + model name) and is ready to compile and link with RAMSES.


FormatExtensionUse caseLossless?
Project.jsonSave/resume editingYes — includes canvas positions, all metadata
DSL.txtInput to codegen binaryStructure only — no canvas layout
Fortran.f90Output from codegenExport only — cannot be re-imported

ShortcutAction
Ctrl+S / Cmd+SSave project
Ctrl+Z / Cmd+ZUndo
Ctrl+Y / Cmd+Shift+ZRedo
Delete / BackspaceDelete selected block
EscapeClose any open modal

Shortcuts are disabled while typing in text fields.


Click the gear icon in the topbar to configure:

SettingDefaultDescription
Codegen binary pathcodegenFull path to the codegen executable
Server host127.0.0.1Bind address (change to 0.0.0.0 for network access)
Server port8765HTTP port

Changes to host and port require a server restart. The codegen path takes effect immediately.

Settings are stored in server/config.json and can also be edited via the REST API at /docs (Swagger UI).


This walkthrough creates a simplified Automatic Voltage Regulator (AVR) as an EXC model.

  1. Select EXC from the Type dropdown
  2. Type simple_avr in the Name field

Switch to the %data tab and add rows:

NameValueComment
KAAVR gain
TAAVR time constant
VREFReference voltage

Drag the following blocks from the palette onto the canvas:

  1. algeq — to compute the voltage error
  2. tf1p — a first-order transfer function for the AVR
  1. Connect the algeq output to the tf1p input
  2. Select the algeq block and set its Expression to {VREF}-[v]-avr1
  3. Select the tf1p block and:
    • Rename its output signal to vf (this is the mandatory EXC output)
    • Set K to {KA} and T to {TA}

Switch to the %states tab and add:

NameInitComment
avr1vf/{KA}AVR integrator state

Switch to the %observables tab and add vf.

  1. Click “Export DSL” — validation passes because vf is produced by the tf1p block
  2. The downloaded simple_avr.txt is ready for codegen -tsimple_avr.txt
  3. Or click “Run Codegen” to generate exc_simple_avr.f90 directly