Skip to content

Commit

Permalink
Restore some of ResultNetwork creation performance. (#130)
Browse files Browse the repository at this point in the history
Co-authored-by: Gediminas Kirsanskas <geki@dhigroup.com>
  • Loading branch information
gedaskir and Gediminas Kirsanskas authored Nov 6, 2024
1 parent d9cb69e commit 018089e
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 15 deletions.
43 changes: 35 additions & 8 deletions mikeio1d/quantities/timeseries_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import pandas as pd

from ..various import NAME_DELIMITER
from ..various import DELETE_VALUE

from DHI.Mike1D.ResultDataAccess import ItemTypeGroup

Expand Down Expand Up @@ -428,25 +429,51 @@ def create_reach_span_tag(m1d_dataset) -> str:
start_gp = m1d_dataset.GridPoints[0]
end_gp = m1d_dataset.GridPoints[m1d_dataset.GridPoints.Count - 1]

tag = f"{start_gp.Chainage:.1f}-{end_gp.Chainage:.1f}"
tag = TimeSeriesId.create_reach_span_tag_from_gridpoints(start_gp, end_gp)
return tag

@staticmethod
def create_reach_span_tag_from_gridpoints(start_gp, end_gp) -> str:
"""Create a tag for an IRes1DReach object based on its start and end gridpoints.
Parameters
----------
start_gp : IRes1DGridPoint
The MIKE 1D gridpoint at the start of the reach.
end_gp : IRes1DGridPoint
The MIKE 1D gridpoint at the end of the reach.
Returns
-------
str
The tag for the reach (e.g. '0.0-100.0')
"""
return f"{start_gp.Chainage:.1f}-{end_gp.Chainage:.1f}"

@staticmethod
def from_result_quantity(result_quantity: ResultQuantity) -> TimeSeriesId:
"""Create a TimeSeriesId object from a ResultQuantity object.
Note: this method assumes there are no duplicates (e.g. duplicate = 0). To get the
unique TimeSeriesId of a ResultQuantity, access its timeseries_id property.
"""
m1d_dataitem = result_quantity.data_item
m1d_dataset = result_quantity.m1d_dataset
element_index = result_quantity.element_index
result_location = result_quantity.result_location
nan = float("nan")

timeseries_id = TimeSeriesId.from_dataset_dataitem_and_element(
m1d_dataset, m1d_dataitem, element_index
)
group = result_location._group
quantity = result_quantity._name
name = getattr(result_location, "_name", "")
tag = getattr(result_location, "_tag", "")
chainage = getattr(result_location, "chainage", nan)
chainage = nan if chainage == DELETE_VALUE else chainage

return timeseries_id
return TimeSeriesId(
quantity=quantity,
group=group,
name=name,
chainage=chainage,
tag=tag,
)

@staticmethod
def get_dataset_name(m1d_dataset, item_id=None, delimiter=NAME_DELIMITER) -> str:
Expand Down
1 change: 1 addition & 0 deletions mikeio1d/result_network/result_catchment.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ResultCatchment(ResultLocation):
def __init__(self, catchment, res1d):
ResultLocation.__init__(self, catchment.DataItems, res1d)
self._group = TimeSeriesIdGroup.CATCHMENT
self._name = catchment.Id
self._catchment = catchment
self.set_quantities()
self.set_static_attributes()
Expand Down
7 changes: 6 additions & 1 deletion mikeio1d/result_network/result_gridpoint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""ResultGridPoint class."""

from ..query import QueryDataReach
from ..quantities import TimeSeriesIdGroup
from .result_location import ResultLocation


Expand All @@ -27,9 +28,13 @@ class ResultGridPoint(ResultLocation):
"""

def __init__(self, reach, gridpoint, data_items, result_reach, res1d):
def __init__(self, reach, gridpoint, data_items, result_reach, res1d, tag=""):
empty_data_item_list = []
ResultLocation.__init__(self, empty_data_item_list, res1d)
self._group = TimeSeriesIdGroup.REACH
self._name = reach.Name
self._chainage = gridpoint.Chainage
self._tag = tag
self.reach = reach
self.gridpoint = gridpoint
self.result_reach = result_reach
Expand Down
2 changes: 2 additions & 0 deletions mikeio1d/result_network/result_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class ResultLocation(ABC):
"""

def __init__(self, data_items, res1d: Res1D):
self._name = ""
self._tag = ""
self.data_items = data_items
self.res1d = res1d
self.quantity_label = "q_"
Expand Down
1 change: 1 addition & 0 deletions mikeio1d/result_network/result_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ResultNode(ResultLocation):
def __init__(self, node, res1d):
ResultLocation.__init__(self, node.DataItems, res1d)
self._group = TimeSeriesIdGroup.NODE
self._name = node.ID
self._node = node
self.set_quantities()
self.set_static_attributes()
Expand Down
18 changes: 15 additions & 3 deletions mikeio1d/result_network/result_reach.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .result_gridpoint import ResultGridPoint
from .various import make_proper_variable_name
from ..various import try_import_shapely
from ..quantities import TimeSeriesId
from ..quantities import TimeSeriesIdGroup
from ..dotnet import pythonnet_implementation as impl

Expand Down Expand Up @@ -252,11 +253,22 @@ def set_gridpoints(self, reach):
self.set_gridpoint(reach, gridpoint)

gridpoints = list(reach.GridPoints)
tag = self.create_reach_span_tag(gridpoints)
for i in range(gridpoint_count):
gridpoint = gridpoints[i]
self.set_gridpoint(reach, gridpoint)
self.set_gridpoint(reach, gridpoint, tag)

def create_reach_span_tag(self, gridpoints):
"""Create reach span tag to be set on ResultGridPoint."""
if len(gridpoints) == 0:
return ""

start_gp = gridpoints[0]
end_gp = gridpoints[-1]
tag = TimeSeriesId.create_reach_span_tag_from_gridpoints(start_gp, end_gp)
return tag

def set_gridpoint(self, reach, gridpoint):
def set_gridpoint(self, reach, gridpoint, tag=""):
"""Assign chainage attribute to a current ResultReach object from a data provided by IRes1DReach and IRes1DGridPoint.
Parameters
Expand All @@ -269,7 +281,7 @@ def set_gridpoint(self, reach, gridpoint):
"""
current_reach_result_gridpoints = self.current_reach_result_gridpoints

result_gridpoint = ResultGridPoint(reach, gridpoint, reach.DataItems, self, self.res1d)
result_gridpoint = ResultGridPoint(reach, gridpoint, reach.DataItems, self, self.res1d, tag)
current_reach_result_gridpoints.append(result_gridpoint)

chainage_string = f"{gridpoint.Chainage:g}"
Expand Down
2 changes: 2 additions & 0 deletions mikeio1d/result_network/result_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def __init__(self, structure_id, reach, data_items, res1d):
ResultLocation.__init__(self, empty_list, res1d)

self._group = TimeSeriesIdGroup.STRUCTURE
self._name = structure_id
self._tag = reach.Name
self.id = structure_id
self.reach = reach
self.chainage = None
Expand Down
2 changes: 0 additions & 2 deletions mikeio1d/result_query/query_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ class QueryData(ABC):
"""

delete_value = -1e-30

def __init__(self, quantity, name=None, validate=True):
self._name = name
self._quantity = quantity
Expand Down
3 changes: 2 additions & 1 deletion mikeio1d/result_query/query_data_reach.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from math import isnan

from ..various import NAME_DELIMITER
from ..various import DELETE_VALUE
from .query_data import QueryData
from ..quantities import TimeSeriesId
from ..quantities import TimeSeriesIdGroup
Expand Down Expand Up @@ -140,6 +141,6 @@ def __repr__(self):

return (
NAME_DELIMITER.join([quantity, name, f"{chainage:g}"])
if chainage is not None and chainage != self.delete_value
if chainage is not None and chainage != DELETE_VALUE
else NAME_DELIMITER.join([quantity, name])
)
1 change: 1 addition & 0 deletions mikeio1d/various.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from DHI.Mike1D.Generic import PredefinedQuantity

NAME_DELIMITER = ":"
DELETE_VALUE = -1e-30


def mike1d_quantities():
Expand Down

0 comments on commit 018089e

Please sign in to comment.