easysewer 0.0.2__py3-none-any.whl → 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
easysewer/Rain.py CHANGED
@@ -4,7 +4,7 @@ Rainfall Data Management Module
4
4
  This module handles rainfall data input and processing, including rain gages,
5
5
  time series data, and rainfall patterns for the drainage model.
6
6
  """
7
-
7
+ from warnings import warn
8
8
  from .utils import *
9
9
 
10
10
 
@@ -116,21 +116,23 @@ class RainGage:
116
116
 
117
117
  Attributes:
118
118
  name (str): Unique identifier for the rain gage
119
- format (str): Format of the rainfall data (INTENSITY/VOLUME/CUMULATIVE)
119
+ form (str): Format of the rainfall data (INTENSITY/VOLUME/CUMULATIVE)
120
120
  interval (float): Recording time interval
121
- snow_catch (float): Snow catch deficiency correction
122
- data_source (str): Source of the rainfall data
123
- time_series (str): Name of associated time series data
121
+ source_type (str): Source type (TIMESERIES or FILE)
122
+ unit (str): Unit for FILE source (e.g., mm)
124
123
  """
125
124
  def __init__(self):
126
125
  self.name = ''
127
126
  self.form = '' # INTENSIFY: mm/h
128
127
  self.interval = ''
129
128
  self.SCF = 1 # snow catch deficiency correction factor (use 1.0 for no adjustment)
130
- self.source = '' # timeseries name
129
+ self.source = '' # timeseries name or file name
130
+ self.source_type = 'TIMESERIES' # TIMESERIES or FILE
131
+ self.station_id = None # Only for FILE source
132
+ self.unit = None # Only for FILE source
131
133
 
132
134
  def __repr__(self):
133
- return f'RainGage<{self.name}>: {self.source}'
135
+ return f'RainGage<{self.name}>: {self.source} ({self.source_type})'
134
136
 
135
137
 
136
138
  class Rain:
@@ -217,13 +219,34 @@ class Rain:
217
219
  # rain gage section
218
220
  content = get_swmm_inp_content(filename, '[RAINGAGES]')
219
221
  for line in content:
220
- name, form, interval, SCF, _, tise = line.split()
221
- this_gage = RainGage()
222
- this_gage.name = name
223
- this_gage.form = form
224
- this_gage.interval = interval
225
- this_gage.SCF = SCF
226
- this_gage.source = tise
222
+ parts = line.split()
223
+ if len(parts) < 6:
224
+ continue # skip malformed lines
225
+ source_type = parts[4]
226
+ if source_type == 'TIMESERIES' and len(parts) == 6:
227
+ name, form, interval, SCF, source_type, tise = parts
228
+ this_gage = RainGage()
229
+ this_gage.name = name
230
+ this_gage.form = form
231
+ this_gage.interval = interval
232
+ this_gage.SCF = SCF
233
+ this_gage.source_type = source_type
234
+ this_gage.source = tise
235
+ # unit remains default
236
+ elif source_type == 'FILE' and len(parts) == 8:
237
+ name, form, interval, SCF, source_type, filepath, station_id, unit = parts
238
+ this_gage = RainGage()
239
+ this_gage.name = name
240
+ this_gage.form = form
241
+ this_gage.interval = interval
242
+ this_gage.SCF = SCF
243
+ this_gage.source_type = source_type
244
+ this_gage.source = filepath
245
+ this_gage.station_id = station_id
246
+ this_gage.unit = unit
247
+ else:
248
+ warn(f'Failed to add rain gauge for content "{line}".')
249
+ continue # skip malformed lines
227
250
  self.add_gage(this_gage)
228
251
  return 0
229
252
 
@@ -262,8 +285,14 @@ class Rain:
262
285
  f.write(';;\n')
263
286
 
264
287
  f.write('\n\n[RAINGAGES]\n')
265
- f.write(';;Name Format Interval SCF Source \n')
266
- f.write(';;----- -------- --------- ---- ----------\n')
288
+ f.write(';;Name Format Interval SCF SourceType Source [Unit]\n')
289
+ f.write(';;----- -------- --------- ---- ---------- ---------- -------\n')
267
290
  for gage in self.gage_list:
268
- f.write(f'{gage.name} {gage.form} {gage.interval} {gage.SCF} TIMESERIES {gage.source}\n')
291
+ if gage.source_type == 'TIMESERIES':
292
+ f.write(f'{gage.name} {gage.form} {gage.interval} {gage.SCF} TIMESERIES {gage.source}\n')
293
+ elif gage.source_type == 'FILE':
294
+ f.write(f'{gage.name} {gage.form} {gage.interval} {gage.SCF} FILE {gage.source} {gage.station_id} {gage.unit}\n')
295
+ else:
296
+ # fallback for unknown type
297
+ raise ValueError(f"Unknown source type: {gage.source_type}")
269
298
  return 0
easysewer/UDM.py CHANGED
@@ -11,6 +11,8 @@ The model supports:
11
11
  - Handling rainfall and calculation settings
12
12
  - Supporting various hydraulic elements like conduits and junctions
