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 viadistance="start"/"end"(which return the node, not the breakpoint), or not at all by a number. The corresponding edges of :attr:grapharelength=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. |