def __init__(self, epanet_project, model_output): self.LogoTxt = ( '**********************************************************************', '* E P A N E T *', '* Hydraulic and Water Quality *', '* Analysis for Pipe Networks *', '* Version 2.0 *', '**********************************************************************' ) self.F = None # File being written to if isinstance(epanet_project, Project): self.project = epanet_project elif isinstance(epanet_project, str): self.project = Project() self.project.read_file(epanet_project) else: raise Exception( "Report Initialization: could not read EPANET project.") if isinstance(model_output, OutputObject): self.output = model_output elif isinstance(model_output, str): self.output = OutputObject(model_output) else: raise Exception( "Report Initialization: could not read output of model.\n" "Run the model to generate new output.") self.RptTitle = self.project.title.title self.PageNum = 0 self.LineNum = 0 self.Progstep = 0 self.Nprogress = 0
def test_curves(self): """Test Curves section""" self.my_curve = curves.Curve() self.my_curve = curves.Curve() self.my_curve.curve_id = "XXX" self.my_curve.description = "test curve" self.my_curve.curve_type = curves.CurveType.HEADLOSS self.my_curve.curve_xy = ((1500, 250), (1400, 200)) assert self.my_curve.curve_id == "XXX" assert self.my_curve.description == "test curve" assert self.my_curve.get_text().split() == [ ';HEADLOSS:', 'test', 'curve', 'XXX', '1500', '250', 'XXX', '1400', '200' ], "incorrect pattern block" # Create new project with new text test_text = ("[CURVES]", ";ID\tX-Value\tY-Value", ";--\t-------\t-------", ";PUMP: Pump Curve for Pump 9", " 1\t1500\t250\t") from_text = Project() from_text.set_text('\n'.join(test_text)) project_curves = from_text.curves assert Section.match_omit(project_curves.get_text(), '\n'.join(test_text), " -;\t\n") assert len(project_curves.value) == 1 this_curve = project_curves.value[0] assert this_curve.curve_id == '1' assert this_curve.description == "Pump Curve for Pump 9" assert this_curve.curve_type == curves.CurveType.PUMP assert this_curve.curve_xy == [("1500", "250")]
def runTest(self): """Test set_text and get_text""" from_text = Project() source_text = '\n'.join(self.TEST_TEXT) from_text.set_text(source_text) project_sources = from_text.sources assert Section.match_omit(project_sources.get_text(), source_text, " \t-;\n") assert project_sources.value[0].id == "JUNCTION-9090" assert project_sources.value[0].source_type == SourceType.CONCEN assert project_sources.value[0].baseline_strength == "8330" assert project_sources.value[0].pattern_id == "Pattern-A" assert project_sources.value[1].id == "JUNCTION-9091" assert project_sources.value[1].source_type == SourceType.MASS assert project_sources.value[1].baseline_strength == "8331" assert project_sources.value[1].pattern_id == "Pattern-B" assert project_sources.value[2].id == "JUNCTION-9092" assert project_sources.value[2].source_type == SourceType.FLOWPACED assert project_sources.value[2].baseline_strength == "8332" assert project_sources.value[2].pattern_id == "Pattern-C" assert project_sources.value[3].id == "JUNCTION-9093" assert project_sources.value[3].source_type == SourceType.SETPOINT assert project_sources.value[3].baseline_strength == "8333" assert project_sources.value[3].pattern_id == "Pattern-D" assert project_sources.value[4].id == "JUNCTION-9094" assert project_sources.value[4].source_type == SourceType.CONCEN assert project_sources.value[4].baseline_strength == "8334" assert project_sources.value[4].pattern_id == ""
def test_curves(self): """Test Curves section""" self.my_curve = curves.Curve() self.my_curve = curves.Curve() self.my_curve.curve_id = "XXX" self.my_curve.description = "test curve" self.my_curve.curve_type = curves.CurveType.HEADLOSS self.my_curve.curve_xy = ((1500, 250), (1400, 200)) assert self.my_curve.curve_id == "XXX" assert self.my_curve.description == "test curve" assert self.my_curve.get_text().split() == [';HEADLOSS:', 'test', 'curve', 'XXX', '1500', '250', 'XXX', '1400', '200'], "incorrect pattern block" # Create new project with new text test_text = ("[CURVES]", ";ID\tX-Value\tY-Value", ";--\t-------\t-------", ";PUMP: Pump Curve for Pump 9", " 1\t1500\t250\t") from_text = Project() from_text.set_text('\n'.join(test_text)) project_curves = from_text.curves assert Section.match_omit(project_curves.get_text(), '\n'.join(test_text), " -;\t\n") assert len(project_curves.value) == 1 this_curve = project_curves.value[0] assert this_curve.curve_id == '1' assert this_curve.description == "Pump Curve for Pump 9" assert this_curve.curve_type == curves.CurveType.PUMP assert this_curve.curve_xy == [("1500", "250")]
def test_patterns(self): """Test one Pattern section""" self.my_pattern = patterns.Pattern() self.my_pattern.description = "test pattern" self.my_pattern.pattern_id = "XXX" self.my_pattern.multipliers = ("1.0", "1.1", "1.2", "1.3") assert self.my_pattern.pattern_id == "XXX" assert self.my_pattern.description == "test pattern" assert self.my_pattern.get_text().split() == [";test", "pattern", "XXX", "1.0", "1.1", "1.2", "1.3"], "get_text" # Create new Project with this section populated from TEST_TEXT test_text = ("[PATTERNS]", ";ID\tMultipliers", ";Demand Pattern", " 1\t1.0\t1.2\t1.4\t1.6\t1.4\t1.2", " 1\t1.0\t0.8\t0.6\t0.4\t0.6\t0.8", " 2\t2.0\t2.2\t2.4\t2.6\t2.4\t2.2", " 2\t2.0\t2.8\t2.6\t2.4\t2.6\t2.8") from_text = Project() from_text.set_text('\n'.join(test_text)) pattern_list = from_text.patterns.value assert len(pattern_list) == 2 assert int(pattern_list[0].pattern_id) == 1 assert int(pattern_list[1].pattern_id) == 2 assert float(pattern_list[0].multipliers[0]) == 1.0 assert float(pattern_list[0].multipliers[1]) == 1.2 assert float(pattern_list[0].multipliers[2]) == 1.4 assert float(pattern_list[0].multipliers[3]) == 1.6 assert float(pattern_list[0].multipliers[4]) == 1.4 assert float(pattern_list[0].multipliers[5]) == 1.2 assert float(pattern_list[0].multipliers[6]) == 1.0 assert float(pattern_list[0].multipliers[7]) == 0.8 assert float(pattern_list[0].multipliers[8]) == 0.6 assert float(pattern_list[0].multipliers[9]) == 0.4 assert float(pattern_list[0].multipliers[10]) == 0.6 assert float(pattern_list[0].multipliers[11]) == 0.8 assert float(pattern_list[1].multipliers[0]) == 2.0 assert float(pattern_list[1].multipliers[1]) == 2.2 assert float(pattern_list[1].multipliers[2]) == 2.4 assert float(pattern_list[1].multipliers[3]) == 2.6 assert float(pattern_list[1].multipliers[4]) == 2.4 assert float(pattern_list[1].multipliers[5]) == 2.2 assert float(pattern_list[1].multipliers[6]) == 2.0 assert float(pattern_list[1].multipliers[7]) == 2.8 assert float(pattern_list[1].multipliers[8]) == 2.6 assert float(pattern_list[1].multipliers[9]) == 2.4 assert float(pattern_list[1].multipliers[10]) == 2.6 assert float(pattern_list[1].multipliers[11]) == 2.8
def __init__(self, epanet_project, model_output): self.LogoTxt = ( '**********************************************************************', '* E P A N E T *', '* Hydraulic and Water Quality *', '* Analysis for Pipe Networks *', '* Version 2.0 *', '**********************************************************************') self.F = None # File being written to if isinstance(epanet_project, Project): self.project = epanet_project elif isinstance(epanet_project, str): self.project = Project() self.project.read_file(epanet_project) else: raise Exception("Report Initialization: could not read EPANET project.") if isinstance(model_output, OutputObject): self.output = model_output elif isinstance(model_output, str): self.output = OutputObject(model_output) else: raise Exception("Report Initialization: could not read output of model.\n" "Run the model to generate new output.") self.RptTitle = self.project.title.title self.PageNum = 0 self.LineNum = 0 self.Progstep = 0 self.Nprogress = 0
def runTest(self): """Test set_text and get_text of demand options""" from_text = Project() source_text = '\n'.join(self.TEST_TEXT) from_text.set_text(source_text) project_demands = from_text.demands assert Section.match_omit(project_demands.get_text(), source_text, " \t-;\n") assert project_demands.value[0].junction_id == "JUNCTION-0" assert project_demands.value[0].base_demand == "0.0" assert project_demands.value[0].demand_pattern == "PATTERN-1" assert project_demands.value[0].category == '' assert project_demands.value[1].junction_id == "JUNCTION-1" assert project_demands.value[1].base_demand == "0.1" assert project_demands.value[1].demand_pattern == "PATTERN-2" assert project_demands.value[1].category == '' assert project_demands.value[2].junction_id == "JUNCTION-12" assert project_demands.value[2].base_demand == "0.2" assert project_demands.value[2].demand_pattern == "PATTERN-12" assert project_demands.value[2].category == "Category-12"
class Reports: PAGESIZE = 55 ULINE = '----------------------------------------------------------------------' FMT18 = ' Page 1 {:>22}' FMT_DATE = '%Y/%m/%d %I:%M%p' FMT82 = ' Page {:4d} {:60}' FMT71 = 'Energy Usage:' FMT72 = ' Usage Avg. Kw-hr Avg. Peak Cost' FMT73 = 'Pump Factor Effic. {:5} Kw Kw /day' FMT74 = '{:45} Demand Charge: {:9.2f}' FMT75 = '{:45} Total Cost: {:9.2f}' TXT_perM3 = '/m3' TXT_perMGAL = '/Mgal' TXT_CONTINUED = ' (continued)' TXT_INPUT_FILE = 'Input File: ' TXT_LINK_INFO = 'Link - Node Table:' TXT_NODE_RESULTS = 'Node Results' TXT_LINK_RESULTS = 'Link Results' TXT_AT = ' at ' TXT_ID = 'ID' TXT_NODE = 'Node' TXT_LINK = 'Link' TXT_START = 'Start' TXT_END = 'End' TimeStat = ['Single Period', 'Average', 'Minimum', 'Maximum', 'Range'] def __init__(self, epanet_project, model_output): self.LogoTxt = ( '**********************************************************************', '* E P A N E T *', '* Hydraulic and Water Quality *', '* Analysis for Pipe Networks *', '* Version 2.0 *', '**********************************************************************') self.F = None # File being written to if isinstance(epanet_project, Project): self.project = epanet_project elif isinstance(epanet_project, str): self.project = Project() self.project.read_file(epanet_project) else: raise Exception("Report Initialization: could not read EPANET project.") if isinstance(model_output, OutputObject): self.output = model_output elif isinstance(model_output, str): self.output = OutputObject(model_output) else: raise Exception("Report Initialization: could not read output of model.\n" "Run the model to generate new output.") self.RptTitle = self.project.title.title self.PageNum = 0 self.LineNum = 0 self.Progstep = 0 self.Nprogress = 0 def write_line(self, line): if (self.LineNum >= self.PAGESIZE): self.PageNum += 1 self.F.write('\n\f\n') # newline form-feed newline self.F.write(self.FMT82.format(self.PageNum, self.RptTitle) + '\n') self.LineNum = 3 self.F.write(' ' + line + '\n') self.LineNum += 1 def write_logo(self): self.PageNum = 1 self.LineNum = 1 self.write_line(self.FMT18.format(datetime.now().strftime(self.FMT_DATE))) for line in self.LogoTxt: self.write_line(line) self.write_line('') self.write_line(self.TXT_INPUT_FILE + self.project.file_name) self.write_line('') self.write_line(self.RptTitle) self.write_line(self.project.title.notes) # self.write_line('') def write_energy_header(self, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE units = (self.TXT_perMGAL, self.TXT_perM3)[self.output.unit_system] line = self.FMT71 if ContinueFlag: line += self.TXT_CONTINUED self.write_line(line) self.write_line(self.ULINE) line = self.FMT72 self.write_line(line) line = self.FMT73.format(units) self.write_line(line) self.write_line(self.ULINE) def write_energy(self): self.write_energy_header(False) Csum = 0.0 for pump in self.project.pumps.value: x = [0,0,0,0,0,0] Dcharge = 0 # Uoutput.GetPumpEnergy(k,x,Dcharge) Csum += x[5] if (self.LineNum >= self.PAGESIZE): self.write_energy_header(True) line = '{:15} {:6.2f} {:6.2f} {:9.2f} {:9.2f} {:9.2f} {:9.2f}'.format( pump.id, x[0], x[1], x[2], x[3], x[4], x[5]) self.write_line(line) self.write_line(self.ULINE) line = self.FMT74.format('', Dcharge) self.write_line(line) line = self.FMT75.format('', Csum + Dcharge) self.write_line(line) self.write_line('') def write_node_header(self, period, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE line = self.TXT_NODE_RESULTS if self.output.numPeriods > 1: line += self.TXT_AT + self.output.get_time_string(period) line += ':' if ContinueFlag: line += self.TXT_CONTINUED self.write_line(line) self.write_line(self.ULINE) line = '{:15} {:>10}{:>10}{:>10}{:>10}'.format(self.TXT_NODE, ENR_NodeAttributeNames[ENR_demand], ENR_NodeAttributeNames[ENR_head], ENR_NodeAttributeNames[ENR_pressure], ENR_NodeAttributeNames[ENR_quality]) self.write_line(line) line = '{:15} {:>10}{:>10}{:>10}{:>10}'.format(self.TXT_ID, ENR_NodeAttributeUnits[ENR_demand][self.output.unit_system], ENR_NodeAttributeUnits[ENR_head][self.output.unit_system], ENR_NodeAttributeUnits[ENR_pressure][self.output.unit_system], ENR_NodeAttributeUnits[ENR_quality][self.output.unit_system]) self.write_line(line) self.write_line(self.ULINE) def write_link_header(self, period, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE S = self.TXT_LINK_RESULTS if self.output.numPeriods > 1: S += self.TXT_AT + self.output.get_time_string(period) S += ':' if ContinueFlag: S += self.TXT_CONTINUED self.write_line(S) self.write_line(self.ULINE) S = '{:15} {:10}{:10}{:10}{:10}'.format(self.TXT_LINK, ENR_LinkAttributeNames[ENR_flow], ENR_LinkAttributeNames[ENR_velocity], ENR_LinkAttributeNames[ENR_headloss], ENR_LinkAttributeNames[ENR_status]) self.write_line(S) S = '{:15} {:10}{:10}{:10}'.format(self.TXT_ID, ENR_LinkAttributeUnits[ENR_flow][self.output.unit_system], ENR_LinkAttributeUnits[ENR_velocity][self.output.unit_system], ENR_LinkAttributeUnits[ENR_headloss][self.output.unit_system]) self.write_line(S) self.write_line(self.ULINE) def write_link_info_header(self, ContinueFlag): S = self.TXT_LINK_INFO if ContinueFlag: S += self.TXT_CONTINUED self.write_line(S) self.write_line(self.ULINE) S = '{:15}{:15}{:15}{:10}{:10}'.format(self.TXT_LINK, self.TXT_START, self.TXT_END, "Length", "Diameter") self.write_line(S) len_units = ('ft','m')[self.output.unit_system] dia_units = ('in','mm')[self.output.unit_system] S = '{:15}{:15}{:15}{:>10}{:>10}'.format(self.TXT_ID, self.TXT_NODE, self.TXT_NODE, len_units, dia_units) self.write_line(S) self.write_line(self.ULINE) def write_link_info(self): self.write_link_info_header(False) for conduits in (self.project.pipes, self.project.pumps, self.project.valves): # TODO: update progress bar: MainForm.UpdateProgressBar(Nprogress, ProgStep) for conduit in conduits.value: # Note: Pascal report got these values from binary, we get them here from input # length = self.output.get_LinkValue(conduits.id, 0, 1) # Uoutput.GetLinkValStr(LINKLENGTH,0,I,J) if (self.LineNum >= self.PAGESIZE): self.write_link_info_header(True) if hasattr(conduit, "length"): length = conduit.length else: length = "#N/A" if hasattr(conduit, "diameter"): diameter = conduit.diameter else: diameter = "#N/A" S = '{:15}{:15}{:15}{:>10}{:>10}'.format(conduit.id, conduit.inlet_node, conduit.outlet_node, length, diameter) if conduits is self.project.pumps: S += ' Pump' elif conduits is self.project.valves: S += ' Valve' self.write_line(S) self.write_line('') def write_node_table(self, period): self.write_node_header(period, False) for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: # MainForm.UpdateProgressBar(Nprogress, ProgStep) node_index = self.output.get_NodeIndex(node.id) if node_index < 0: line = '{:15} {}'.format(node.id, 'not found in output.') else: demand = self.output.get_NodeValue(node_index, period, ENR_demand) head = self.output.get_NodeValue(node_index, period, ENR_head) pressure = self.output.get_NodeValue(node_index, period, ENR_pressure) quality = self.output.get_NodeValue(node_index, period, ENR_quality) line = '{:15} {:7.2f} {:7.2f} {:7.2f} {:7.2f}'.format(node.id, demand, head, pressure, quality) if nodes is self.project.reservoirs: line += ' Reservoir' elif nodes is self.project.tanks: line += ' Tank' if (self.LineNum >= self.PAGESIZE): self.write_node_header(period, True) self.write_line(line) self.write_line('') def write_link_table(self, period): self.write_link_header(period, False) for links in (self.project.pipes, self.project.pumps, self.project.valves): for link in links.value: # MainForm.UpdateProgressBar(Nprogress, ProgStep) link_index = self.output.get_LinkIndex(link.id) if link_index < 0: line = '{:15} {}'.format(link.id, 'not found in output.') else: flow = self.output.get_LinkValue(link_index, period, ENR_flow) velocity = self.output.get_LinkValue(link_index, period, ENR_velocity) headloss = self.output.get_LinkValue(link_index, period, ENR_headloss) linkstat = "Unknown" # TODO: self.output.get_LinkValue(link_index, T, ENR_ line = '{:15} {:9.2f} {:9.2f} {:9.2f} {:>10}'.format(link.id, flow, velocity, headloss, linkstat) if links is self.project.pumps: line += ' Pump' elif links is self.project.valves: line += ' Valve' if (self.LineNum >= self.PAGESIZE): self.write_link_header(period, True) self.write_line(line) self.write_line('') def write_results(self): for period in range(0, self.output.numPeriods): # Application.ProcessMessages self.write_node_table(period) # Application.ProcessMessages self.write_link_table(period) def write_report(self, report_file_name): # MainForm.ShowProgressBar('Writing full report...') with open(report_file_name, 'w') as self.F: try: # Total = self.output.nodeCount + self.output.linkCount # Total *= self.output.numPeriods # Total += self.output.linkCount # with MainForm.ProgressBar do # N = Max div Step # ProgStep = Round(Total/N) # Nprogress = 0 self.write_logo() # Application.ProcessMessages self.write_link_info() if self.output.pumpCount > 0: self.write_energy() self.write_results() return True finally: print "Finished writing report " + report_file_name # MainForm.HideProgressBar def all_link_ids(self): ids = [] for links in (self.project.pipes, self.project.pumps, self.project.valves): for link in links.value: if self.output.get_LinkIndex(link.id) > -1: ids.append(link.id) else: print("Skipping link " + link.id + " because it was not found in output") return ids def all_link_types(self): types = [] for link in self.project.pipes.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Pipe") for link in self.project.pumps.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Pump") for link in self.project.valves.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Valve") return types def all_node_indexes(self): indexes = [] for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: node_index = self.output.get_NodeIndex(node.id) if node_index > -1: indexes.append(node_index) return indexes def all_node_ids(self): ids = [] for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: node_index = self.output.get_NodeIndex(node.id) if node_index > -1: ids.append(node.id) else: print("Skipping node " + node.id + " because it was not found in output") return ids def all_node_types(self): types = [] for node in self.project.junctions.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Junction") for node in self.project.reservoirs.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Reservoir") for node in self.project.tanks.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Tank") return types def node_distances(self, node_ids): return range(0, len(node_ids)) # TODO: compute distance from node coordinates distances = [0] x = None y = None for node_id in node_ids: for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: if node.id == node_id: if x and y: distances.append(sqrt((x - node.x) ^ 2 + (y - node.y) ^ 2)) return distances
class Reports: PAGESIZE = 55 ULINE = '----------------------------------------------------------------------' FMT18 = ' Page 1 {:>22}' FMT_DATE = '%Y/%m/%d %I:%M%p' FMT82 = ' Page {:4d} {:60}' FMT71 = 'Energy Usage:' FMT72 = ' Usage Avg. Kw-hr Avg. Peak Cost' FMT73 = 'Pump Factor Effic. {:5} Kw Kw /day' FMT74 = '{:45} Demand Charge: {:9.2f}' FMT75 = '{:45} Total Cost: {:9.2f}' TXT_perM3 = '/m3' TXT_perMGAL = '/Mgal' TXT_CONTINUED = ' (continued)' TXT_INPUT_FILE = 'Input File: ' TXT_LINK_INFO = 'Link - Node Table:' TXT_NODE_RESULTS = 'Node Results' TXT_LINK_RESULTS = 'Link Results' TXT_AT = ' at ' TXT_ID = 'ID' TXT_NODE = 'Node' TXT_LINK = 'Link' TXT_START = 'Start' TXT_END = 'End' TimeStat = ['Single Period', 'Average', 'Minimum', 'Maximum', 'Range'] def __init__(self, epanet_project, model_output): self.LogoTxt = ( '**********************************************************************', '* E P A N E T *', '* Hydraulic and Water Quality *', '* Analysis for Pipe Networks *', '* Version 2.0 *', '**********************************************************************' ) self.F = None # File being written to if isinstance(epanet_project, Project): self.project = epanet_project elif isinstance(epanet_project, str): self.project = Project() self.project.read_file(epanet_project) else: raise Exception( "Report Initialization: could not read EPANET project.") if isinstance(model_output, OutputObject): self.output = model_output elif isinstance(model_output, str): self.output = OutputObject(model_output) else: raise Exception( "Report Initialization: could not read output of model.\n" "Run the model to generate new output.") self.RptTitle = self.project.title.title self.PageNum = 0 self.LineNum = 0 self.Progstep = 0 self.Nprogress = 0 def write_line(self, line): if (self.LineNum >= self.PAGESIZE): self.PageNum += 1 self.F.write('\n\f\n') # newline form-feed newline self.F.write(self.FMT82.format(self.PageNum, self.RptTitle) + '\n') self.LineNum = 3 self.F.write(' ' + line + '\n') self.LineNum += 1 def write_logo(self): self.PageNum = 1 self.LineNum = 1 self.write_line( self.FMT18.format(datetime.now().strftime(self.FMT_DATE))) for line in self.LogoTxt: self.write_line(line) self.write_line('') self.write_line(self.TXT_INPUT_FILE + self.project.file_name) self.write_line('') self.write_line(self.RptTitle) self.write_line(self.project.title.notes) # self.write_line('') def write_energy_header(self, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE units = (self.TXT_perMGAL, self.TXT_perM3)[self.output.unit_system] line = self.FMT71 if ContinueFlag: line += self.TXT_CONTINUED self.write_line(line) self.write_line(self.ULINE) line = self.FMT72 self.write_line(line) line = self.FMT73.format(units) self.write_line(line) self.write_line(self.ULINE) def write_energy(self): self.write_energy_header(False) Csum = 0.0 for pump in self.project.pumps.value: x = [0, 0, 0, 0, 0, 0] Dcharge = 0 # Uoutput.GetPumpEnergy(k,x,Dcharge) Csum += x[5] if (self.LineNum >= self.PAGESIZE): self.write_energy_header(True) line = '{:15} {:6.2f} {:6.2f} {:9.2f} {:9.2f} {:9.2f} {:9.2f}'.format( pump.id, x[0], x[1], x[2], x[3], x[4], x[5]) self.write_line(line) self.write_line(self.ULINE) line = self.FMT74.format('', Dcharge) self.write_line(line) line = self.FMT75.format('', Csum + Dcharge) self.write_line(line) self.write_line('') def write_node_header(self, period, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE line = self.TXT_NODE_RESULTS if self.output.numPeriods > 1: line += self.TXT_AT + self.output.get_time_string(period) line += ':' if ContinueFlag: line += self.TXT_CONTINUED self.write_line(line) self.write_line(self.ULINE) line = '{:15} {:>10}{:>10}{:>10}{:>10}'.format( self.TXT_NODE, ENR_NodeAttributeNames[ENR_demand], ENR_NodeAttributeNames[ENR_head], ENR_NodeAttributeNames[ENR_pressure], ENR_NodeAttributeNames[ENR_quality]) self.write_line(line) line = '{:15} {:>10}{:>10}{:>10}{:>10}'.format( self.TXT_ID, ENR_NodeAttributeUnits[ENR_demand][self.output.unit_system], ENR_NodeAttributeUnits[ENR_head][self.output.unit_system], ENR_NodeAttributeUnits[ENR_pressure][self.output.unit_system], ENR_NodeAttributeUnits[ENR_quality][self.output.unit_system]) self.write_line(line) self.write_line(self.ULINE) def write_link_header(self, period, ContinueFlag): if self.LineNum + 11 > self.PAGESIZE: self.LineNum = self.PAGESIZE S = self.TXT_LINK_RESULTS if self.output.numPeriods > 1: S += self.TXT_AT + self.output.get_time_string(period) S += ':' if ContinueFlag: S += self.TXT_CONTINUED self.write_line(S) self.write_line(self.ULINE) S = '{:15} {:10}{:10}{:10}{:10}'.format( self.TXT_LINK, ENR_LinkAttributeNames[ENR_flow], ENR_LinkAttributeNames[ENR_velocity], ENR_LinkAttributeNames[ENR_headloss], ENR_LinkAttributeNames[ENR_status]) self.write_line(S) S = '{:15} {:10}{:10}{:10}'.format( self.TXT_ID, ENR_LinkAttributeUnits[ENR_flow][self.output.unit_system], ENR_LinkAttributeUnits[ENR_velocity][self.output.unit_system], ENR_LinkAttributeUnits[ENR_headloss][self.output.unit_system]) self.write_line(S) self.write_line(self.ULINE) def write_link_info_header(self, ContinueFlag): S = self.TXT_LINK_INFO if ContinueFlag: S += self.TXT_CONTINUED self.write_line(S) self.write_line(self.ULINE) S = '{:15}{:15}{:15}{:10}{:10}'.format(self.TXT_LINK, self.TXT_START, self.TXT_END, "Length", "Diameter") self.write_line(S) len_units = ('ft', 'm')[self.output.unit_system] dia_units = ('in', 'mm')[self.output.unit_system] S = '{:15}{:15}{:15}{:>10}{:>10}'.format(self.TXT_ID, self.TXT_NODE, self.TXT_NODE, len_units, dia_units) self.write_line(S) self.write_line(self.ULINE) def write_link_info(self): self.write_link_info_header(False) for conduits in (self.project.pipes, self.project.pumps, self.project.valves): # TODO: update progress bar: MainForm.UpdateProgressBar(Nprogress, ProgStep) for conduit in conduits.value: # Note: Pascal report got these values from binary, we get them here from input # length = self.output.get_LinkValue(conduits.id, 0, 1) # Uoutput.GetLinkValStr(LINKLENGTH,0,I,J) if (self.LineNum >= self.PAGESIZE): self.write_link_info_header(True) if hasattr(conduit, "length"): length = conduit.length else: length = "#N/A" if hasattr(conduit, "diameter"): diameter = conduit.diameter else: diameter = "#N/A" S = '{:15}{:15}{:15}{:>10}{:>10}'.format( conduit.id, conduit.inlet_node, conduit.outlet_node, length, diameter) if conduits is self.project.pumps: S += ' Pump' elif conduits is self.project.valves: S += ' Valve' self.write_line(S) self.write_line('') def write_node_table(self, period): self.write_node_header(period, False) for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: # MainForm.UpdateProgressBar(Nprogress, ProgStep) node_index = self.output.get_NodeIndex(node.id) if node_index < 0: line = '{:15} {}'.format(node.id, 'not found in output.') else: demand = self.output.get_NodeValue(node_index, period, ENR_demand) head = self.output.get_NodeValue(node_index, period, ENR_head) pressure = self.output.get_NodeValue( node_index, period, ENR_pressure) quality = self.output.get_NodeValue( node_index, period, ENR_quality) line = '{:15} {:7.2f} {:7.2f} {:7.2f} {:7.2f}'.format( node.id, demand, head, pressure, quality) if nodes is self.project.reservoirs: line += ' Reservoir' elif nodes is self.project.tanks: line += ' Tank' if (self.LineNum >= self.PAGESIZE): self.write_node_header(period, True) self.write_line(line) self.write_line('') def write_link_table(self, period): self.write_link_header(period, False) for links in (self.project.pipes, self.project.pumps, self.project.valves): for link in links.value: # MainForm.UpdateProgressBar(Nprogress, ProgStep) link_index = self.output.get_LinkIndex(link.id) if link_index < 0: line = '{:15} {}'.format(link.id, 'not found in output.') else: flow = self.output.get_LinkValue(link_index, period, ENR_flow) velocity = self.output.get_LinkValue( link_index, period, ENR_velocity) headloss = self.output.get_LinkValue( link_index, period, ENR_headloss) linkstat = "Unknown" # TODO: self.output.get_LinkValue(link_index, T, ENR_ line = '{:15} {:9.2f} {:9.2f} {:9.2f} {:>10}'.format( link.id, flow, velocity, headloss, linkstat) if links is self.project.pumps: line += ' Pump' elif links is self.project.valves: line += ' Valve' if (self.LineNum >= self.PAGESIZE): self.write_link_header(period, True) self.write_line(line) self.write_line('') def write_results(self): for period in range(0, self.output.numPeriods): # Application.ProcessMessages self.write_node_table(period) # Application.ProcessMessages self.write_link_table(period) def write_report(self, report_file_name): # MainForm.ShowProgressBar('Writing full report...') with open(report_file_name, 'w') as self.F: try: # Total = self.output.nodeCount + self.output.linkCount # Total *= self.output.numPeriods # Total += self.output.linkCount # with MainForm.ProgressBar do # N = Max div Step # ProgStep = Round(Total/N) # Nprogress = 0 self.write_logo() # Application.ProcessMessages self.write_link_info() if self.output.pumpCount > 0: self.write_energy() self.write_results() return True finally: print "Finished writing report " + report_file_name # MainForm.HideProgressBar def all_link_ids(self): ids = [] for links in (self.project.pipes, self.project.pumps, self.project.valves): for link in links.value: if self.output.get_LinkIndex(link.id) > -1: ids.append(link.id) else: print("Skipping link " + link.id + " because it was not found in output") return ids def all_link_types(self): types = [] for link in self.project.pipes.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Pipe") for link in self.project.pumps.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Pump") for link in self.project.valves.value: if self.output.get_LinkIndex(link.id) > -1: types.append("Valve") return types def all_node_indexes(self): indexes = [] for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: node_index = self.output.get_NodeIndex(node.id) if node_index > -1: indexes.append(node_index) return indexes def all_node_ids(self): ids = [] for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: node_index = self.output.get_NodeIndex(node.id) if node_index > -1: ids.append(node.id) else: print("Skipping node " + node.id + " because it was not found in output") return ids def all_node_types(self): types = [] for node in self.project.junctions.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Junction") for node in self.project.reservoirs.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Reservoir") for node in self.project.tanks.value: if self.output.get_NodeIndex(node.id) > -1: types.append("Tank") return types def node_distances(self, node_ids): return range(0, len(node_ids)) # TODO: compute distance from node coordinates distances = [0] x = None y = None for node_id in node_ids: for nodes in (self.project.junctions, self.project.reservoirs, self.project.tanks): for node in nodes.value: if node.id == node_id: if x and y: distances.append( sqrt((x - node.x) ^ 2 + (y - node.y) ^ 2)) return distances
class frmMainEPANET(frmMain): """Main form for EPANET user interface, based on frmMain which is shared with SWMM.""" # Variables used to populate the tree control # Each item is a list: label plus either editing form for this section or a child list. # Special cases may just have a label and no editing form or children. # *_items are a lists of items in a section tree_options_Hydraulics = ["Hydraulics", frmHydraulicsOptions] tree_options_Quality = ["Quality", frmQualityOptions] tree_options_Reactions = ["Reactions", frmReactionsOptions] tree_options_Times = ["Times", frmTimesOptions] tree_options_Energy = ["Energy", frmEnergyOptions] tree_options_Report = ["Report", frmReportOptions] tree_options_MapBackdrop = ["Map/Backdrop", frmMapBackdropOptions] tree_options_items = [tree_options_Hydraulics, tree_options_Quality, tree_options_Reactions, tree_options_Times, tree_options_Energy, tree_options_Report, tree_options_MapBackdrop] tree_controls_Simple = ["Simple", frmControls, ["EPANET Simple Controls", "CONTROLS"]] tree_controls_RuleBased = ["Rule-Based", frmControls, ["EPANET Rule-Based Controls", "RULES"]] tree_controls_items = [tree_controls_Simple, tree_controls_RuleBased] tree_TitleNotes = ["Title/Notes", frmTitle] tree_Options = ["Options", tree_options_items] tree_Junctions = ["Junctions", None] tree_Reservoirs = ["Reservoirs", None] tree_Tanks = ["Tanks", None] tree_Pipes = ["Pipes", None] tree_Pumps = ["Pumps", None] tree_Valves = ["Valves", None] tree_Labels = ["Labels", None] tree_Patterns = ["Patterns", frmPatternEditor] tree_Curves = ["Curves", frmCurveEditor] tree_Controls = ["Controls", tree_controls_items] tree_top_items = [tree_TitleNotes, tree_Options, tree_Junctions, tree_Reservoirs, tree_Tanks, tree_Pipes, tree_Pumps, tree_Valves, tree_Labels, tree_Patterns, tree_Curves, tree_Controls] def __init__(self, q_application): frmMain.__init__(self, q_application) self.model = "EPANET" self.model_path = '' # Set this only if needed later when running model self.output = None # Set this when model output is available self.status_suffix = "_status.txt" self.status_file_name = '' # Set this when model status is available self.output_filename = '' # Set this when model output is available self.project_type = Project # Use the model-specific Project as defined in core.epanet.project self.project = Project() self.assembly_path = os.path.dirname(os.path.abspath(__file__)) self.on_load(tree_top_item_list=self.tree_top_items) HelpHandler.init_class(os.path.join(self.assembly_path, "epanet.qhc")) self.help_topic = "" # TODO: specify topic to open when Help key is pressed on main form self.helper = HelpHandler(self) self.actionStatus_ReportMenu = QtGui.QAction(self) self.actionStatus_ReportMenu.setObjectName(from_utf8("actionStatus_ReportMenu")) self.actionStatus_ReportMenu.setText(transl8("frmMain", "Status", None)) self.actionStatus_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Status", None)) self.menuReport.addAction(self.actionStatus_ReportMenu) QtCore.QObject.connect(self.actionStatus_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_status) self.actionEnergy_ReportMenu = QtGui.QAction(self) self.actionEnergy_ReportMenu.setObjectName(from_utf8("actionEnergy_ReportMenu")) self.actionEnergy_ReportMenu.setText(transl8("frmMain", "Energy", None)) self.actionEnergy_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Energy", None)) self.menuReport.addAction(self.actionEnergy_ReportMenu) QtCore.QObject.connect(self.actionEnergy_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_energy) self.actionCalibration_ReportMenu = QtGui.QAction(self) self.actionCalibration_ReportMenu.setObjectName(from_utf8("actionCalibration_ReportMenu")) self.actionCalibration_ReportMenu.setText(transl8("frmMain", "Calibration", None)) self.actionCalibration_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Calibration", None)) self.menuReport.addAction(self.actionCalibration_ReportMenu) QtCore.QObject.connect(self.actionCalibration_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_calibration) self.actionReaction_ReportMenu = QtGui.QAction(self) self.actionReaction_ReportMenu.setObjectName(from_utf8("actionReaction_ReportMenu")) self.actionReaction_ReportMenu.setText(transl8("frmMain", "Reaction", None)) self.actionReaction_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Reaction", None)) self.menuReport.addAction(self.actionReaction_ReportMenu) QtCore.QObject.connect(self.actionReaction_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_reaction) self.actionFull_ReportMenu = QtGui.QAction(self) self.actionFull_ReportMenu.setObjectName(from_utf8("actionFull_ReportMenu")) self.actionFull_ReportMenu.setText(transl8("frmMain", "Full...", None)) self.actionFull_ReportMenu.setToolTip(transl8("frmMain", "Save full report as text file", None)) self.menuReport.addAction(self.actionFull_ReportMenu) QtCore.QObject.connect(self.actionFull_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_full) self.actionGraph_ReportMenu = QtGui.QAction(self) self.actionGraph_ReportMenu.setObjectName(from_utf8("actionGraph_ReportMenu")) self.actionGraph_ReportMenu.setText(transl8("frmMain", "Graph...", None)) self.actionGraph_ReportMenu.setToolTip(transl8("frmMain", "Display graph selection options", None)) self.menuReport.addAction(self.actionGraph_ReportMenu) QtCore.QObject.connect(self.actionGraph_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_graph) self.actionTable_ReportMenu = QtGui.QAction(self) self.actionTable_ReportMenu.setObjectName(from_utf8("actionTable_ReportMenu")) self.actionTable_ReportMenu.setText(transl8("frmMain", "Table...", None)) self.actionTable_ReportMenu.setToolTip(transl8("frmMain", "Display table selection options", None)) self.menuReport.addAction(self.actionTable_ReportMenu) QtCore.QObject.connect(self.actionTable_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_table) self.Help_Topics_Menu = QtGui.QAction(self) self.Help_Topics_Menu.setObjectName(from_utf8("Help_Topics_Menu")) self.Help_Topics_Menu.setText(transl8("frmMain", "Help Topics", None)) self.Help_Topics_Menu.setToolTip(transl8("frmMain", "Display Help Topics", None)) self.menuHelp.addAction(self.Help_Topics_Menu) QtCore.QObject.connect(self.Help_Topics_Menu, QtCore.SIGNAL('triggered()'), self.help_topics) self.Help_About_Menu = QtGui.QAction(self) self.Help_About_Menu.setObjectName(from_utf8("Help_About_Menu")) self.Help_About_Menu.setText(transl8("frmMain", "About", None)) self.Help_About_Menu.setToolTip(transl8("frmMain", "About EPANET", None)) self.menuHelp.addAction(self.Help_About_Menu) QtCore.QObject.connect(self.Help_About_Menu, QtCore.SIGNAL('triggered()'), self.help_about) def report_status(self): print "report_status" if not os.path.isfile(self.status_file_name): prefix, extension = os.path.splitext(self.project.file_name) if os.path.isfile(prefix + self.status_suffix): self.status_file_name = prefix + self.status_suffix if os.path.isfile(self.status_file_name): webbrowser.open_new_tab(self.status_file_name) else: QMessageBox.information(None, self.model, "Model status not found.\n" "Run the model to generate model status.", QMessageBox.Ok) def report_energy(self): self._frmEnergyReport = frmEnergyReport(self) self._frmEnergyReport.set_data() self._frmEnergyReport.show() pass def report_calibration(self): if self.output: self._frmCalibrationReportOptions = frmCalibrationReportOptions(self, self.project) self._frmCalibrationReportOptions.show() else: QMessageBox.information(None, self.model, "Model output not found.\n" "Run the model to generate output.", QMessageBox.Ok) def report_reaction(self): self.reaction_report() pass def report_full(self): if self.output: directory = os.path.dirname(self.project.file_name) report_file_name = QtGui.QFileDialog.getSaveFileName(self, "Save Full Report As...", directory, "Text files (*.txt)") if report_file_name: try: reporter = reports.Reports(self.project, self.output) reporter.write_report(report_file_name) webbrowser.open_new_tab(report_file_name) except Exception as e1: msg = str(e1) + '\n' + str(traceback.print_exc()) print(msg) QMessageBox.information(None, self.model, "Error writing report to \n" + report_file_name + '\n' + msg, QMessageBox.Ok) else: QMessageBox.information(None, self.model, "There is no model output currently open.\n" "Model output is automatically opened after model is run.", QMessageBox.Ok) def report_graph(self): if self.output: self._frmGraph = frmGraph(self) self._frmGraph.set_from(self.project, self.output) self._frmGraph.show() else: QMessageBox.information(None, self.model, "Model output not found.\n" "Run the model to generate output.", QMessageBox.Ok) def report_table(self): if self.output: self._frmTable = frmTable(self) self._frmTable.set_from(self.project, self.output) self._frmTable.show() else: QMessageBox.information(None, self.model, "Model output not found.\n" "Run the model to generate output.", QMessageBox.Ok) def reaction_report(self): # TXT_NO_REACTION = 'No reactions occurred' # TXT_AVG_RATES = 'Average Reaction Rates (kg/day)' # ' Reaction Report' # Find conversion factor to kilograms/day ucf = 1.0e6/24 quality_options = self.project.options.quality if 'ug' in str(quality_options.mass_units): ucf = 1.0e9/24 # # // Get average reaction rates from output file # Uoutput.GetReactRates(r); # procedure GetReactRates(var R: array of Single); # //----------------------------------------------- # // Retrieves overall average reaction rates # // NOTE: The 3 avg. reaction rates + avg. source # // input rate are stored at end of the # // binary output file just before the last # // 3 records. # //----------------------------------------------- # begin # Seek(Fout, FileSize(Fout)-7*RECORDSIZE); # BlockRead(Fout, R, 4*Sizeof(Single)); # end; # for i := 0 to 3 do rate[i] := r[i] / ucf; # # // Check max. rate to see if any reactions occurred # maxrate := MaxValue(Slice(rate,3)); # if maxrate = 0 then # begin # Chart1.Foot.Text.Add(TXT_NO_REACTION); # end # # // Add each rate category to chart # else # begin # Chart1.Title.Text.Add(TXT_AVG_RATES); # Add(rate[0],TXT_BULK,clBlue); # Add(rate[1],TXT_WALL,clRed); # Add(rate[2],TXT_TANKS,clGreen); # Active := True; # Chart1.Foot.Text.Add(Format(FMT_INFLOW,[rate[3]])); # end; # end; import matplotlib.pyplot as plt # The slices will be ordered and plotted counter-clockwise. labels = '2.8 Tanks', '0.5 Bulk', '2.1 Wall' sizes = [52.49, 8.57, 38.93] colors = ['green', 'blue', 'red'] explode = (0, 0, 0) plt.figure("Reaction Report") plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.2f%%', shadow=True, startangle=180) # Set aspect ratio to be equal so that pie is drawn as a circle. plt.axis('equal') plt.suptitle("Average Reaction Rates (kg/day)", fontsize=16) plt.text(0.9,-0.9,"Inflow Rate = 6") plt.show() def calibration_data(self): self._frmCalibrationData = frmCalibrationData(self) self._frmCalibrationData.show() pass def get_editor(self, edit_name): frm = None # First handle special cases where forms need more than simply being created # the following items will respond to a click on a node form, not the tree diagram if edit_name == 'Reservoirs' or edit_name == 'Tanks': # assume we're editing the first node for now frm = frmSourcesQuality(self) frm.setWindowTitle('EPANET Source Editor for Node ' + '1') frm.set_from(self.project, '1') elif edit_name == 'Junctions': # assume we're editing the first junction for now frm = frmDemands(self) frm.setWindowTitle('EPANET Demands for Junction ' + '1') frm.set_from(self.project, '1') elif edit_name == 'Patterns': return None elif edit_name == 'Curves': return None else: # General-purpose case finds most editors from tree information frm = self.make_editor_from_tree(edit_name, self.tree_top_items) return frm def get_editor_with_selected_item(self, edit_name, selected_item): frm = None # the following items will respond to a click on a node form, not the tree diagram if edit_name == 'Reservoirs' or edit_name == 'Tanks': # assume we're editing the first node for now frm = frmSourcesQuality(self) frm.setWindowTitle('EPANET Source Editor for Node ' + '1') frm.set_from(self.project, '1') elif edit_name == 'Junctions': # assume we're editing the first junction for now frm = frmDemands(self) frm.setWindowTitle('EPANET Demands for Junction ' + '1') frm.set_from(self.project, '1') else: # General-purpose case finds most editors from tree information frm = self.make_editor_from_tree(edit_name, self.tree_top_items) frm.set_from(self.project, selected_item) return frm def get_object_list(self, category): ids = [] if category.lower() == 'junctions': for i in range(0, len(self.project.junctions.value)): ids.append(self.project.junctions.value[i].id) elif category.lower() == 'reservoirs': for i in range(0, len(self.project.reservoirs.value)): ids.append(self.project.reservoirs.value[i].id) elif category.lower() == 'tanks': for i in range(0, len(self.project.tanks.value)): ids.append(self.project.tanks.value[i].id) elif category.lower() == 'pipes': for i in range(0, len(self.project.pipes.value)): ids.append(self.project.pipes.value[i].id) elif category.lower() == 'pumps': for i in range(0, len(self.project.pumps.value)): ids.append(self.project.pumps.value[i].id) elif category.lower() == 'valves': for i in range(0, len(self.project.valves.value)): ids.append(self.project.valves.value[i].id) elif category.lower() == 'labels': for i in range(0, len(self.project.labels.value)): ids.append(self.project.labels.value[i].label) elif category.lower() == 'patterns': for i in range(0, len(self.project.patterns.value)): ids.append(self.project.patterns.value[i].pattern_id) elif category.lower() == 'curves': for i in range(0, len(self.project.curves.value)): ids.append(self.project.curves.value[i].curve_id) else: ids = None return ids def add_object_clicked(self, section_name): if section_name == "Patterns": new_item = Pattern() new_item.pattern_id = "NewPattern" self.project.patterns.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.pattern_id)) elif section_name == "Curves": new_item = Curve() new_item.curve_id = "NewCurve" self.project.curves.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.curve_id)) elif section_name == "Junctions": new_item = Junction() new_item.id = "New" self.project.junctions.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Reservoirs': new_item = Reservoir() new_item.id = "New" self.project.reservoirs.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Tanks': new_item = Tank() new_item.id = "New" self.project.tanks.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Pipes': new_item = Pipe() new_item.id = "New" self.project.pipes.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Pumps': new_item = Pump() new_item.id = "New" self.project.pumps.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Valves': new_item = Valve() new_item.id = "New" self.project.valves.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) elif section_name == 'Labels': new_item = Label() new_item.id = "New" self.project.labels.value.append(new_item) self.show_edit_window(self.get_editor_with_selected_item(self.tree_section, new_item.id)) def delete_object_clicked(self, section_name, item_name): if section_name == "Patterns": for value in self.project.patterns.value: if value.pattern_id == item_name: self.project.patterns.value.remove(value) elif section_name == "Curves": for value in self.project.curves.value: if value.curve_id == item_name: self.project.curves.value.remove(value) elif section_name == "Junctions": for value in self.project.junctions.value: if value.id == item_name: self.project.junctions.value.remove(value) elif section_name == 'Reservoirs': for value in self.project.reservoirs.value: if value.id == item_name: self.project.reservoirs.value.remove(value) elif section_name == 'Tanks': for value in self.project.tanks.value: if value.id == item_name: self.project.tanks.value.remove(value) elif section_name == 'Pipes': for value in self.project.pipes.value: if value.id == item_name: self.project.pipes.value.remove(value) elif section_name == 'Pumps': for value in self.project.pumps.value: if value.id == item_name: self.project.pumps.value.remove(value) elif section_name == 'Valves': for value in self.project.valves.value: if value.id == item_name: self.project.valves.value.remove(value) elif section_name == 'Labels': for value in self.project.labels.value: if value.id == item_name: self.project.labels.value.remove(value) def run_simulation(self): # Find input file to run file_name = '' use_existing = self.project and self.project.file_name and os.path.exists(self.project.file_name) if use_existing: file_name = self.project.file_name # TODO: save if needed, decide whether to save to temp location as previous version did. else: directory = QtCore.QSettings(self.model, "GUI").value("ProjectDir", "") file_name = QFileDialog.getOpenFileName(self, "Open Project...", directory, "Inp files (*.inp);;All files (*.*)") if os.path.exists(file_name): if not os.path.exists(self.model_path): if 'darwin' in sys.platform: lib_name = 'libepanet.dylib.dylib' elif 'win' in sys.platform: lib_name = 'epanet2_amd64.dll' else: # Linux lib_name = 'libepanet2_amd64.so' self.model_path = self.find_external(lib_name) if os.path.exists(self.model_path): try: prefix, extension = os.path.splitext(file_name) self.status_file_name = prefix + self.status_suffix self.output_filename = prefix + '.out' model_api = ENepanet(file_name, self.status_file_name, self.output_filename, self.model_path) frmRun = frmRunEPANET(model_api, self.project, self) self._forms.append(frmRun) if not use_existing: # Read this project so we can refer to it while running frmRun.progressBar.setVisible(False) frmRun.lblTime.setVisible(False) frmRun.fraTime.setVisible(False) frmRun.fraBottom.setVisible(False) frmRun.showNormal() frmRun.set_status_text("Reading " + file_name) self.project = Project() self.project.read_file(file_name) frmRun.project = self.project frmRun.Execute() self.report_status() self.output = ENOutputWrapper.OutputObject(self.output_filename) return except Exception as e1: print(str(e1) + '\n' + str(traceback.print_exc())) QMessageBox.information(None, self.model, "Error running model with library:\n {0}\n{1}\n{2}".format( self.model_path, str(e1), str(traceback.print_exc())), QMessageBox.Ok) finally: try: if model_api and model_api.isOpen(): model_api.ENclose() except: pass return # # Could not run with library, try running with executable # # Run executable with StatusMonitor0 # args = [] # self.modelenv1 = 'EXE_EPANET' # program = os.environ[self.modelenv1] # # exe_name = "epanet2d.exe" # exe_path = os.path.join(self.assembly_path, exe_name) # if not os.path.exists(exe_path): # pp = os.path.dirname(os.path.dirname(self.assembly_path)) # exe_path = os.path.join(pp, "Externals", exe_name) # if not os.path.exists(exe_path): # exe_path = QFileDialog.getOpenFileName(self, 'Locate EPANET Executable', '/', # 'exe files (*.exe)') # if os.path.exists(exe_path): # os.environ[self.modelenv1] = exe_path # else: # os.environ[self.modelenv1] = '' # # if not os.path.exists(program): # QMessageBox.information(None, "EPANET", "EPANET Executable not found", QMessageBox.Ok) # return -1 # # args.append(file_name) # args.append(prefix + '.txt') # args.append(prefix + '.out') # status = model_utility.StatusMonitor0(program, args, self, model='EPANET') # status.show() else: QMessageBox.information(None, self.model, self.model + " input file not found", QMessageBox.Ok) def find_external(self, lib_name): filename = os.path.join(self.assembly_path, lib_name) if not os.path.exists(filename): pp = os.path.dirname(os.path.dirname(self.assembly_path)) filename = os.path.join(pp, "Externals", lib_name) if not os.path.exists(filename): pp = os.path.dirname(os.path.dirname(self.assembly_path)) filename = os.path.join(pp, "Externals", "epanet", "model", lib_name) if not os.path.exists(filename): filename = QFileDialog.getOpenFileName(self, 'Locate ' + self.model + ' Library', '/', '(*{0})'.format(os.path.splitext(lib_name)[1])) return filename def help_topics(self): self.helper.show_help() def help_about(self): self._frmAbout = frmAbout(self) self._frmAbout.show() pass
def run_simulation(self): # Find input file to run file_name = '' use_existing = self.project and self.project.file_name and os.path.exists(self.project.file_name) if use_existing: file_name = self.project.file_name # TODO: save if needed, decide whether to save to temp location as previous version did. else: directory = QtCore.QSettings(self.model, "GUI").value("ProjectDir", "") file_name = QFileDialog.getOpenFileName(self, "Open Project...", directory, "Inp files (*.inp);;All files (*.*)") if os.path.exists(file_name): if not os.path.exists(self.model_path): if 'darwin' in sys.platform: lib_name = 'libepanet.dylib.dylib' elif 'win' in sys.platform: lib_name = 'epanet2_amd64.dll' else: # Linux lib_name = 'libepanet2_amd64.so' self.model_path = self.find_external(lib_name) if os.path.exists(self.model_path): try: prefix, extension = os.path.splitext(file_name) self.status_file_name = prefix + self.status_suffix self.output_filename = prefix + '.out' model_api = ENepanet(file_name, self.status_file_name, self.output_filename, self.model_path) frmRun = frmRunEPANET(model_api, self.project, self) self._forms.append(frmRun) if not use_existing: # Read this project so we can refer to it while running frmRun.progressBar.setVisible(False) frmRun.lblTime.setVisible(False) frmRun.fraTime.setVisible(False) frmRun.fraBottom.setVisible(False) frmRun.showNormal() frmRun.set_status_text("Reading " + file_name) self.project = Project() self.project.read_file(file_name) frmRun.project = self.project frmRun.Execute() self.report_status() self.output = ENOutputWrapper.OutputObject(self.output_filename) return except Exception as e1: print(str(e1) + '\n' + str(traceback.print_exc())) QMessageBox.information(None, self.model, "Error running model with library:\n {0}\n{1}\n{2}".format( self.model_path, str(e1), str(traceback.print_exc())), QMessageBox.Ok) finally: try: if model_api and model_api.isOpen(): model_api.ENclose() except: pass return # # Could not run with library, try running with executable # # Run executable with StatusMonitor0 # args = [] # self.modelenv1 = 'EXE_EPANET' # program = os.environ[self.modelenv1] # # exe_name = "epanet2d.exe" # exe_path = os.path.join(self.assembly_path, exe_name) # if not os.path.exists(exe_path): # pp = os.path.dirname(os.path.dirname(self.assembly_path)) # exe_path = os.path.join(pp, "Externals", exe_name) # if not os.path.exists(exe_path): # exe_path = QFileDialog.getOpenFileName(self, 'Locate EPANET Executable', '/', # 'exe files (*.exe)') # if os.path.exists(exe_path): # os.environ[self.modelenv1] = exe_path # else: # os.environ[self.modelenv1] = '' # # if not os.path.exists(program): # QMessageBox.information(None, "EPANET", "EPANET Executable not found", QMessageBox.Ok) # return -1 # # args.append(file_name) # args.append(prefix + '.txt') # args.append(prefix + '.out') # status = model_utility.StatusMonitor0(program, args, self, model='EPANET') # status.show() else: QMessageBox.information(None, self.model, self.model + " input file not found", QMessageBox.Ok)
def __init__(self, q_application): frmMain.__init__(self, q_application) self.model = "EPANET" self.model_path = '' # Set this only if needed later when running model self.output = None # Set this when model output is available self.status_suffix = "_status.txt" self.status_file_name = '' # Set this when model status is available self.output_filename = '' # Set this when model output is available self.project_type = Project # Use the model-specific Project as defined in core.epanet.project self.project = Project() self.assembly_path = os.path.dirname(os.path.abspath(__file__)) self.on_load(tree_top_item_list=self.tree_top_items) HelpHandler.init_class(os.path.join(self.assembly_path, "epanet.qhc")) self.help_topic = "" # TODO: specify topic to open when Help key is pressed on main form self.helper = HelpHandler(self) self.actionStatus_ReportMenu = QtGui.QAction(self) self.actionStatus_ReportMenu.setObjectName(from_utf8("actionStatus_ReportMenu")) self.actionStatus_ReportMenu.setText(transl8("frmMain", "Status", None)) self.actionStatus_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Status", None)) self.menuReport.addAction(self.actionStatus_ReportMenu) QtCore.QObject.connect(self.actionStatus_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_status) self.actionEnergy_ReportMenu = QtGui.QAction(self) self.actionEnergy_ReportMenu.setObjectName(from_utf8("actionEnergy_ReportMenu")) self.actionEnergy_ReportMenu.setText(transl8("frmMain", "Energy", None)) self.actionEnergy_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Energy", None)) self.menuReport.addAction(self.actionEnergy_ReportMenu) QtCore.QObject.connect(self.actionEnergy_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_energy) self.actionCalibration_ReportMenu = QtGui.QAction(self) self.actionCalibration_ReportMenu.setObjectName(from_utf8("actionCalibration_ReportMenu")) self.actionCalibration_ReportMenu.setText(transl8("frmMain", "Calibration", None)) self.actionCalibration_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Calibration", None)) self.menuReport.addAction(self.actionCalibration_ReportMenu) QtCore.QObject.connect(self.actionCalibration_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_calibration) self.actionReaction_ReportMenu = QtGui.QAction(self) self.actionReaction_ReportMenu.setObjectName(from_utf8("actionReaction_ReportMenu")) self.actionReaction_ReportMenu.setText(transl8("frmMain", "Reaction", None)) self.actionReaction_ReportMenu.setToolTip(transl8("frmMain", "Display Simulation Reaction", None)) self.menuReport.addAction(self.actionReaction_ReportMenu) QtCore.QObject.connect(self.actionReaction_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_reaction) self.actionFull_ReportMenu = QtGui.QAction(self) self.actionFull_ReportMenu.setObjectName(from_utf8("actionFull_ReportMenu")) self.actionFull_ReportMenu.setText(transl8("frmMain", "Full...", None)) self.actionFull_ReportMenu.setToolTip(transl8("frmMain", "Save full report as text file", None)) self.menuReport.addAction(self.actionFull_ReportMenu) QtCore.QObject.connect(self.actionFull_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_full) self.actionGraph_ReportMenu = QtGui.QAction(self) self.actionGraph_ReportMenu.setObjectName(from_utf8("actionGraph_ReportMenu")) self.actionGraph_ReportMenu.setText(transl8("frmMain", "Graph...", None)) self.actionGraph_ReportMenu.setToolTip(transl8("frmMain", "Display graph selection options", None)) self.menuReport.addAction(self.actionGraph_ReportMenu) QtCore.QObject.connect(self.actionGraph_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_graph) self.actionTable_ReportMenu = QtGui.QAction(self) self.actionTable_ReportMenu.setObjectName(from_utf8("actionTable_ReportMenu")) self.actionTable_ReportMenu.setText(transl8("frmMain", "Table...", None)) self.actionTable_ReportMenu.setToolTip(transl8("frmMain", "Display table selection options", None)) self.menuReport.addAction(self.actionTable_ReportMenu) QtCore.QObject.connect(self.actionTable_ReportMenu, QtCore.SIGNAL('triggered()'), self.report_table) self.Help_Topics_Menu = QtGui.QAction(self) self.Help_Topics_Menu.setObjectName(from_utf8("Help_Topics_Menu")) self.Help_Topics_Menu.setText(transl8("frmMain", "Help Topics", None)) self.Help_Topics_Menu.setToolTip(transl8("frmMain", "Display Help Topics", None)) self.menuHelp.addAction(self.Help_Topics_Menu) QtCore.QObject.connect(self.Help_Topics_Menu, QtCore.SIGNAL('triggered()'), self.help_topics) self.Help_About_Menu = QtGui.QAction(self) self.Help_About_Menu.setObjectName(from_utf8("Help_About_Menu")) self.Help_About_Menu.setText(transl8("frmMain", "About", None)) self.Help_About_Menu.setToolTip(transl8("frmMain", "About EPANET", None)) self.menuHelp.addAction(self.Help_About_Menu) QtCore.QObject.connect(self.Help_About_Menu, QtCore.SIGNAL('triggered()'), self.help_about)