|
63 | 63 | ) |
64 | 64 | from ribasim.utils import ( |
65 | 65 | MissingOptionalModule, |
66 | | - _add_cf_attributes, |
67 | 66 | _concat, |
68 | 67 | _link_lookup, |
69 | 68 | _node_lookup, |
@@ -895,120 +894,3 @@ def _add_allocation(self, uds): |
895 | 894 | ) |
896 | 895 |
|
897 | 896 | return uds |
898 | | - |
899 | | - def to_fews( |
900 | | - self, |
901 | | - region_home: str | PathLike[str], |
902 | | - add_network: bool = True, |
903 | | - add_results: bool = True, |
904 | | - ) -> None: |
905 | | - """ |
906 | | - Write the model network and results into files used by Delft-FEWS. |
907 | | -
|
908 | | - ** Warning: This method is experimental and is likely to change. ** |
909 | | -
|
910 | | - To run this method, the model needs to be written to disk, and have results. |
911 | | - The Node, Link and Basin / area tables are written to shapefiles in the REGION_HOME/Config directory. |
912 | | - The results are written to NetCDF files in the REGION_HOME/Modules directory. |
913 | | - The netCDF files are NetCDF4 with CF-conventions. |
914 | | -
|
915 | | - Parameters |
916 | | - ---------- |
917 | | - region_home: str | PathLike[str] |
918 | | - Path to the Delft-FEWS REGION_HOME directory. |
919 | | - add_network: bool, optional |
920 | | - Write shapefiles representing the network, enabled by default. |
921 | | - add_results: bool, optional |
922 | | - Write the results to NetCDF files, enabled by default. |
923 | | - """ |
924 | | - region_home = DirectoryPath(region_home) |
925 | | - if add_network: |
926 | | - self._network_to_fews(region_home) |
927 | | - if add_results: |
928 | | - self._results_to_fews(region_home) |
929 | | - |
930 | | - def _network_to_fews(self, region_home: DirectoryPath) -> None: |
931 | | - """Write the Node and Link tables to shapefiles for use in Delft-FEWS.""" |
932 | | - df_link = self.link.df |
933 | | - df_node = self.node.df |
934 | | - assert df_link is not None |
935 | | - assert df_node is not None |
936 | | - |
937 | | - df_basin_area = self.basin.area.df |
938 | | - if df_basin_area is None: |
939 | | - # Fall back to the Basin points if the area polygons are not set |
940 | | - df_basin_area = df_node[df_node["node_type"] == "Basin"] |
941 | | - |
942 | | - network_dir = region_home / "Config/MapLayerFiles/{ModelId}" |
943 | | - network_dir.mkdir(parents=True, exist_ok=True) |
944 | | - link_path = network_dir / "{ModelId}Links.shp" |
945 | | - node_path = network_dir / "{ModelId}Nodes.shp" |
946 | | - basin_area_path = network_dir / "{ModelId}Areas.shp" |
947 | | - |
948 | | - with warnings.catch_warnings(): |
949 | | - warnings.filterwarnings( |
950 | | - "ignore", "Normalized/laundered field name", RuntimeWarning |
951 | | - ) |
952 | | - warnings.filterwarnings( |
953 | | - "ignore", |
954 | | - "Column names longer than 10 characters will be truncated when saved to ESRI Shapefile.", |
955 | | - UserWarning, |
956 | | - ) |
957 | | - df_link.to_file(link_path) |
958 | | - df_node.to_file(node_path) |
959 | | - df_basin_area.to_file(basin_area_path) |
960 | | - |
961 | | - def _results_to_fews(self, region_home: DirectoryPath) -> None: |
962 | | - """Convert the model results to NetCDF with CF-conventions for importing into Delft-FEWS.""" |
963 | | - # Delft-FEWS doesn't support our UGRID from `model.to_xugrid` yet, |
964 | | - # so we convert Arrow to regular CF-NetCDF4. |
965 | | - |
966 | | - ext = self.results_extension |
967 | | - basin_path = self.results_path / f"basin{ext}" |
968 | | - flow_path = self.results_path / f"flow{ext}" |
969 | | - concentration_path = self.results_path / f"concentration{ext}" |
970 | | - |
971 | | - if ext == ".arrow": |
972 | | - basin_df = pd.read_feather(basin_path) |
973 | | - flow_df = pd.read_feather(flow_path) |
974 | | - else: |
975 | | - basin_df = xr.open_dataset(basin_path).to_dataframe().reset_index() |
976 | | - flow_df = xr.open_dataset(flow_path).to_dataframe().reset_index() |
977 | | - |
978 | | - ds_basin = basin_df.set_index(["time", "node_id"]).to_xarray() |
979 | | - _add_cf_attributes(ds_basin, timeseries_id="node_id") |
980 | | - ds_basin["level"].attrs.update({"units": "m"}) |
981 | | - ds_basin["storage"].attrs.update({"units": "m3"}) |
982 | | - ds_basin["relative_error"].attrs.update({"units": "1"}) |
983 | | - |
984 | | - flow_rate_variables = [ |
985 | | - "inflow_rate", |
986 | | - "outflow_rate", |
987 | | - "storage_rate", |
988 | | - "precipitation", |
989 | | - "evaporation", |
990 | | - "drainage", |
991 | | - "infiltration", |
992 | | - "balance_error", |
993 | | - ] |
994 | | - for var in flow_rate_variables: |
995 | | - ds_basin[var].attrs.update({"units": "m3 s-1"}) |
996 | | - |
997 | | - ds_flow = flow_df.set_index(["time", "link_id"]).to_xarray() |
998 | | - _add_cf_attributes(ds_flow, timeseries_id="link_id") |
999 | | - ds_flow["flow_rate"].attrs.update({"units": "m3 s-1"}) |
1000 | | - |
1001 | | - results_dir = region_home / "Modules/ribasim/{ModelId}/work/results" |
1002 | | - results_dir.mkdir(parents=True, exist_ok=True) |
1003 | | - ds_basin.to_netcdf(results_dir / "basin.nc") |
1004 | | - ds_flow.to_netcdf(results_dir / "flow.nc") |
1005 | | - |
1006 | | - if concentration_path.is_file(): |
1007 | | - if ext == ".arrow": |
1008 | | - df = pd.read_feather(concentration_path) |
1009 | | - else: |
1010 | | - df = xr.open_dataset(concentration_path).to_dataframe().reset_index() |
1011 | | - ds = df.set_index(["time", "node_id", "substance"]).to_xarray() |
1012 | | - _add_cf_attributes(ds, timeseries_id="node_id", realization="substance") |
1013 | | - ds["concentration"].attrs.update({"units": "g m-3"}) |
1014 | | - ds.to_netcdf(results_dir / "concentration.nc") |
0 commit comments