13
13
  """
14
+ import json
15
+ from pathlib import Path
14
16
 
15
17
  from .Options import CalculationInformation
16
18
  from .Link import LinkList
@@ -18,7 +20,6 @@ from .Node import NodeList
18
20
  from .Area import AreaList
19
21
  from .Rain import Rain
20
22
  from .Curve import ValueList
21
- import json
22
23
  from .utils import get_swmm_inp_content
23
24
 
24
25
 
@@ -68,32 +69,56 @@ class UrbanDrainageModel:
68
69
 
69
70
  def to_inp(self, filename):
70
71
  """
71
- Writes the model to a SWMM .inp file.
72
-
72
+ Writes the model to a SWMM .inp file, creating parent directories if needed.
73
73
  Args:
74
- filename (str): Path to the output .inp file
75
-
74
+ filename (str or Path): Path to the output .inp file
76
75
  Returns:
77
- int: 0 on success
76
+ int: 0 on success, raises exceptions on failure
77
+ Raises:
78
+ OSError: If file operations fail
79
+ TypeError: If JSON serialization fails
78
80
  """
79
- with open(filename, 'w', encoding='utf-8') as f:
80
- # Write TITLE section first
81
- f.write('[TITLE]\n')
82
- if self.label:
81
+ # Convert to Path object if it isn't already
82
+ filepath = Path(filename)
83
+
84
+ # Create parent directories if they don't exist
85
+ filepath.parent.mkdir(parents=True, exist_ok=True)
86
+
87
+ try:
88
+ with open(filepath, 'w', encoding='utf-8') as f:
89
+ # Write TITLE section first
90
+ f.write('[TITLE]\n')
91
+ if self.label:
92
+ try:
93
+ # Only attempt JSON if it's a dictionary
94
+ if isinstance(self.label, dict):
95
+ f.write(json.dumps(self.label, indent=2))
96
+ else:
97
+ f.write(str(self.label))
98
+ f.write('\n\n')
99
+ except (TypeError, ValueError) as e:
100
+ # Fallback to simple string representation
101
+ f.write(str(self.label.get('TITLE', '')) if isinstance(self.label, dict) else str(self.label))
102
+ f.write('\n\n')
103
+
104
+ # Continue with other sections - now using the same filepath
105
+ self.calc.write_to_swmm_inp(filepath)
106
+ self.node.write_to_swmm_inp(filepath)
107
+ self.link.write_to_swmm_inp(filepath)
108
+ self.area.write_to_swmm_inp(filepath)
109
+ self.rain.write_to_swmm_inp(filepath)
110
+ self.value.write_to_swmm_inp(filepath)
111
+
112
+ return 0
113
+
114
+ except Exception as e:
115
+ # Clean up partially written file if there was an error
116
+ if filepath.exists():
83
117
  try:
84
- f.write(json.dumps(self.label, indent=2))
85
- f.write('\n\n')
118
+ filepath.unlink()
86
119
  except:
87
- f.write(str(self.label.get('TITLE', '')) + '\n\n')
88
-
89
- # Continue with other sections
90
- self.calc.write_to_swmm_inp(filename)
91
- self.node.write_to_swmm_inp(filename)
92
- self.link.write_to_swmm_inp(filename)
93
- self.area.write_to_swmm_inp(filename)
94
- self.rain.write_to_swmm_inp(filename)
95
- self.value.write_to_swmm_inp(filename)
96
- return 0
120
+ pass # Don't mask the original error
121
+ raise # Re-raise the original exception
97
122
 
98
123
  def read_inp(self, filename):
99
124
  """
easysewer/__init__.py CHANGED
@@ -2,6 +2,6 @@
2
2
  pass
