From 6f13005c269f048d3f0f606073652c343d3992bd Mon Sep 17 00:00:00 2001 From: Angus Date: Thu, 26 Sep 2024 13:31:02 +0100 Subject: [PATCH 01/10] Add ability to input single demand from giw/dict --- wntr/network/base.py | 2 +- wntr/network/elements.py | 31 ++++++++++++++++++++++++++++++- wntr/network/io.py | 10 +++++----- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/wntr/network/base.py b/wntr/network/base.py index c2229469f..a569ab046 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -257,7 +257,7 @@ def to_dict(self): d['node_type'] = self.node_type for k in dir(self): if not k.startswith('_') and \ - k not in ['demand', 'base_demand', 'head', 'leak_area', 'leak_demand', + k not in ['demand', 'head', 'leak_area', 'leak_demand', 'leak_discharge_coeff', 'leak_status', 'level', 'pressure', 'quality', 'vol_curve', 'head_timeseries']: try: val = getattr(self, k) diff --git a/wntr/network/elements.py b/wntr/network/elements.py index 28e3e7fe8..561676ff0 100644 --- a/wntr/network/elements.py +++ b/wntr/network/elements.py @@ -81,7 +81,10 @@ class Junction(Node): _base_attributes = ["name", "elevation", "coordinates"] - _optional_attributes = ["emitter_coefficient", + _optional_attributes = ["base_demand", + "demand_pattern", + "demand_category", + "emitter_coefficient", "initial_quality", "minimum_pressure", "required_pressure", @@ -216,6 +219,32 @@ def base_demand(self): def base_demand(self, value): raise RuntimeWarning('The base_demand property is read-only. Please modify using demand_timeseries_list[0].base_value.') + @property + def demand_pattern(self): + """Get the pattern_name of the first demand in the demand_timeseries_list. + + This is a read-only property. + """ + if len(self.demand_timeseries_list) > 0: + return self.demand_timeseries_list[0].pattern_name + return 0.0 + @demand_pattern.setter + def demand_pattern(self, value): + raise RuntimeWarning('The demand_pattern property is read-only. Please modify using demand_timeseries_list[0].pattern_name') + + @property + def demand_category(self): + """Get the category of the first demand in the demand_timeseries_list. + + This is a read-only property. + """ + if len(self.demand_timeseries_list) > 0: + return self.demand_timeseries_list[0].category + return 0.0 + @demand_category.setter + def demand_category(self, value): + raise RuntimeWarning('The demand_category property is read-only. Please modify using demand_timeseries_list[0].category.') + def add_leak(self, wn, area, discharge_coeff=0.75, start_time=None, end_time=None): """ Add a leak control to the water network model diff --git a/wntr/network/io.py b/wntr/network/io.py index 83bca2cf0..776901bd1 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -117,18 +117,18 @@ def from_dict(d: dict, append=None): if dl is not None and len(dl) > 0: base_demand = dl[0].setdefault("base_val", 0.0) pattern_name = dl[0].setdefault("pattern_name") - category = dl[0].setdefault("category") + demand_category = dl[0].setdefault("category") else: - base_demand = 0.0 - pattern_name = None - category = None + base_demand = node.setdefault('base_demand',0.0) + pattern_name = node.setdefault('pattern_name') + demand_category = node.setdefault('demand_category') wn.add_junction( name=name, base_demand=base_demand, demand_pattern=pattern_name, elevation=node.setdefault("elevation"), coordinates=node.setdefault("coordinates", list()), - demand_category=category, + demand_category=demand_category, ) j = wn.get_node(name) j.emitter_coefficient = node.setdefault("emitter_coefficient") From 7c62655c5d84fbc2b82a05517064f6925a14235b Mon Sep 17 00:00:00 2001 From: Angus Date: Thu, 26 Sep 2024 14:54:48 +0100 Subject: [PATCH 02/10] Add test --- wntr/tests/test_gis.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wntr/tests/test_gis.py b/wntr/tests/test_gis.py index 31513f265..86b2c7c1d 100644 --- a/wntr/tests/test_gis.py +++ b/wntr/tests/test_gis.py @@ -131,6 +131,9 @@ def test_wn_to_gis(self): assert set(['link_type', 'start_node_name', 'end_node_name', 'geometry']).issubset(self.gis_data.pipes.columns) assert set(['link_type', 'start_node_name', 'end_node_name', 'geometry']).issubset(self.gis_data.pumps.columns) #assert set(['link_type', 'start_node_name', 'end_node_name', 'geometry']).issubset(self.gis_data.valves.columns) # Net1 has no valves + + #check base_demand and demand_pattern attrivutes + assert set(['base_demand','demand_pattern']).issubset(self.gis_data.junctions.columns) def test_gis_to_wn(self): From d87a158723feaf35e45c4d08e11772795c31dd23 Mon Sep 17 00:00:00 2001 From: kbonney Date: Mon, 21 Oct 2024 10:30:14 -0400 Subject: [PATCH 03/10] update doctests to account for column name changes --- documentation/gis.rst | 42 +++++++++++++++++++------------------- documentation/model_io.rst | 4 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/documentation/gis.rst b/documentation/gis.rst index e57d6886d..8befa1f65 100644 --- a/documentation/gis.rst +++ b/documentation/gis.rst @@ -112,13 +112,13 @@ For example, the junctions GeoDataFrame contains the following information: :skipif: gpd is None >>> print(wn_gis.junctions.head()) - node_type elevation initial_quality geometry - name - 10 Junction 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 Junction 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 Junction 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 Junction 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 Junction 213.360 5.000e-04 POINT (30.00000 40.00000) + node_type base_demand demand_pattern elevation initial_quality geometry + name + 10 Junction 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) + 11 Junction 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) + 12 Junction 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) + 13 Junction 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) + 21 Junction 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) Each GeoDataFrame contains attributes and geometry: @@ -334,23 +334,23 @@ and then translates the GeoDataFrames coordinates to EPSG:3857. >>> wn_gis = wntr.network.to_gis(wn, crs='EPSG:4326') >>> print(wn_gis.junctions.head()) - node_type elevation initial_quality geometry - name - 10 Junction 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 Junction 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 Junction 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 Junction 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 Junction 213.360 5.000e-04 POINT (30.00000 40.00000) + node_type base_demand demand_pattern elevation initial_quality geometry + name + 10 Junction 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) + 11 Junction 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) + 12 Junction 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) + 13 Junction 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) + 21 Junction 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) >>> wn_gis.to_crs('EPSG:3857') >>> print(wn_gis.junctions.head()) - node_type elevation initial_quality geometry - name - 10 Junction 216.408 5.000e-04 POINT (2226389.816 11068715.659) - 11 Junction 216.408 5.000e-04 POINT (3339584.724 11068715.659) - 12 Junction 213.360 5.000e-04 POINT (5565974.540 11068715.659) - 13 Junction 211.836 5.000e-04 POINT (7792364.356 11068715.659) - 21 Junction 213.360 5.000e-04 POINT (3339584.724 4865942.280) + node_type base_demand demand_pattern elevation initial_quality geometry + name + 10 Junction 0.000 1 216.408 5.000e-04 POINT (2226389.816 11068715.659) + 11 Junction 0.009 1 216.408 5.000e-04 POINT (3339584.724 11068715.659) + 12 Junction 0.009 1 213.360 5.000e-04 POINT (5565974.540 11068715.659) + 13 Junction 0.006 1 211.836 5.000e-04 POINT (7792364.356 11068715.659) + 21 Junction 0.009 1 213.360 5.000e-04 POINT (3339584.724 4865942.280) Snap point geometries to the nearest point or line ---------------------------------------------------- diff --git a/documentation/model_io.rst b/documentation/model_io.rst index f66f8fd53..9c2edb770 100644 --- a/documentation/model_io.rst +++ b/documentation/model_io.rst @@ -216,7 +216,7 @@ The following example returns valid base GeoJSON column names for junctions. >>> geojson_column_names = wntr.network.io.valid_gis_names() >>> print(geojson_column_names['junctions']) - ['name', 'elevation', 'coordinates', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] + ['name', 'elevation', 'coordinates', 'base_demand', 'demand_pattern', 'demand_category', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] A minimal list of valid column names can also be obtained by setting ``complete_list`` to False. Column names that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are defined using default values. @@ -311,7 +311,7 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: >>> shapefile_field_names = wntr.network.io.valid_gis_names(truncate_names=10) >>> print(shapefile_field_names['junctions']) - ['name', 'elevation', 'coordinate', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] + ['name', 'elevation', 'coordinate', 'base_deman', 'demand_pat', 'demand_cat', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] A minimal list of valid field names can also be obtained by setting ``complete_list`` to False. Field names that are optional (i.e., ``initial_quality``) and not included in the Shapefile are defined using default values. From 80f6b69087e8550c581ac729cda3018093764fb2 Mon Sep 17 00:00:00 2001 From: kbonney Date: Mon, 21 Oct 2024 10:31:07 -0400 Subject: [PATCH 04/10] change default return in junction properties to reflect default values in add_junction --- wntr/network/elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wntr/network/elements.py b/wntr/network/elements.py index 561676ff0..7e7ae0eb9 100644 --- a/wntr/network/elements.py +++ b/wntr/network/elements.py @@ -227,7 +227,7 @@ def demand_pattern(self): """ if len(self.demand_timeseries_list) > 0: return self.demand_timeseries_list[0].pattern_name - return 0.0 + return None @demand_pattern.setter def demand_pattern(self, value): raise RuntimeWarning('The demand_pattern property is read-only. Please modify using demand_timeseries_list[0].pattern_name') @@ -240,7 +240,7 @@ def demand_category(self): """ if len(self.demand_timeseries_list) > 0: return self.demand_timeseries_list[0].category - return 0.0 + return None @demand_category.setter def demand_category(self, value): raise RuntimeWarning('The demand_category property is read-only. Please modify using demand_timeseries_list[0].category.') From 81bd1d76b7219ee58622888a53095f4ff2c3f3eb Mon Sep 17 00:00:00 2001 From: kbonney Date: Tue, 12 Nov 2024 13:28:58 -0500 Subject: [PATCH 05/10] fix doctests --- documentation/gis.rst | 42 +++++++++++++++++++------------------- documentation/model_io.rst | 4 ++-- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/documentation/gis.rst b/documentation/gis.rst index 6a4428e84..3f3c765e5 100644 --- a/documentation/gis.rst +++ b/documentation/gis.rst @@ -119,13 +119,13 @@ For example, the junctions GeoDataFrame contains the following information: :skipif: gpd is None >>> print(wn_gis.junctions.head()) - elevation initial_quality geometry - name - 10 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 213.360 5.000e-04 POINT (30.00000 40.00000) + base_demand demand_pattern elevation initial_quality geometry + name + 10 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) + 11 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) + 12 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) + 13 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) + 21 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) Each GeoDataFrame contains attributes and geometry: @@ -341,23 +341,23 @@ and then translates the GeoDataFrames coordinates to EPSG:3857. >>> wn_gis = wntr.network.to_gis(wn, crs='EPSG:4326') >>> print(wn_gis.junctions.head()) - elevation initial_quality geometry - name - 10 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 213.360 5.000e-04 POINT (30.00000 40.00000) + base_demand demand_pattern elevation initial_quality geometry + name + 10 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) + 11 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) + 12 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) + 13 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) + 21 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) >>> wn_gis.to_crs('EPSG:3857') >>> print(wn_gis.junctions.head()) - elevation initial_quality geometry - name - 10 216.408 5.000e-04 POINT (2226389.816 11068715.659) - 11 216.408 5.000e-04 POINT (3339584.724 11068715.659) - 12 213.360 5.000e-04 POINT (5565974.540 11068715.659) - 13 211.836 5.000e-04 POINT (7792364.356 11068715.659) - 21 213.360 5.000e-04 POINT (3339584.724 4865942.280) + base_demand demand_pattern elevation initial_quality geometry + name + 10 0.000 1 216.408 5.000e-04 POINT (2226389.816 11068715.659) + 11 0.009 1 216.408 5.000e-04 POINT (3339584.724 11068715.659) + 12 0.009 1 213.360 5.000e-04 POINT (5565974.540 11068715.659) + 13 0.006 1 211.836 5.000e-04 POINT (7792364.356 11068715.659) + 21 0.009 1 213.360 5.000e-04 POINT (3339584.724 4865942.280) Snap point geometries to the nearest point or line ---------------------------------------------------- diff --git a/documentation/model_io.rst b/documentation/model_io.rst index bcd5b7636..22efe05d4 100644 --- a/documentation/model_io.rst +++ b/documentation/model_io.rst @@ -217,7 +217,7 @@ The following example returns valid GeoJSON column names for junctions. >>> geojson_column_names = wntr.network.io.valid_gis_names() >>> print(geojson_column_names['junctions']) - ['name', 'elevation', 'geometry', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] + ['name', 'elevation', 'geometry', 'base_demand', 'demand_pattern', 'demand_category', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] A minimal list of required column names can also be obtained by setting ``complete_list`` to False. Column names that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are @@ -314,7 +314,7 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: >>> shapefile_field_names = wntr.network.io.valid_gis_names(truncate_names=10) >>> print(shapefile_field_names['junctions']) - ['name', 'elevation', 'geometry', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] + ['name', 'elevation', 'geometry', 'base_deman', 'demand_pat', 'demand_cat', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] A minimal list of required field names can also be obtained by setting ``complete_list`` to False. Field names that are optional (i.e., ``initial_quality``) and not included in the Shapefile are defined using default values. From 82c0ff15a3fb696693b6a5cc2e2d70a1a6084fc0 Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 13 Nov 2024 09:05:01 -0500 Subject: [PATCH 06/10] move demand attributes from optional to base. fix docstest accordingly --- documentation/gis.rst | 42 ++++++++++++++++++++-------------------- wntr/network/elements.py | 10 +++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/documentation/gis.rst b/documentation/gis.rst index 3f3c765e5..897110ac9 100644 --- a/documentation/gis.rst +++ b/documentation/gis.rst @@ -119,13 +119,13 @@ For example, the junctions GeoDataFrame contains the following information: :skipif: gpd is None >>> print(wn_gis.junctions.head()) - base_demand demand_pattern elevation initial_quality geometry - name - 10 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) + base_demand demand_pattern elevation initial_quality demand_category geometry + name + 10 0.000 1 216.408 5.000e-04 None POINT (20.00000 70.00000) + 11 0.009 1 216.408 5.000e-04 None POINT (30.00000 70.00000) + 12 0.009 1 213.360 5.000e-04 None POINT (50.00000 70.00000) + 13 0.006 1 211.836 5.000e-04 None POINT (70.00000 70.00000) + 21 0.009 1 213.360 5.000e-04 None POINT (30.00000 40.00000) Each GeoDataFrame contains attributes and geometry: @@ -341,23 +341,23 @@ and then translates the GeoDataFrames coordinates to EPSG:3857. >>> wn_gis = wntr.network.to_gis(wn, crs='EPSG:4326') >>> print(wn_gis.junctions.head()) - base_demand demand_pattern elevation initial_quality geometry - name - 10 0.000 1 216.408 5.000e-04 POINT (20.00000 70.00000) - 11 0.009 1 216.408 5.000e-04 POINT (30.00000 70.00000) - 12 0.009 1 213.360 5.000e-04 POINT (50.00000 70.00000) - 13 0.006 1 211.836 5.000e-04 POINT (70.00000 70.00000) - 21 0.009 1 213.360 5.000e-04 POINT (30.00000 40.00000) + base_demand demand_pattern elevation initial_quality demand_category geometry + name + 10 0.000 1 216.408 5.000e-04 None POINT (20.00000 70.00000) + 11 0.009 1 216.408 5.000e-04 None POINT (30.00000 70.00000) + 12 0.009 1 213.360 5.000e-04 None POINT (50.00000 70.00000) + 13 0.006 1 211.836 5.000e-04 None POINT (70.00000 70.00000) + 21 0.009 1 213.360 5.000e-04 None POINT (30.00000 40.00000) >>> wn_gis.to_crs('EPSG:3857') >>> print(wn_gis.junctions.head()) - base_demand demand_pattern elevation initial_quality geometry - name - 10 0.000 1 216.408 5.000e-04 POINT (2226389.816 11068715.659) - 11 0.009 1 216.408 5.000e-04 POINT (3339584.724 11068715.659) - 12 0.009 1 213.360 5.000e-04 POINT (5565974.540 11068715.659) - 13 0.006 1 211.836 5.000e-04 POINT (7792364.356 11068715.659) - 21 0.009 1 213.360 5.000e-04 POINT (3339584.724 4865942.280) + base_demand demand_pattern elevation initial_quality demand_category geometry + name + 10 0.000 1 216.408 5.000e-04 None POINT (2226389.816 11068715.659) + 11 0.009 1 216.408 5.000e-04 None POINT (3339584.724 11068715.659) + 12 0.009 1 213.360 5.000e-04 None POINT (5565974.540 11068715.659) + 13 0.006 1 211.836 5.000e-04 None POINT (7792364.356 11068715.659) + 21 0.009 1 213.360 5.000e-04 None POINT (3339584.724 4865942.280) Snap point geometries to the nearest point or line ---------------------------------------------------- diff --git a/wntr/network/elements.py b/wntr/network/elements.py index afecec52a..9c117ca18 100644 --- a/wntr/network/elements.py +++ b/wntr/network/elements.py @@ -79,12 +79,12 @@ class Junction(Node): # base and optional attributes used to create a Junction in _from_dict # base attributes are used in add_junction _base_attributes = ["name", + "base_demand", + "demand_pattern", "elevation", - "coordinates"] - _optional_attributes = ["base_demand", - "demand_pattern", - "demand_category", - "emitter_coefficient", + "coordinates", + "demand_category"] + _optional_attributes = ["emitter_coefficient", "initial_quality", "minimum_pressure", "required_pressure", From ffada5d8f51b0929c43ebb0d53ca94f8a616b5d3 Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 13 Nov 2024 09:55:16 -0500 Subject: [PATCH 07/10] fix doctest --- documentation/model_io.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/model_io.rst b/documentation/model_io.rst index 22efe05d4..e2a962a76 100644 --- a/documentation/model_io.rst +++ b/documentation/model_io.rst @@ -217,7 +217,7 @@ The following example returns valid GeoJSON column names for junctions. >>> geojson_column_names = wntr.network.io.valid_gis_names() >>> print(geojson_column_names['junctions']) - ['name', 'elevation', 'geometry', 'base_demand', 'demand_pattern', 'demand_category', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] + ['name', 'base_demand', 'demand_pattern', 'elevation', 'demand_category', 'geometry', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] A minimal list of required column names can also be obtained by setting ``complete_list`` to False. Column names that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are @@ -228,7 +228,7 @@ defined using default values. >>> geojson_column_names = wntr.network.io.valid_gis_names(complete_list=False) >>> print(geojson_column_names['junctions']) - ['name', 'elevation', 'geometry'] + ['name', 'base_demand', 'demand_pattern', 'elevation', 'demand_category', 'geometry'] Note that GeoJSON files can contain additional custom column names that are assigned to WaterNetworkModel objects. @@ -314,7 +314,7 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: >>> shapefile_field_names = wntr.network.io.valid_gis_names(truncate_names=10) >>> print(shapefile_field_names['junctions']) - ['name', 'elevation', 'geometry', 'base_deman', 'demand_pat', 'demand_cat', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] + ['name', 'base_deman', 'demand_pat', 'elevation', 'demand_cat', 'geometry', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] A minimal list of required field names can also be obtained by setting ``complete_list`` to False. Field names that are optional (i.e., ``initial_quality``) and not included in the Shapefile are defined using default values. @@ -325,7 +325,7 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: >>> shapefile_field_names = wntr.network.io.valid_gis_names(complete_list=False, ... truncate_names=10) >>> print(shapefile_field_names['junctions']) - ['name', 'elevation', 'geometry'] + ['name', 'base_deman', 'demand_pat', 'elevation', 'demand_cat', 'geometry'] * Shapefiles can contain additional custom field names that are assigned to WaterNetworkModel objects. From 97ca6faee9f2077776b68f6355ae564f6c7c8ba8 Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 13 Nov 2024 14:34:44 -0500 Subject: [PATCH 08/10] fix doctest by adding sort to column name list --- wntr/gis/network.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wntr/gis/network.py b/wntr/gis/network.py index dd1a633e7..7dd1552c7 100644 --- a/wntr/gis/network.py +++ b/wntr/gis/network.py @@ -143,6 +143,7 @@ def _extract_geodataframe(df, crs=None, valid_base_names=None, # Add back in valid base attributes that had all None values cols = list(set(valid_base_names) - set(df.columns)) + cols.sort() if len(cols) > 0: df[cols] = None From 6bc811b97e1095ababc825610bffe2c142c63e8e Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 13 Nov 2024 15:25:37 -0500 Subject: [PATCH 09/10] rewrite portions of IO documentation for clarity --- documentation/model_io.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/documentation/model_io.rst b/documentation/model_io.rst index e2a962a76..72aa49c06 100644 --- a/documentation/model_io.rst +++ b/documentation/model_io.rst @@ -206,11 +206,14 @@ GeoJSON files GeoJSON files are commonly used to store geographic data structures. More information on GeoJSON files can be found at https://geojson.org. -When reading GeoJSON files into WNTR, only a set of valid column names can be used. -Valid GeoJSON column names can be obtained using the -:class:`~wntr.network.io.valid_gis_names` function. By default, the function -returns all column names, both required and optional. -The following example returns valid GeoJSON column names for junctions. +When reading GeoJSON files into WNTR, the file should contain columns from the set of valid column names. +Valid GeoJSON column names can be obtained using the :class:`~wntr.network.io.valid_gis_names` function. +By default, the function returns a complete set of required and optional column names. +A minimal list of column names containing commonly used attributes can be obtained by setting ``complete_list`` to False. +The minimal set correspond with attributes used in `add_junction`, `add_tank`, etc. +Columns that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are defined using default values. + +The following examples return the complete and minimal lists of valid GeoJSON column names for junctions. .. doctest:: :skipif: gpd is None @@ -219,10 +222,6 @@ The following example returns valid GeoJSON column names for junctions. >>> print(geojson_column_names['junctions']) ['name', 'base_demand', 'demand_pattern', 'elevation', 'demand_category', 'geometry', 'emitter_coefficient', 'initial_quality', 'minimum_pressure', 'required_pressure', 'pressure_exponent', 'tag'] -A minimal list of required column names can also be obtained by setting ``complete_list`` to False. -Column names that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are -defined using default values. - .. doctest:: :skipif: gpd is None @@ -301,12 +300,16 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: node and link attribute names are often longer. For this reason, it is assumed that the first 10 characters of each attribute are unique. -* To create WaterNetworkModel from Shapefiles, a set of valid field names are required. +* When reading Shapefiles files into WNTR, the file should contain fields from the set of valid column names. Valid Shapefiles field names can be obtained using the :class:`~wntr.network.io.valid_gis_names` function. By default, the function - returns all column names, both required and optional. + returns a complete set of required and optional field names. + A minimal list of field names containing commonly used attributes can be obtained by setting ``complete_list`` to False. + The minimal set correspond with attributes used in `add_junction`, `add_tank`, etc. + Fields that are optional (i.e., ``initial_quality``) and not included in the Shapefile are defined using default values. + For Shapefiles, the `truncate_names` input parameter should be set to 10 (characters). - The following example returns valid Shapefile field names for junctions. + The following examples return the complete and minimal lists of valid Shapefile field names for junctions. Note that attributes like ``minimum_pressure`` are truncated to ``minimum_pr``. .. doctest:: @@ -316,9 +319,6 @@ To use Esri Shapefiles in WNTR, several formatting requirements are enforced: >>> print(shapefile_field_names['junctions']) ['name', 'base_deman', 'demand_pat', 'elevation', 'demand_cat', 'geometry', 'emitter_co', 'initial_qu', 'minimum_pr', 'required_p', 'pressure_e', 'tag'] - A minimal list of required field names can also be obtained by setting ``complete_list`` to False. - Field names that are optional (i.e., ``initial_quality``) and not included in the Shapefile are defined using default values. - .. doctest:: :skipif: gpd is None From 8462df91d5396e0121893217768a1c66b29f5dce Mon Sep 17 00:00:00 2001 From: kbonney Date: Wed, 13 Nov 2024 15:38:50 -0500 Subject: [PATCH 10/10] add cross references for methods --- documentation/model_io.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/model_io.rst b/documentation/model_io.rst index 72aa49c06..b581b8e9e 100644 --- a/documentation/model_io.rst +++ b/documentation/model_io.rst @@ -210,7 +210,7 @@ When reading GeoJSON files into WNTR, the file should contain columns from the s Valid GeoJSON column names can be obtained using the :class:`~wntr.network.io.valid_gis_names` function. By default, the function returns a complete set of required and optional column names. A minimal list of column names containing commonly used attributes can be obtained by setting ``complete_list`` to False. -The minimal set correspond with attributes used in `add_junction`, `add_tank`, etc. +The minimal set correspond with attributes used in :class:`~wntr.network.model.WaterNetworkModel.add_junction`, :class:`~wntr.network.model.WaterNetworkModel.add_tank`, etc. Columns that are optional (i.e., ``initial_quality``) and not included in the GeoJSON file are defined using default values. The following examples return the complete and minimal lists of valid GeoJSON column names for junctions.