NodeObservation
NodeObservation(
data,
*,
at,
item=None,
name=None,
weight=1.0,
quantity=None,
aux_items=None,
attrs=None,
position_tol=None,
)Class for observations at network nodes.
Create a NodeObservation from a DataFrame or other data source. The at parameter accepts two forms:
- str — the node’s name in the model (e.g. a Res1D node name).
- tuple[str, float] — a breakpoint, as
(reach_id, position)along a reach.
Both are resolved against the network when the observation is matched.
.. note:: “Node” in this API follows the broad graph sense: it covers both junctions (named connection points) and chainage points (breakpoints along a reach). MIKE 1D users who distinguish node (junction) from gridpoint sharply can use the (reach_id, position) tuple form to target a specific chainage point, or :class:ReachObservation when the quantity is uniform across the whole reach and any breakpoint will do.
To create multiple NodeObservation objects from a single data source, use :meth:from_multiple.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | (str, Path, mikeio.Dataset, mikeio.DataArray, pd.DataFrame, pd.Series, xr.Dataset or xr.DataArray) | data source with time series for the node | required |
| at | str or tuple[str, float] | Observation location. Accepted forms: * str — the node’s name in the model (e.g. a Res1D node name). * tuple[str, float] — a breakpoint, as (reach_id, position). |
required |
| item | (int, str) | index or name of the wanted item/column, by default None if data contains more than one item, item must be given | None |
| name | str | user-defined name for easy identification in plots etc, by default derived from data | None |
| weight | float | weighting factor for skill scores, by default 1.0 | 1.0 |
| quantity | Quantity | The quantity of the observation, for validation with model results | None |
| aux_items | list | list of names or indices of auxiliary items, by default None | None |
| attrs | dict | additional attributes to be added to the data, by default None | None |
| position_tol | float | How far the position in at may be from a model breakpoint and still match it. The nearest breakpoint inside it that carries the model result’s item is used. By default None, which absorbs only rounding (mikeio1d’s 1e-3). Ignored for a node name. |
None |
Raises
| Name | Type | Description |
|---|---|---|
| ValueError | If position_tol is negative or not finite. |
Examples
>>> import modelskill as ms
>>> o1 = ms.NodeObservation(data, at="123", name="123")
>>> o2 = ms.NodeObservation(df, item="Water Level", at="456")
>>>
>>> # String alias resolved at match time
>>> o3 = ms.NodeObservation(data, at="node_A")
>>>
>>> # Breakpoint as (reach_id, position) tuple
>>> o4 = ms.NodeObservation(data, at=("reach_1", 24.5))
>>>
>>> # A measured chainage, snapped onto the nearest breakpoint within 0.5
>>> o5 = ms.NodeObservation(data, at=("reach_1", 24.0), position_tol=0.5)
>>>
>>> # Multiple node observations from separate data sources
>>> obs = ms.NodeObservation.from_multiple(nodes={"123": df1, "456": df2})Attributes
| Name | Description |
|---|---|
| at | Observation location: a node name, or a (reach_id, position) breakpoint. |
| attrs | Attributes of the observation |
| gtype | Geometry type |
| n_points | Number of data points |
| name | Name of time series (value item name) |
| node | Name of the node this observation sits at, or None for a break point. |
| plot | Plot using the ComparerPlotter |
| quantity | Quantity of time series |
| time | Time index |
| values | Values as numpy array |
| weight | Weighting factor for skill scores |
| x | x-coordinate |
| y | y-coordinate |
Methods
| Name | Description |
|---|---|
| copy | Create a deep copy of the TimeSeries. |
| equals | Check if two TimeSeries are equal |
| from_multiple | Create multiple NodeObservation objects. |
| sel | Select data by label |
| to_dataframe | Convert matched data to pandas DataFrame |
| trim | Trim observation data to a given time interval |
copy
NodeObservation.copy()Create a deep copy of the TimeSeries.
Returns
| Name | Type | Description |
|---|---|---|
| TimeSeries | Deep copy of the TimeSeries object |
equals
NodeObservation.equals(other)Check if two TimeSeries are equal
from_multiple
NodeObservation.from_multiple(
data=None,
nodes=None,
quantity=None,
aux_items=None,
attrs=None,
position_tol=None,
)Create multiple NodeObservation objects.
Two calling conventions are supported:
Separate data sources — pass only
nodesas a dict mapping each node ID to its own data source (file path, DataFrame, etc.)::obs = NodeObservation.from_multiple(nodes={"123": df1, "456": "sensor.csv"})Shared data source — pass a single
dataobject together withnodesas a dict mapping each node ID to the column name or index to select fromdata::obs = NodeObservation.from_multiple(data=df, nodes={"123": "col_a", "456": "col_b"})
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | PointType | Shared data source (required when nodes values are column selectors). |
None |
| nodes | dict[str | tuple[str, float], PointType | str | int] | Mapping of location -> data source or column selector. A location takes either of the forms accepted by at: a node name, or a (reach_id, position) breakpoint. Note that a location can appear only once, so this form cannot express several observations at the same node. |
None |
| quantity | Quantity | Physical quantity metadata, by default None. | None |
| aux_items | list[int | str] | None | Auxiliary items, by default None. | None |
| attrs | dict | None | Additional attributes, by default None. | None |
| position_tol | float | Tolerance for every breakpoint position, as in NodeObservation, by default None. |
None |
Returns
| Name | Type | Description |
|---|---|---|
| list[NodeObservation] | List of NodeObservation objects. |
Raises
| Name | Type | Description |
|---|---|---|
| ValueError | If nodes is not given. |
sel
NodeObservation.sel(**kwargs)Select data by label
to_dataframe
NodeObservation.to_dataframe()Convert matched data to pandas DataFrame
Include x, y coordinates only if gtype=track
Returns
| Name | Type | Description |
|---|---|---|
| pd.DataFrame | data as a pandas DataFrame |
trim
NodeObservation.trim(
start_time=None,
end_time=None,
buffer='1s',
no_overlap='error',
)Trim observation data to a given time interval
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| start_time | pd.Timestamp | start time | None |
| end_time | pd.Timestamp | end time | None |
| buffer | str | buffer time around start and end time, by default “1s” | '1s' |
| no_overlap | Literal['ignore', 'error', 'warn'] | Empty data handling. | 'error' |