3
3
  """
4
4
  from .UDM import UrbanDrainageModel
5
- from .UDM import UrbanDrainageModel as Model
5
+ from .ModelAPI import Model
6
6
  from .OutputAPI import SWMMOutputAPI
7
7
  from .SolverAPI import SWMMSolverAPI
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easysewer
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: An urban drainage modeling toolkit
5
5
  Author-email: Yiran Ji <yiranji@zju.edu.cn>
6
6
  License-Expression: AGPL-3.0-only
@@ -0,0 +1,20 @@
1
+ easysewer/Area.py,sha256=Hw3xr-XiqAiTGVsG-fH71ovIBNnsRYBwmJrWG9l3YLA,32703
2
+ easysewer/Curve.py,sha256=C5X_CJ9CtuYcUFqdClFkxWYZOYHhQFBxENYg9jC6Dqs,4241
3
+ easysewer/Link.py,sha256=7hyQPme-ibnsgHO1VCjA0WgvPYflMgz3zCF8r5lhZ3g,23749
4
+ easysewer/ModelAPI.py,sha256=qJe8YroVostJ_Xwnlu0P9EdBy8FEFJ6vjev_Jn9sECs,7557
5
+ easysewer/Node.py,sha256=Cbexul4OdPWRhLW9h2fGjeMhLLwtDl0vGwmbACg_Hjs,45547
6
+ easysewer/Options.py,sha256=zsmyDpiQO0Swsrqkzw_vow4lNKbiLsLX_0YQ6XWsSBI,18425
7
+ easysewer/OutputAPI.py,sha256=tD6-6VjBpG-DBlmvVhb9siZ_zgEe1lD1d0h2xPr72Qw,7519
8
+ easysewer/Rain.py,sha256=Bb-SD-j7J0F6lWENsdU6Qc6Nr4ZcrCMOQcbJW3ZcbaQ,10865
9
+ easysewer/SolverAPI.py,sha256=H1KZkS_03Mv2ruSNX6-Rg_fesTwL9O6R5TRCil2eC7o,5612
10
+ easysewer/UDM.py,sha256=A2SCLhiM9LD05VVn0L8S8vIv6WgWxpl6_ckM_5JmRCI,5655
11
+ easysewer/__init__.py,sha256=8i9amFHLOrXYo3vjg6hCQPZ676d650UTCxPkblgyJvk,158
12
+ easysewer/utils.py,sha256=dkK5YwwaE2eLdiaY3YAEg78xv74TU6ff7Q3Rl3ltatI,2847
13
+ easysewer/libs/linux/libswmm5.so,sha256=UI5v1fCZ7LU9zkjLQMJqqJtzDefkFnL1iy3jmAlFsVo,839664
14
+ easysewer/libs/linux/swmm-output.so,sha256=248JHb0PUGyeo3tLj9fL4L114ySTSLBrUUA_k3VHnCQ,30928
15
+ easysewer/libs/win/swmm-output.dll,sha256=tN0K2ZRk7rlQZ-cLxlGLYZ6w269uvc5JuH1oVumADD0,71168
16
+ easysewer/libs/win/swmm5.dll,sha256=7LjGQXUyj8bdVuFzzY8-pObQV0VcUDI5KsAz-hstWls,915968
17
+ easysewer-0.0.3.dist-info/METADATA,sha256=G8-hiKnEacVIA20nHHrMwYbJvBI25EFoe70fpHg6kC4,586
18
+ easysewer-0.0.3.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
19
+ easysewer-0.0.3.dist-info/top_level.txt,sha256=YJi065ohgpDZhPb0XuXfE6ExHMhHPlwveH40BgZ7kt4,10
20
+ easysewer-0.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,19 +0,0 @@
1
- easysewer/Area.py,sha256=Y7SjlcA9byN4A3fk70D4M4hG8MulE0LLVJLqZ8FDt6c,13010
2
- easysewer/Curve.py,sha256=C5X_CJ9CtuYcUFqdClFkxWYZOYHhQFBxENYg9jC6Dqs,4241
3
- easysewer/Link.py,sha256=tZWGPg5EMcii6hfswNPp5MMz3wLdZPzuil9Sjv6OqXc,11802
4
- easysewer/Node.py,sha256=trtXGPLDk1gkdKMXXwJ1hUOmsS6x2mVr4wh61Lxisqk,14092
5
- easysewer/Options.py,sha256=zsmyDpiQO0Swsrqkzw_vow4lNKbiLsLX_0YQ6XWsSBI,18425
6
- easysewer/OutputAPI.py,sha256=tD6-6VjBpG-DBlmvVhb9siZ_zgEe1lD1d0h2xPr72Qw,7519
7
- easysewer/Rain.py,sha256=MCw-vmDwLANuRGmh_EEQS4kNB1RNdeGSvQ9L8GobbIA,9239
8
- easysewer/SolverAPI.py,sha256=H1KZkS_03Mv2ruSNX6-Rg_fesTwL9O6R5TRCil2eC7o,5612
9
- easysewer/UDM.py,sha256=DfEOFRyFR5guy7yEU_ve_XsRypXQ3k2nn5Slc5VAzOc,4385
10
- easysewer/__init__.py,sha256=XD2zR0vua7-FMz5brRDY9FCzF_QNkPozfrOl7dvYALc,175
11
- easysewer/utils.py,sha256=dkK5YwwaE2eLdiaY3YAEg78xv74TU6ff7Q3Rl3ltatI,2847
12
- easysewer/libs/linux/libswmm5.so,sha256=UI5v1fCZ7LU9zkjLQMJqqJtzDefkFnL1iy3jmAlFsVo,839664
13
- easysewer/libs/linux/swmm-output.so,sha256=248JHb0PUGyeo3tLj9fL4L114ySTSLBrUUA_k3VHnCQ,30928
14
- easysewer/libs/win/swmm-output.dll,sha256=tN0K2ZRk7rlQZ-cLxlGLYZ6w269uvc5JuH1oVumADD0,71168
15
- easysewer/libs/win/swmm5.dll,sha256=7LjGQXUyj8bdVuFzzY8-pObQV0VcUDI5KsAz-hstWls,915968
16
- easysewer-0.0.2.dist-info/METADATA,sha256=Gzv6CSbBmfTvrNfdkHR1calbcDmKpjlFx-JLTbZQiEs,586
17
- easysewer-0.0.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
18
- easysewer-0.0.2.dist-info/top_level.txt,sha256=YJi065ohgpDZhPb0XuXfE6ExHMhHPlwveH40BgZ7kt4,10
19
- easysewer-0.0.2.dist-info/RECORD,,