Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show allocation flows on the map in QGIS #1066

Closed
SouthEndMusic opened this issue Feb 2, 2024 · 3 comments · Fixed by #1478
Closed

Show allocation flows on the map in QGIS #1066

SouthEndMusic opened this issue Feb 2, 2024 · 3 comments · Fixed by #1478
Assignees
Labels
allocation Allocation layer QGIS Ribasim QGIS plugin

Comments

@SouthEndMusic
Copy link
Collaborator

SouthEndMusic commented Feb 2, 2024

What
In addition to #969, we also want to be able to visualize the allocation flows who have their own output file introduced in #1012. There are some notable distinctions between allocation flow and physical flow:

  • Allocation flow is given per priority;
  • If the model has a main network and subnetworks, for the subnetworks there is both a demand collecting flow and an actual allocating flow per edge (distinguished using the boolean column collect_demands);
  • Edges connecting the main network to a subnetwork are considered to be both part of the main network and the subnetwork;
  • It can seem that the water balance isn't closed around the main network to subnetwork connection. This is because all flow allocated to a subnetwork is redistributed over priorities within the subnetwork.

Best done after #1399.

@SouthEndMusic SouthEndMusic added QGIS Ribasim QGIS plugin allocation Allocation layer improvement labels Feb 2, 2024
@github-project-automation github-project-automation bot moved this to To do in Ribasim Feb 2, 2024
@SnippenE SnippenE moved this from To do to What's next in Ribasim Feb 15, 2024
@visr visr moved this from What's next to Sprint backlog in Ribasim Apr 23, 2024
@visr
Copy link
Member

visr commented Apr 23, 2024

This should be added to to_xugrid from #1369. One possible issue is that the time dimension is different, since saveat and allocation_timestep is not the same. Not sure what is better, to write a separate UGrid file, or to have two time dimensions in there.

@Huite
Copy link
Contributor

Huite commented Apr 23, 2024

This might be constrained by what QGIS and MDAL accept. It might be that "time" is special cased as a literal label.

In that case, the only option is a separate file.

@Jingru923 Jingru923 moved this from Sprint backlog to To do in Ribasim May 2, 2024
@Jingru923 Jingru923 moved this from To do to What's next in Ribasim May 2, 2024
@visr visr self-assigned this May 16, 2024
@visr visr moved this from What's next to 🏗 In progress in Ribasim May 16, 2024
@visr
Copy link
Member

visr commented May 16, 2024

It looks like a separate file is needed. Allocation flow has 4 dimensions:

  1. time
  2. edge
  3. optimization_type (one of the 3 given in https://deltares.github.io/Ribasim/core/allocation.html#the-high-level-algorithm)
  4. priority

As discussed with @JoerivanEngelen the 3rd and 4th dimension needs to be added in the variable name of variables with dimension 1 and 2 only. To allow users to select one. So I used varname = f"{optimization_type}_priority_{priority}". Also discussed with @SouthEndMusic to add a variable I now call flow_rate_allocated, which is optimization_type = allocate and the sum over all priorities.

I'm not sure what's the best API. We need model.to_xugrid(add_results=False) to avoid the other time dimension in the same file. I suppose we could do model.to_xugrid(add_results=False, add_allocation_results=True), but open to other ideas.

import ribasim

model = ribasim.Model.read(toml_path)
uds = model.to_xugrid(add_results=False)

results_path = toml_path.parent / model.results_dir
alloc_flow_path = results_path / "allocation_flow.arrow"
alloc_flow_df = pd.read_feather(
    alloc_flow_path,
    columns=["time", "edge_id", "flow_rate", "optimization_type", "priority"],
)

edge_dim = uds.grid.edge_dimension
node_dim = uds.grid.node_dimension

# from edge_id to the edge_dim index
edge_lookup = pd.Series(
    index=uds["edge_id"],
    data=uds[edge_dim],
    name="edge_index",
)

alloc_flow_df[edge_dim] = edge_lookup[alloc_flow_df["edge_id"]].to_numpy()
alloc_flow_df["time"] = alloc_flow_df["time"].astype("datetime64[ns]")

# "flow_rate_allocated" is the sum of all allocated flow rates over the priorities
allocate_df = alloc_flow_df.loc[alloc_flow_df["optimization_type"] == "allocate"]
uds["flow_rate_allocated"] = (
    allocate_df.groupby(["time", edge_dim])["flow_rate"].sum().to_xarray()
)

# also add the individual priorities and optimization types
# added as separate variables to ensure QGIS / MDAL compatibility
for (optimization_type, priority), group in alloc_flow_df.groupby(
    ["optimization_type", "priority"]
):
    varname = f"{optimization_type}_priority_{priority}"
    da = group.set_index(["time", edge_dim])["flow_rate"].to_xarray()
    uds[varname] = da

uds.ugrid.to_netcdf(toml_path.parent / "results" / "ugrid_allocation.nc")

visr added a commit that referenced this issue May 21, 2024
Fixes #1066, see
#1066 (comment)
for more information on the approach used here. I just modified the
keywords a bit, defaulting to `to_xugrid(add_flow = False,
add_allocation = False)`. That means there are three options resulting
in three different datasets:

```python
import ribasim

model = ribasim.Model.read(toml_path)
uds = model.to_xugrid()
uds.ugrid.to_netcdf(toml_path.parent / "results" / "ugrid-network.nc")
uds = model.to_xugrid(add_flow=True)
uds.ugrid.to_netcdf(toml_path.parent / "results" / "ugrid-flow.nc")
uds = model.to_xugrid(add_allocation=True)
uds.ugrid.to_netcdf(toml_path.parent / "results" / "ugrid-allocation.nc")
```

The last `uds`, with `add_allocation=True`, looks like this in xugrid /
xarray:


![image](https://github.com/Deltares/Ribasim/assets/4471859/69d2f63a-1a44-44a1-b4f0-47403ff85091)

And like this in QGIS, this is for `main_network_with_subnetworks`:


![image](https://github.com/Deltares/Ribasim/assets/4471859/57e783f0-179f-4415-b609-d60d6c44ba40)

I refactored the code a bit to avoid duplication.
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in Ribasim May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
allocation Allocation layer QGIS Ribasim QGIS plugin
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants