Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Post-Simulation Analytics

After a run, Hydra can derive higher-level metrics from the saved results. There are three surfaces:

  • Programmatic analytics (SDK) — two on-demand modules, demand reliability and service compliance, that read a saved .out file and return a structured report.
  • Report blocks (SDK) — a catalog of named, self-contained content blocks that render into txt/csv/html/PDF documents. Several of them are built on the two modules above, which is how those metrics reach a generated report. See SDK Overview.
  • The GUI Analysis tab — an interactive dashboard computed separately from the same results.

The CLI exposes report blocks through its report subcommand (CLI) but not the two modules directly. The GUI uses report blocks for its generated reports, while its Analysis tab computes its own dashboard rather than calling the two modules.


Report blocks

The water distribution engine publishes thirteen blocks. Each is self-contained: it carries its own heading and renders identically in every output format.

Block idHeadingContents
wds.run-summaryRun SummaryNetwork size, reporting window, units, and quality mode
wds.result-extremesResult ExtremesGlobal minimum and maximum pressure, head, demand, flow, and velocity
wds.pump-energyPump EnergyPer-pump utilization, efficiency, power, and cost, plus network totals
wds.quality-summaryWater Quality SummaryQuality mode and global quality extremes
wds.service-compliancePressure AdequacyJunction-pressure compliance against a minimum (and optional maximum)
wds.demand-reliabilityDemand ReliabilityDelivered-vs-required volumes and the reliability ratio
wds.pressure-distributionPressure DistributionDistribution of each junction’s minimum pressure
wds.velocity-distributionVelocity DistributionDistribution of each pipe’s maximum velocity
wds.pressure-thresholdsPressure ThresholdsJunction minimum pressure counted into caller-supplied bands
wds.velocity-thresholdsVelocity ThresholdsPipe maximum velocity counted into caller-supplied bands
wds.tank-levelsTank LevelsHydraulic head of each tank over the reporting horizon
wds.mass-balanceMass BalanceCumulative inflow and outflow with closure percentage
wds.pipe-criticalityPipe CriticalityPipes ranked by peak velocity

A block that does not apply to a run is not dropped: it renders as a placeholder section under its normal heading, carrying the reason. Asking for wds.pump-energy on a network with no pumps yields a Pump Energy section reading [not available: the network has no pumps]. This is deliberate — a requested section that silently vanished would be indistinguishable from one that was never requested.

Some blocks accept options — the *-thresholds pair takes its band edges, and several take a worstCount for their worst-performing tables. report_block_options(id, network) describes what a given block accepts, including labels, defaults, and bounds, so an interface can build an editor for it without hardcoding the list.

Templates

A template is the saved answer to “what goes in my report”: a document title plus an ordered list of block references. The GUI’s template builder and the CLI’s --template flag read the same JSON.

{
  "version": 1,
  "title": "Quarterly hydraulic report",
  "blocks": [
    { "id": "wds.run-summary" },
    { "id": "wds.pump-energy", "title": "Pumping cost" },
    { "id": "wds.pressure-thresholds", "options": { "edges": [20, 40, 60] } }
  ]
}
FieldRequiredMeaning
versionyesTemplate format version. Must be 1; any other value is rejected with a typed error
titleyesDocument title. Plain text, must not be empty
blocksnoOrdered block references. Defaults to empty, which yields a document with no sections
blocks[].idyesA block id from the table above
blocks[].titlenoHeading override, replacing the block’s default heading
blocks[].optionsnoPer-block options, passed to the engine verbatim — this is how the *-thresholds blocks receive their band edges

Unknown fields are ignored on read, so a template written by a newer Hydra still loads. An id that is not in the catalog is not an error: it renders as a placeholder section headed with the id itself, so a mistyped id is visible in the output rather than silently dropped.

Omit --template entirely to get every block that applies to the run.

Formats

The same document renders four ways, and the differences are presentational rather than editorial — every format carries the same sections in the same order.

