Model run views
Model run views are custom, parameterized reports that visualize a model run’s output in the pd4castr UI. Each view is its own page in a model’s Model Run Views section, where a viewer picks a model run, sets the view’s parameters, and sees the result rendered as a chart, a table, or both.
A view runs a SQL query over the selected run’s output and your model’s supporting data. This lets you reshape and aggregate run results into a purpose-built report, beyond the forecast chart that outputs define. Views build on datasets, which supply the static reference data a view query joins against.
When to use a view
Use a view when you want to give users a dedicated report over a model run, with its own parameters, chart, and table. For example:
- A summary that aggregates fine-grained output into a compact chart and table.
- A breakdown that joins output against a dataset, such as labeling result rows with friendly names from a reference table.
- A parameterized report where users pick a value (such as a region or scenario) from a dropdown and the report recomputes for that selection.
If you only need to plot forecast series over time, the forecast chart that outputs define already covers that. To summarize input data rather than run results, use input aggregations.
How a view appears in the UI
Each view is a separate page under a model’s Model Run Views section, and users switch between a model’s views with the view selector. On a view page, the viewer chooses which model run to inspect, sets the view’s parameters, and the view query runs against that run.
The result renders as a chart, a table, or both, depending on the view’s columns:
- A chart plots the first
dimensioncolumn on the x-axis and draws one line permeasurecolumn. A view renders a chart only when every measure declares the same non-emptyunit. Otherwise it falls back to a table. - A table shows every returned column in query order, with each measure’s
unitappended to its header.
See Columns for how role, unit, and label shape this.
How a view query works
A view is a SQL query, stored in a file in your project, that the platform runs against a model run. The query has these tables in scope:
output: the rows your model produced for the run.dataset_<key>: one table per declared dataset, named from itskey(for example,dataset_regions).input_<key>: one table per declared input, named from itskey(for example,input_demand).
Datasets and inputs are namespaced by kind so an input and a dataset that share a key don’t collide.
The query reads any parameters through getvariable(). For
example, a region parameter is read as getvariable('region'). Each column
the query returns must be declared in columns, and each columns
entry must match a returned column.
Configure views
Add views in the views array in your .pd4castrrc.json file. Each view points
to a local SQL file and declares the columns its query returns.
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Unique identifier for the view. Must be lowercase alphanumeric, with hyphens or underscores. |
name | string | Yes | Display name for the view, shown in the pd4castr UI. |
sql | string | Yes | Path to the view’s SQL file, relative to your project root. |
params | object | No | Map of parameter name to parameter configuration. See Parameters. |
columns | array | Yes | Metadata for each column the query returns. See Columns. |
A minimal view with no parameters looks like this:
{
"views": [
{
"key": "daily_average",
"name": "Daily average price",
"sql": "views/daily_average.sql",
"columns": [
{ "key": "day", "role": "dimension", "label": "Day" },
{
"key": "avg_price",
"role": "measure",
"label": "Average price",
"unit": "$/MWh"
}
]
}
]
}Parameters
Parameters let users drive a view query from the UI. You declare each parameter
under params, keyed by the variable name the query reads with getvariable().
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Yes | — | Value type: string, number, or boolean. |
label | string | Yes | — | Display label shown above the parameter’s form field. |
description | string | No | — | Explanatory text shown in an info tooltip beside the label. Maximum 500 characters. |
optional | boolean | No | false | Whether the parameter can be left unset. An unset parameter binds to NULL. |
control | string | No | — | UI control for the parameter. Currently only select (a dropdown) is supported. |
options | string | select only | — | Path to a SQL file whose rows populate the dropdown. Required for select, invalid otherwise. |
defaultFrom | string | No | — | Resolve this parameter’s default from another select parameter’s option metadata. See below. |
sample | string | number | boolean | Required non-select | — | A representative value the CLI uses to test the view when you publish. See Sample values. |
Every declared parameter must be referenced at least once with getvariable()
in the view SQL or its options SQL, and every getvariable() reference must map
to a declared parameter.
Select parameters and the options query
A select parameter shows a dropdown populated by a separate options query. The
options query must return these columns:
| Column | Type | Required | Description |
|---|---|---|---|
value | string | number | boolean | Yes | The value bound to the parameter when the option is selected. Must be non-null and unique. |
label | string | Yes | The text shown for the option in the dropdown. |
metadata | JSON object | No | Per-option data. Powers dependent parameters and dependent field pre-fill in the UI. |
The first option row is the default selection. Use json_object() to build the
metadata column.
Optional parameters
Mark a parameter optional: true when the user can leave it unset. An unset
optional parameter binds to NULL, so the view SQL must handle the null case,
typically with coalesce().
Dependent parameters
Use defaultFrom to default one parameter from another parameter’s selection.
The reference takes the form <sourceParam>.metadata.<key>, where
<sourceParam> is a select parameter and <key> is a field on that
parameter’s option metadata.
A defaultFrom parameter must be optional: true and must not itself be a
select. The referenced metadata key must be present and non-null on every
option row of the source parameter.
Sample values
When you publish, the CLI runs each view query once to confirm it works and to capture the columns it returns. To run the query, it needs a value for every parameter, before any real user has chosen one. It fills these in as follows:
- A
selectparameter uses its first option. - An optional parameter is left unset.
- A required parameter that isn’t a
select(a free text, number, or boolean value the user types in) has no value the CLI can pick. For these, you provide a representative value withsample.
The sample value is only used for this check at publish. When someone opens
the view, they supply their own value. The value must match the parameter’s
type.
Columns
The columns array declares metadata for each column the view query returns.
Every returned column must have an entry, and every entry must match a returned
column.
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Column name as returned by the query. |
role | string | Yes | dimension for category columns (the chart x-axis), measure for numeric values (chart series and measure columns). |
label | string | No | Display label for the column. Defaults to the column key. |
unit | string | No | Unit for the column’s values, such as $/MWh or %. Appended to table headers and used as the chart y-axis title. |
format | string | No | Declared value format: currency, percent, integer, decimal, date, or datetime. |
Example
This example defines a price_by_hour view. It lets a viewer pick a region from
a dropdown, then shows the average and peak forecast price for each hour of the
day in that region.
The view configuration declares the SQL file, the region select parameter
backed by an options query, and the columns the query returns:
{
"views": [
{
"key": "price_by_hour",
"name": "Average price by hour",
"sql": "views/price-by-hour.sql",
"params": {
"region": {
"type": "string",
"label": "Region",
"description": "The NEM region the prices are averaged over",
"optional": false,
"control": "select",
"options": "views/region-options.sql"
}
},
"columns": [
{ "key": "hour_of_day", "role": "dimension", "label": "Hour of day" },
{
"key": "avg_price",
"role": "measure",
"label": "Average price",
"unit": "$/MWh"
},
{
"key": "peak_price",
"role": "measure",
"label": "Peak price",
"unit": "$/MWh"
}
]
}
]
}The view SQL reads the selected region with getvariable('region'), filters the
run’s output to that region, and aggregates price by hour of day:
select
hour(forecast_datetime) as hour_of_day,
avg(price) as avg_price,
max(price) as peak_price
from output
where region = getvariable('region')
group by 1
order by 1;The options query reads the available regions from a dataset, returning a
value and label for each, plus a metadata object carrying the region’s
time zone:
select
code as value,
name as label,
json_object('timezone', timezone) as metadata
from dataset_regions
order by name;Validation at publish
When you run pd4castr publish, the CLI validates every view against your local
test data before uploading it, so problems surface before the view reaches the
platform. It runs each view query and its options queries, then checks that the
parameters resolve and that the declared columns match what the query returns.
This validation uses the output from your most recent local test run, so run
pd4castr test before publishing.
Next steps
- See the Configuration file reference for the full schema.
- See Model datasets to publish the reference data a view query joins against.
- See Testing your model to capture the run output that view validation needs.
- See Publishing for the release workflow.