network.Network

network.Network(self, reaches)

A network of nodes and reaches, addressable by the names it came with.

A result file names a location the way the model did: a node id, or a reach and a distance along it. A graph needs one flat set of integers. A Network holds both - :attr:graph is the integer-labelled graph carrying the timeseries each location holds, and :meth:find and :meth:recall translate between the two namings.

Build one with :meth:open, which reads a result file, or by handing the constructor a sequence of :class:~mikeio1d.network.NetworkReach.

Attributes

Name Description
graph Graph of the network.
quantities Quantities present in data.
reaches The network’s reaches, by the id the model gave them.

Methods

Name Description
copy Create a deep copy of the Network.
find Find node or breakpoint id in the Network object based on former coordinates.
open Read a network from a result file.
recall Recover the original coordinates of an element given the node id(s) in the Network object.
to_dataframe Dataframe using node ids as column names.
to_dataset Dataset of the timeseries, with each node’s original identity alongside.

copy

network.Network.copy()

Create a deep copy of the Network.

Returns

Name Type Description
Network Deep copy of the Network object

find

network.Network.find(node=None, reach=None, distance=None)

Find node or breakpoint id in the Network object based on former coordinates.

Parameters

Name Type Description Default
node str | List[str] Node id(s) in the original network, by default None None
reach str | List[str] Reach id(s) for breakpoint lookup or reach endpoint lookup, by default None None
distance str | float | List[str | float] Distance(s) along reach for breakpoint lookup, or “start”/“end” for reach endpoints, by default None None

Returns

Name Type Description
int | List[int] Node or breakpoint id(s) in the generic network. A list argument is answered with a list, even a one-element one; a scalar argument with a scalar.

Raises

Name Type Description
ValueError If invalid combination of parameters is provided
KeyError If requested node/breakpoint is not found in the network

open

network.Network.open(
    res,
    *,
    companions=None,
    nodes=None,
    reaches=None,
    quantities=None,
)

Read a network from a result file.

Parameters

Name Type Description Default
res (str, Path or Res1D) Path to a .res1d, .res11 or .res result file, or an already-opened :class:~mikeio1d.Res1D. required
companions sequence of str, Path or Res1D, or None Files read alongside the result and recognised by their extension: * .resx – extra EPANET results for the same network. Its node quantities (tank Volume and Volume Percentage) are merged onto the matching nodes, and its reach quantities (pump efficiency, energy and energy costs) onto the matching reach’s breakpoints. * .inp – the EPANET input file, read for its [PIPES] lengths. No result file carries a reach length, so without this one no reach has one. None (default) looks for them beside the result file, matching its folder and stem; [] reads none; a list reads exactly those. Only EPANET results are looked beside. None
nodes str, list of str, or None Controls which nodes have their timeseries data loaded into memory. * None (default) – data is loaded for every node. * A single node ID or a list of node IDs – only those nodes get data; others are topology-only. * [] (empty list) – no node data is loaded at all. The full network topology is always constructed regardless of this setting, so find() and recall() still work on all nodes. None
reaches str, list of str, or None Controls which reaches have their intermediate gridpoint data populated. * None (default) – gridpoints are populated for every reach. * A single reach name or a list of reach names – only those reaches get gridpoint data; others are topology-only. * [] (empty list) – no gridpoint data is loaded at all. EPANET reaches have at most one gridpoint (see Notes), but this argument still governs whether its data, and any matching .resx reach quantities, are populated. None
quantities str, list of str, or None Controls which quantities are read at each selected location. * None (default) – every quantity is read. * A single quantity name or a list of names – only those are read. * [] (empty list) – no data is read at all. A location that does not carry a requested quantity becomes topology-only rather than an error, so this composes with nodes and reaches on files where nodes and reaches hold different quantities. None

Returns

Name Type Description
Network

Raises

Name Type Description
NotImplementedError If no network can be built from the file’s extension.
ValueError If a companion has an extension this reader does not know, if two companions of the same kind are given, or if a .resx does not come from the same run as the result file.

Examples

>>> from mikeio1d.network import Network
>>> network = Network.open("model.res1d")

Load data only for the two nodes where observations exist, and skip all intermediate gridpoint data to keep memory usage low:

>>> network = Network.open(
...     "model.res1d",
...     nodes=["node_a", "node_b"],
...     reaches=[],
... )

Read a single quantity, for a calibration loop that only scores discharge:

>>> network = Network.open("model.res1d", quantities="Discharge")

Name the companions rather than letting them be found:

>>> network = Network.open(
...     "model.res",
...     companions=["other.resx", "other.inp"],
... )

Notes

MIKE 11 keeps its timeseries on reach gridpoints rather than on nodes, so the nodes of a .res11 network carry no data of their own. Pass reaches rather than nodes to control what gets loaded.

An EPANET reach carries one synthetic gridpoint, which mikeio1d gives a breakpoint at each end so that the reach’s own quantities (Flow, Velocity, …) are reachable the way a MIKE reach’s end data is. As a result:

  • without the .inp, a reach’s length is unknown, so only its first breakpoint (distance=0.0) is real; the second is not addressable by distance at all – find(reach=..., distance=...) resolves it only via distance="start"/"end" (which return the node, not the breakpoint), or not at all by a number. The corresponding edges of :attr:graph are length=None
  • with the .inp, a pipe’s second breakpoint sits at its full length – both breakpoints are then addressable by distance, and the edge between them carries the pipe’s real length. Pumps and valves keep an unaddressable second breakpoint even so, since [PIPES] is the only section carrying lengths

Node timeseries, :meth:to_dataframe, :meth:to_dataset, find(node=...) and :meth:recall are unaffected.

recall

network.Network.recall(id)

Recover the original coordinates of an element given the node id(s) in the Network object.

Parameters

Name Type Description Default
id int | List[int] Node id(s) in the generic network required

Returns

Name Type Description
Dict[str, Any] | List[Dict[str, Any]] Original coordinates: a dict for a single id, a list of dicts for a list of ids, even a one-element one. Dict contains coordinates: - For nodes: ‘node’ key with node id - For breakpoints: ‘reach’ and ‘distance’ keys with reach id and distance

Raises

Name Type Description
KeyError If node id is not found in the network

to_dataframe

network.Network.to_dataframe(sel=None)

Dataframe using node ids as column names.

It will be multiindex unless ‘sel’ is passed.

Parameters

Name Type Description Default
sel Optional[str] Quantity to select, by default None None

Returns

Name Type Description
pd.DataFrame Timeseries contained in graph nodes

to_dataset

network.Network.to_dataset()

Dataset of the timeseries, with each node’s original identity alongside.

Returns

Name Type Description
xr.Dataset One variable per quantity over (time, node). node is the integer index the graph uses, and the name, reach and distance coordinates carry the names the model gave the same locations, so a consumer never has to hold on to the network to know what a column is:: Coordinates: * time datetime64 * node int64 0 1 2 3 … name <U16 ‘J1’ ‘J2’ ’’ ’’ reach <U16 ’’ ’’ ‘r1’ ‘r1’ distance float64 nan nan 0.0 24.5 Empty when no location carries data.