FormatNotes
txtFixed-width columns; reads correctly in a monospace viewer
csvRFC 4180 quoting, full numeric precision
htmlOne self-contained file — inline CSS, no external resources, no scripts
pdfA4, numbered 3 / 12 in the bottom margin, and a running header naming the document and what it was produced from on every page after the first

Only the PDF is typeset, so only it paginates: a section heading is never left as the last thing on a page, and a table continuing onto another page repeats its column header. A long table still breaks where it falls — sections are not forced onto fresh pages.


Demand reliability (SDK)

Measures how well the network delivered the demand that was asked of it, per junction and network-wide.

Entry points (see SDK Examples):

#![allow(unused)]
fn main() {
compute_demand_reliability_from_out(out_path, &network) -> DemandReliabilityReport
compute_demand_reliability_from_out_with_options(out_path, &network, options)
}

It needs both the .out file and the loaded Network (the network supplies the demand categories and patterns used to recompute required demand). Only junction nodes are analysed.

What it computes, per reporting period and junction:

  • Required demand (from the model) and delivered demand (from the .out file), each accumulated into a volume.
  • Unmet volume (required − delivered, clamped at zero) and surplus volume (delivered − required, non-zero only under PDA when pressure exceeds the required-pressure threshold).
  • Deficit periods — the number of periods where the shortfall exceeded the deficit tolerance — plus the longest consecutive deficit streak and the maximum instantaneous deficit rate.

Reliability ratio = served ÷ required volume, in [0, 1] (reported per node and for the whole network).

OptionsDemandReliabilityOptions { deficit_tolerance }: shortfalls below this rate (m³/s) are not counted as deficit periods, though their volume still accumulates. Default 1e-9.

Units: volumes in m³, rates in m³/s, times in seconds (internal SI). The report also records the model’s demand model (DDA or PDA) — under DDA delivered ≈ required, so reliability is mainly meaningful under PDA or when checking a deficit scenario.


Service compliance (SDK)

Measures how often junction pressures stayed within acceptable bounds.

Entry point (see SDK Examples):

#![allow(unused)]
fn main() {
compute_service_compliance_from_out(out_path, thresholds) -> ServiceComplianceReport
}

It reads only the .out file (junction membership comes from the file’s node table). Only junction nodes are analysed — reservoirs and tanks are excluded so they don’t register as permanent violations.

ThresholdsServiceComplianceThresholds { min_pressure, max_pressure }: min_pressure is required; max_pressure is optional (None disables the upper-bound check). Use ServiceComplianceThresholds::min_only(p) for a lower bound only. When set, max_pressure must be strictly greater than min_pressure.

What it computes, per period and junction:

  • Sample counts: within limits, below minimum, above maximum.
  • Deficit / excess integrals — pressure shortfall or excess accumulated over time (m·s).
  • Worst observed deficit and excess (m), and the longest consecutive violation streak.

The summary aggregates these across all junctions and periods and reports a compliance ratio (fraction of in-limit samples). Pressures use the units stored in the .out file (metres of head for Hydra output).


The GUI Analysis tab

The Analysis tab computes its own dashboard from the scenario’s results (a histogram/summary pass, independent of the two SDK modules above). It has six panels:

PanelShows
System SummaryMetric chips: minimum pressure (and where), maximum velocity (and where), a pressure-compliance percentage, total pump energy, and mass-balance closure
HistogramsDistribution of per-junction minimum pressure and per-pipe maximum velocity. Pumps and valves are excluded from the velocity population — they have no pipe velocity, and counting them would bank a spurious zero each
Pipe CriticalityThe top pipes ranked by peak velocity, with diameter and end nodes
Audit PanelsMass-balance audit (cumulative inflow/outflow, closure, trend) and energy audit (pump energy, specific energy, peak power)
Tank LevelsPer-tank head over the simulation horizon
Pump EnergyPer-pump average power, with total energy and cost

Availability

SurfaceReliability / compliance modulesReport blocksGUI Analysis dashboard
SDK (hydra-sdk)✅ direct
CLI✅ via report blockshydra report
GUI✅ via report blocks